diff options
author | Kirilll Zaborsky <[email protected]> | 2014-10-08 15:31:13 +0400 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2014-12-01 16:51:42 +0100 |
commit | d7142993ed372c7f51ba381d5166ec7707951670 (patch) | |
tree | 41ea35c3ca5ad3918db0a8166811703286ef4264 /lib/inets/test | |
parent | 3651fbc0ff9b87c3ffe765ad1583e025f31d2259 (diff) | |
download | otp-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.erl | 29 |
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, |