diff options
author | Micael Karlberg <[email protected]> | 2010-04-30 12:00:00 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2010-08-20 08:52:37 +0200 |
commit | 6c8fb0bf44f74e9fc82f64949aba0bae8309fc88 (patch) | |
tree | b9a743a450ac4dfdc7d4acb25be2b8449551f8be /lib/inets/src | |
parent | d35dc5f707f307300665c7da2ae3092d0baa9bdd (diff) | |
download | otp-6c8fb0bf44f74e9fc82f64949aba0bae8309fc88.tar.gz otp-6c8fb0bf44f74e9fc82f64949aba0bae8309fc88.tar.bz2 otp-6c8fb0bf44f74e9fc82f64949aba0bae8309fc88.zip |
inets: Patch 1115
OTP-8542 [httpc] Memory leak plugged. The profile manager never cleaned
up in its handler database. This meant that with each new
request handler, another entry was created that was never
deleted. Eventually the request id counter (used as a key)
would wrap, but the machine would most likely run out of
memory before that happened.
OTP-8607 [httpc] https requests with default port not handled properly.
Jebu Ittiachen.
Diffstat (limited to 'lib/inets/src')
-rw-r--r-- | lib/inets/src/http_client/httpc.erl | 8 | ||||
-rw-r--r-- | lib/inets/src/http_client/httpc_handler.erl | 10 | ||||
-rw-r--r-- | lib/inets/src/http_client/httpc_manager.erl | 18 | ||||
-rw-r--r-- | lib/inets/src/inets_app/inets.appup.src | 22 |
4 files changed, 49 insertions, 9 deletions
diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl index 5205605e0a..6deeab6948 100644 --- a/lib/inets/src/http_client/httpc.erl +++ b/lib/inets/src/http_client/httpc.erl @@ -432,7 +432,7 @@ handle_request(Method, Url, Options = request_options(Options0), Sync = proplists:get_value(sync, Options), Stream = proplists:get_value(stream, Options), - Host2 = header_host(Host, Port), + Host2 = header_host(Scheme, Host, Port), HeadersRecord = header_record(NewHeaders, Host2, HTTPOptions), Receiver = proplists:get_value(receiver, Options), SocketOpts = proplists:get_value(socket_opts, Options), @@ -895,9 +895,11 @@ bad_option(Option, BadValue) -> throw({error, {bad_option, Option, BadValue}}). -header_host(Host, 80 = _Port) -> +header_host(https, Host, 443 = _Port) -> Host; -header_host(Host, Port) -> +header_host(http, Host, 80 = _Port) -> + Host; +header_host(_Scheme, Host, Port) -> Host ++ ":" ++ integer_to_list(Port). diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index 695ff9cf82..5e79d874fb 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -1424,14 +1424,16 @@ try_to_enable_pipeline_or_keep_alive( State#state{status = close} end. -answer_request(Request, Msg, #state{timers = Timers} = State) -> +answer_request(#request{id = RequestId, from = From} = Request, Msg, + #state{timers = Timers, profile_name = ProfileName} = State) -> ?hcrt("answer request", [{request, Request}]), - httpc_response:send(Request#request.from, Msg), + httpc_response:send(From, Msg), RequestTimers = Timers#timers.request_timers, TimerRef = - proplists:get_value(Request#request.id, RequestTimers, undefined), - Timer = {Request#request.id, TimerRef}, + proplists:get_value(RequestId, RequestTimers, undefined), + Timer = {RequestId, TimerRef}, cancel_timer(TimerRef, {timeout, Request#request.id}), + httpc_manager:request_done(RequestId, ProfileName), State#state{request = Request#request{from = answer_sent}, timers = Timers#timers{request_timers = diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index f3cd81f4a7..b278077a66 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -30,6 +30,7 @@ request/2, cancel_request/2, request_canceled/2, + request_done/2, retry_request/2, redirect_request/2, insert_session/2, @@ -171,6 +172,18 @@ request_canceled(RequestId, ProfileName) -> %%-------------------------------------------------------------------- +%% Function: request_done(RequestId, ProfileName) -> ok +%% RequestId - ref() +%% ProfileName = atom() +%% +%% Description: Inform tha manager that a request has been completed. +%%-------------------------------------------------------------------- + +request_done(RequestId, ProfileName) -> + cast(ProfileName, {request_done, RequestId}). + + +%%-------------------------------------------------------------------- %% Function: insert_session(Session, ProfileName) -> _ %% Session - #tcp_session{} %% ProfileName - atom() @@ -486,6 +499,11 @@ handle_cast({request_canceled, RequestId}, State) -> {noreply, State} end; +handle_cast({request_done, RequestId}, State) -> + ?hcrv("request done", [{request_id, RequestId}]), + ets:delete(State#state.handler_db, RequestId), + {noreply, State}; + handle_cast({set_options, Options}, State = #state{options = OldOptions}) -> ?hcrv("set options", [{options, Options}, {old_options, OldOptions}]), NewOptions = diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index ba1dc8ccdb..dfdfb41373 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -18,9 +18,18 @@ {"%VSN%", [ + {"5.3.1", + [ + {load_module, httpc, soft_purge, soft_purge, []}, + {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, + {update, httpc_manager, soft, soft_purge, soft_purge, []} + ] + }, {"5.3", [ - {update, httpc_handler, soft, soft_purge, soft_purge, [mod_esi]}, + {load_module, httpc, soft_purge, soft_purge, []}, + {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, + {update, httpc_manager, soft, soft_purge, soft_purge, []}, {load_module, mod_esi, soft_purge, soft_purge, []} ] }, @@ -41,9 +50,18 @@ } ], [ + {"5.3.1", + [ + {load_module, httpc, soft_purge, soft_purge, []}, + {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, + {update, httpc_manager, soft, soft_purge, soft_purge, []} + ] + }, {"5.3", [ - {update, httpc_handler, soft, soft_purge, soft_purge, [mod_esi]}, + {load_module, httpc, soft_purge, soft_purge, []}, + {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, + {update, httpc_manager, soft, soft_purge, soft_purge, []}, {load_module, mod_esi, soft_purge, soft_purge, []} ] }, |