aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2010-04-30 12:00:00 +0200
committerBjörn Gustavsson <[email protected]>2010-08-20 08:52:37 +0200
commit6c8fb0bf44f74e9fc82f64949aba0bae8309fc88 (patch)
treeb9a743a450ac4dfdc7d4acb25be2b8449551f8be
parentd35dc5f707f307300665c7da2ae3092d0baa9bdd (diff)
downloadotp-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.
-rw-r--r--lib/inets/doc/src/notes.xml52
-rw-r--r--lib/inets/src/http_client/httpc.erl8
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl10
-rw-r--r--lib/inets/src/http_client/httpc_manager.erl18
-rw-r--r--lib/inets/src/inets_app/inets.appup.src22
-rw-r--r--lib/inets/vsn.mk8
6 files changed, 107 insertions, 11 deletions
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 762c2c84c5..3216b0c2cd 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -32,6 +32,58 @@
<file>notes.xml</file>
</header>
+ <section><title>Inets 5.3.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <p>-</p>
+
+<!--
+ <list>
+ <item>
+ <p>[httpc] - Allow users to pass socket options to the transport
+ module when making requests. </p>
+ <p>See the <c>socket_opts</c> option in the
+ <seealso marker="httpc#request2">request/4</seealso> or
+ <seealso marker="httpc#set_options">set_options/1,2</seealso>
+ for more info, </p>
+ <p>Own Id: OTP-8352</p>
+ </item>
+
+ </list>
+-->
+ </section>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[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.</p>
+ <p>Own Id: OTP-8542</p>
+ <p>Lev Walkin</p>
+ </item>
+
+ <item>
+ <p>[httpc] - https requests with default port (443) not handled
+ properly. </p>
+ <p>Own Id: OTP-8607</p>
+ <p>jebu ittiachen</p>
+ </item>
+
+ </list>
+ </section>
+
+ </section> <!-- 5.3.2 -->
+
+
<section><title>Inets 5.3.1</title>
<section><title>Improvements and New Features</title>
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, []}
]
},
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 401bf4d37d..7776bef0a5 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -18,11 +18,15 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 5.3.1
+INETS_VSN = 5.3.2
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
-TICKETS = OTP-8508 OTP-8509
+TICKETS = OTP-8542 OTP-8607
+
+TICKETS_5_3_1 = \
+ OTP-8508 \
+ OTP-8509
TICKETS_5_3 = \
OTP-8016 \