From d7142993ed372c7f51ba381d5166ec7707951670 Mon Sep 17 00:00:00 2001 From: Kirilll Zaborsky Date: Wed, 8 Oct 2014 15:31:13 +0400 Subject: 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. --- lib/inets/test/httpc_SUITE.erl | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'lib/inets/test/httpc_SUITE.erl') 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, -- cgit v1.2.3