diff options
Diffstat (limited to 'lib/inets/src/http_client/httpc_handler.erl')
-rw-r--r-- | lib/inets/src/http_client/httpc_handler.erl | 132 |
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. |