summaryrefslogtreecommitdiff
path: root/lib/inets/src/http_client/httpc_handler.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/inets/src/http_client/httpc_handler.erl')
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl132
1 files changed, 59 insertions, 73 deletions
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 63e26f5266..026cea9b1f 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -50,23 +50,23 @@
-record(state,
{
- request :: request() | undefined,
- session :: session() | undefined,
- status_line :: tuple() | undefined, % {Version, StatusCode, ReasonPharse}
- headers :: http_response_h() | undefined,
- body :: binary() | undefined,
- mfa :: {atom(), atom(), term()} | undefined, % {Module, Function, Args}
- pipeline = queue:new() :: queue:queue(),
- keep_alive = queue:new() :: queue:queue(),
- status :: undefined | new | pipeline | keep_alive | close | {ssl_tunnel, request()},
- canceled = [], % [RequestId]
- max_header_size = nolimit :: nolimit | integer(),
- max_body_size = nolimit :: nolimit | integer(),
- options :: options(),
- timers = #timers{} :: #timers{},
- profile_name :: atom(), % id of httpc_manager process.
- once = inactive :: inactive | once
- }).
+ request :: request() | undefined,
+ session :: session() | undefined,
+ status_line :: tuple() | undefined, % {Version, StatusCode, ReasonPharse}
+ headers :: http_response_h() | undefined,
+ body :: binary() | undefined,
+ mfa :: {atom(), atom(), term()} | undefined, % {Module, Function, Args}
+ pipeline = queue:new() :: queue:queue(),
+ keep_alive = queue:new() :: queue:queue(),
+ status :: undefined | new | pipeline | keep_alive | close | {ssl_tunnel, request()},
+ canceled = [] :: [RequestId::reference()],
+ max_header_size = nolimit :: nolimit | integer(),
+ max_body_size = nolimit :: nolimit | integer(),
+ options :: options(),
+ timers = #timers{} :: #timers{},
+ profile_name :: atom(), % id of httpc_manager process.
+ once = inactive :: inactive | once
+ }).
%%====================================================================
@@ -292,65 +292,35 @@ handle_info(Info, State) ->
%% Function: terminate(Reason, State) -> _ (ignored by gen_server)
%% Description: Shutdown the httpc_handler
%%--------------------------------------------------------------------
-
terminate(normal, #state{session = undefined}) ->
- ok;
-
+ ok;
%% Init error sending, no session information has been setup but
%% there is a socket that needs closing.
-terminate(normal,
- #state{session = #session{id = undefined} = Session}) ->
+terminate(normal,
+ #state{session = #session{id = undefined} = Session}) ->
close_socket(Session);
-
%% Socket closed remotely
-terminate(normal,
- #state{session = #session{socket = {remote_close, Socket},
- socket_type = SocketType,
- id = Id},
- profile_name = ProfileName,
- request = Request,
- timers = Timers,
- pipeline = Pipeline,
- keep_alive = KeepAlive} = State) ->
- %% Clobber session
- (catch httpc_manager:delete_session(Id, ProfileName)),
-
- maybe_retry_queue(Pipeline, State),
- maybe_retry_queue(KeepAlive, State),
-
- %% Cancel timers
+terminate(normal, #state{session = #session{socket = {remote_close, Socket},
+ socket_type = SocketType},
+ request = Request,
+ timers = Timers} = State) ->
+ clobber_and_retry(State),
cancel_timers(Timers),
-
- %% Maybe deliver answers to requests
- deliver_answer(Request),
-
+ maybe_deliver_answer(Request, State),
%% And, just in case, close our side (**really** overkill)
http_transport:close(SocketType, Socket);
-
-terminate(_Reason, #state{session = #session{id = Id,
- socket = Socket,
- socket_type = SocketType},
- request = undefined,
- profile_name = ProfileName,
- timers = Timers,
- pipeline = Pipeline,
- keep_alive = KeepAlive} = State) ->
-
- %% Clobber session
- (catch httpc_manager:delete_session(Id, ProfileName)),
-
- maybe_retry_queue(Pipeline, State),
- maybe_retry_queue(KeepAlive, State),
-
+terminate(_Reason, #state{session = #session{socket = Socket,
+ socket_type = SocketType},
+ request = undefined,
+ timers = Timers} = State) ->
+ clobber_and_retry(State),
cancel_timer(Timers#timers.queue_timer, timeout_queue),
http_transport:close(SocketType, Socket);
-
-terminate(_Reason, #state{request = undefined}) ->
+terminate(_Reason, #state{request = undefined}) ->
ok;
-
-terminate(Reason, #state{request = Request} = State) ->
- NewState = maybe_send_answer(Request,
- httpc_response:error(Request, Reason),
+terminate(Reason, #state{request = Request} = State) ->
+ NewState = maybe_send_answer(Request,
+ httpc_response:error(Request, Reason),
State),
terminate(Reason, NewState#state{request = undefined}).
@@ -706,24 +676,26 @@ call(Msg, Pid) ->
cast(Msg, Pid) ->
gen_server:cast(Pid, Msg).
-maybe_retry_queue(Q, State) ->
- case queue:is_empty(Q) of
- false ->
+maybe_retry_queue(Q, #state{status = new} = State) ->
+ retry_pipeline(queue:to_list(Q), State);
+maybe_retry_queue(Q, #state{request = Request} = State) ->
+ case Request of
+ undefined ->
retry_pipeline(queue:to_list(Q), State);
- true ->
- ok
+ _ ->
+ retry_pipeline(queue:to_list(queue:cons(Request, Q)), State)
end.
-
+
maybe_send_answer(#request{from = answer_sent}, _Reason, State) ->
State;
maybe_send_answer(Request, Answer, State) ->
answer_request(Request, Answer, State).
-deliver_answer(#request{from = From} = Request)
+maybe_deliver_answer(#request{from = From} = Request, #state{status = new})
when From =/= answer_sent ->
Response = httpc_response:error(Request, socket_closed_remotely),
httpc_response:send(From, Response);
-deliver_answer(_Request) ->
+maybe_deliver_answer(_,_) ->
ok.
%%%--------------------------------------------------------------------
@@ -1724,3 +1696,17 @@ format_address({[$[|T], Port}) ->
{Address, Port};
format_address(HostPort) ->
HostPort.
+
+clobber_and_retry(#state{session = #session{id = Id,
+ type = Type},
+ profile_name = ProfileName,
+ pipeline = Pipeline,
+ keep_alive = KeepAlive} = State) ->
+ %% Clobber session
+ (catch httpc_manager:delete_session(Id, ProfileName)),
+ case Type of
+ pipeline ->
+ maybe_retry_queue(Pipeline, State);
+ _ ->
+ maybe_retry_queue(KeepAlive, State)
+ end.