From 2c27a2e2a57d37df1f33f481dc0edbfd2cc83db3 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 22 May 2012 14:53:45 +0200 Subject: [inets/httpc] Cancel request does not work Cancel request does not work due to incorrect handler table creation (wrong keypos). OTP-10092 --- lib/inets/src/http_client/httpc_manager.erl | 105 ++++++++++++++-------------- 1 file changed, 54 insertions(+), 51 deletions(-) (limited to 'lib/inets/src') diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index b225b43214..771968e169 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -59,17 +59,9 @@ options = #options{} }). --record(handler_info, - { - id, % Id of the request: request_id() - starter, % Pid of the handler starter process (temp): pid() - handler, % Pid of the handler process: pid() - from, % From for the request: from() - state % State of the handler: initiating | started | operational | canceled - }). - -define(DELAY, 500). + %%==================================================================== %% Internal Application API %%==================================================================== @@ -379,8 +371,7 @@ do_init(ProfileName, CookiesDir) -> %% Create handler db ?hcrt("create handler/request db", []), HandlerDbName = handler_db_name(ProfileName), - ets:new(HandlerDbName, - [protected, set, named_table, {keypos, #handler_info.id}]), + ets:new(HandlerDbName, [protected, set, named_table, {keypos, 1}]), %% Cookie DB ?hcrt("create cookie db", []), @@ -414,9 +405,10 @@ handle_call({request, Request}, _, State) -> {stop, Error, httpc_response:error(Request, Error), State} end; -handle_call({cancel_request, RequestId}, From, State) -> +handle_call({cancel_request, RequestId}, From, + #state{handler_db = HandlerDb} = State) -> ?hcri("cancel_request", [{request_id, RequestId}]), - case ets:lookup(State#state.handler_db, RequestId) of + case ets:lookup(HandlerDb, RequestId) of [] -> %% The request has allready compleated make sure %% it is deliverd to the client process queue so @@ -428,9 +420,9 @@ handle_call({cancel_request, RequestId}, From, State) -> {noreply, State}; [{_, Pid, _}] -> httpc_handler:cancel(RequestId, Pid, From), - {noreply, State#state{cancel = - [{RequestId, Pid, From} | - State#state.cancel]}} + {noreply, + State#state{cancel = + [{RequestId, Pid, From} | State#state.cancel]}} end; handle_call(reset_cookies, _, #state{cookie_db = CookieDb} = State) -> @@ -645,7 +637,7 @@ code_change(_, code_change(_, State, _) -> {ok, State}. -%% This function is to catch everything that calls through the cracks... +%% This function is used to catch everything that falls through the cracks... update_session_table(SessionDB, Transform) -> ets:safe_fixtable(SessionDB, true), update_session_table(SessionDB, ets:first(SessionDB), Transform), @@ -678,35 +670,42 @@ get_manager_info(#state{handler_db = HDB, CookieInfo = httpc_cookie:which_cookies(CDB), [{handlers, HandlerInfo}, {cookies, CookieInfo}]. +sort_handlers(Unsorted) -> + sort_handlers2(lists:keysort(1, Unsorted)). + +sort_handlers2([]) -> + []; +sort_handlers2([{HandlerPid, RequestId}|L]) -> + {Handler, Rest} = sort_handlers2(HandlerPid, [RequestId], L), + [Handler | sort_handlers2(Rest)]. + +sort_handlers2(HandlerPid, Reqs, []) -> + {{HandlerPid, lists:sort(Reqs)}, []}; +sort_handlers2(HandlerPid, Reqs, [{HandlerPid, ReqId}|Rest]) -> + sort_handlers2(HandlerPid, [ReqId|Reqs], Rest); +sort_handlers2(HandlerPid1, Reqs, [{HandlerPid2, _}|_] = Rest) + when HandlerPid1 =/= HandlerPid2 -> + {{HandlerPid1, lists:sort(Reqs)}, Rest}. + get_handler_info(Tab) -> - Pattern = #handler_info{handler = '$1', - state = '$2', - _ = '_'}, - Handlers1 = [{Pid, State} || [Pid, State] <- ets:match(Tab, Pattern)], - F = fun({Pid, State} = Elem, Acc) when State =/= canceled -> - case lists:keymember(Pid, 1, Acc) of - true -> - Acc; - false -> - [Elem | Acc] - end; - (_, Acc) -> - Acc - end, - Handlers2 = lists:foldl(F, [], Handlers1), - Handlers3 = [{Pid, State, - case (catch httpc_handler:info(Pid)) of - {'EXIT', _} -> + Pattern = {'$2', '$1', '_'}, + Handlers1 = [{Pid, Id} || [Pid, Id] <- ets:match(Tab, Pattern)], + Handlers2 = sort_handlers(Handlers1), + Handlers3 = [{Pid, Reqs, + try + begin + httpc_handler:info(Pid) + end + catch + _:_ -> %% Why would this crash? %% Only if the process has died, but we don't %% know about it? - []; - Else -> - Else - end} || - {Pid, State} <- Handlers2], + [] + end} || {Pid, Reqs} <- Handlers2], Handlers3. + handle_request(#request{settings = #http_options{version = "HTTP/0.9"}} = Request, State) -> @@ -758,19 +757,21 @@ handle_request(Request, State = #state{options = Options}) -> {reply, {ok, NewRequest#request.id}, State}. -start_handler(Request, State) -> +start_handler(#request{id = Id, + from = From} = Request, + #state{profile_name = ProfileName, + handler_db = HandlerDb, + options = Options}) -> {ok, Pid} = case is_inets_manager() of true -> httpc_handler_sup:start_child([whereis(httpc_handler_sup), - Request, State#state.options, - State#state.profile_name]); + Request, Options, ProfileName]); false -> - httpc_handler:start_link(self(), Request, State#state.options, - State#state.profile_name) + httpc_handler:start_link(self(), Request, Options, ProfileName) end, - ets:insert(State#state.handler_db, {Request#request.id, - Pid, Request#request.from}), + HandlerInfo = {Id, Pid, From}, + ets:insert(HandlerDb, HandlerInfo), erlang:monitor(process, Pid). @@ -827,12 +828,14 @@ select_session(Candidates, Max) -> {ok, HandlerPid} end. -pipeline_or_keep_alive(Request, HandlerPid, State) -> +pipeline_or_keep_alive(#request{id = Id, + from = From} = Request, + HandlerPid, + #state{handler_db = HandlerDb} = State) -> case (catch httpc_handler:send(Request, HandlerPid)) of ok -> - ets:insert(State#state.handler_db, {Request#request.id, - HandlerPid, - Request#request.from}); + HandlerInfo = {Id, HandlerPid, From}, + ets:insert(HandlerDb, HandlerInfo); _ -> % timeout pipelining failed start_handler(Request, State) end. -- cgit v1.2.3 From b1d12bf8623c5585017b1777236c18da1f5a83a4 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 22 May 2012 15:01:06 +0200 Subject: [inets/httpc] Updated version, release nodes and appup OTP-10092 --- lib/inets/src/inets_app/inets.appup.src | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib/inets/src') diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index c7029f7b31..0a69636851 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -18,6 +18,11 @@ {"%VSN%", [ + {"5.9", + [ + {update, httpc_handler, soft, soft_purge, soft_purge, []} + ] + }, {"5.8.1", [ {load_module, http_uri, soft_purge, soft_purge, []}, @@ -74,6 +79,11 @@ } ], [ + {"5.9", + [ + {update, httpc_handler, soft, soft_purge, soft_purge, []} + ] + }, {"5.8.1", [ {load_module, http_uri, soft_purge, soft_purge, []}, -- cgit v1.2.3 From ef14221acafe78b7a77b5d42b6a615fa7333750d Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 22 May 2012 15:35:26 +0200 Subject: [inets/httpc] Corrected appup file OTP-10092 --- lib/inets/src/inets_app/inets.appup.src | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/inets/src') diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index 0a69636851..93fd5b9595 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -20,7 +20,7 @@ [ {"5.9", [ - {update, httpc_handler, soft, soft_purge, soft_purge, []} + {update, httpc_manager, soft, soft_purge, soft_purge, []} ] }, {"5.8.1", @@ -40,6 +40,7 @@ {load_module, httpd_script_env, soft_purge, soft_purge, []}, {load_module, inets, soft_purge, soft_purge, [inets_trace]}, + {update, httpc_manager, soft, soft_purge, soft_purge, []}, {update, httpc_handler, soft, soft_purge, soft_purge, []}, {update, httpd_sup, soft, soft_purge, soft_purge, []}, {add_module, inets_trace} @@ -81,7 +82,7 @@ [ {"5.9", [ - {update, httpc_handler, soft, soft_purge, soft_purge, []} + {update, httpc_manager, soft, soft_purge, soft_purge, []} ] }, {"5.8.1", @@ -101,6 +102,7 @@ {load_module, httpd_script_env, soft_purge, soft_purge, []}, {load_module, inets, soft_purge, soft_purge, []}, + {update, httpc_manager, soft, soft_purge, soft_purge, []}, {update, httpc_handler, soft, soft_purge, soft_purge, []}, {update, httpd_sup, soft, soft_purge, soft_purge, []}, {remove, {inets_trace, soft_purge, brutal_purge}} -- cgit v1.2.3