aboutsummaryrefslogtreecommitdiffstats
path: root/lib/inets/test
diff options
context:
space:
mode:
authorKirilll Zaborsky <[email protected]>2014-10-08 15:31:13 +0400
committerIngela Anderton Andin <[email protected]>2014-12-01 16:51:42 +0100
commitd7142993ed372c7f51ba381d5166ec7707951670 (patch)
tree41ea35c3ca5ad3918db0a8166811703286ef4264 /lib/inets/test
parent3651fbc0ff9b87c3ffe765ad1583e025f31d2259 (diff)
downloadotp-d7142993ed372c7f51ba381d5166ec7707951670.tar.gz
otp-d7142993ed372c7f51ba381d5166ec7707951670.tar.bz2
otp-d7142993ed372c7f51ba381d5166ec7707951670.zip
inets: stop httpc_handler on 'connection closed' send error
httpc_handler should be stopped when sending requests returns error because of a closed connection and `tcp_closed` message could not be catched (see http://erlang.org/pipermail/erlang-bugs/2007-May/000346.html ) otherwise it will lead to process leak.
Diffstat (limited to 'lib/inets/test')
-rw-r--r--lib/inets/test/httpc_SUITE.erl29
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index c535d59b9f..78d7ecbf61 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -28,6 +28,7 @@
-include_lib("common_test/include/ct.hrl").
-include("inets_test_lib.hrl").
-include("http_internal.hrl").
+-include("httpc_internal.hrl").
%% Note: This directive should only be used in test suites.
-compile(export_all).
@@ -105,6 +106,7 @@ only_simulated() ->
empty_response_header,
remote_socket_close,
remote_socket_close_async,
+ process_leak_on_keepalive%,
transfer_encoding,
transfer_encoding_identity,
redirect_loop,
@@ -900,6 +902,33 @@ remote_socket_close_async(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
+process_leak_on_keepalive(Config) ->
+ {ok, ClosedSocket} = gen_tcp:listen(6666, [{active, false}]),
+ ok = gen_tcp:close(ClosedSocket),
+ Request = {url(group_name(Config), "/dummy.html", Config), []},
+ HttpcHandlers0 = supervisor:which_children(httpc_handler_sup),
+ {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
+ HttpcHandlers1 = supervisor:which_children(httpc_handler_sup),
+ ChildrenCount = supervisor:count_children(httpc_handler_sup),
+ %% Assuming that the new handler will be selected for keep_alive
+ %% which could not be the case if other handlers existed
+ [{undefined, Pid, worker, [httpc_handler]}] =
+ ordsets:to_list(
+ ordsets:subtract(ordsets:from_list(HttpcHandlers1),
+ ordsets:from_list(HttpcHandlers0))),
+ sys:replace_state(
+ Pid, fun (State) ->
+ Session = element(3, State),
+ setelement(3, State, Session#session{socket=ClosedSocket})
+ end),
+ {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
+ %% bad handler with the closed socket should get replaced by
+ %% the new one, so children count should stay the same
+ ChildrenCount = supervisor:count_children(httpc_handler_sup),
+ ok.
+
+%%-------------------------------------------------------------------------
+
stream_to_pid(Config) when is_list(Config) ->
ReceiverPid = create_receiver(pid),
Receiver = ReceiverPid,