From 245b210e368d9d930b8fff0e8bbdb1b083112dc0 Mon Sep 17 00:00:00 2001 From: Jakub Witczak Date: Tue, 25 Jul 2023 15:12:55 +0200 Subject: [PATCH] inets: httpd avoid function_clause during startup - avoid function_clause httpd_request:body_data/2 - happening when httpd is stopped during TLS negotiation - in such cases Manager process is killed and then continue_init fails --- lib/inets/src/http_server/httpd_manager.erl | 14 ++++- .../src/http_server/httpd_request_handler.erl | 56 +++++++++++-------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/lib/inets/src/http_server/httpd_manager.erl b/lib/inets/src/http_server/httpd_manager.erl index d198bc8fbfe7..fe7f721345a4 100644 --- a/lib/inets/src/http_server/httpd_manager.erl +++ b/lib/inets/src/http_server/httpd_manager.erl @@ -454,8 +454,18 @@ report_error(State,String) -> call(ServerRef, Request) -> try gen_server:call(ServerRef, Request, infinity) catch - exit:_ -> - {error, closed} + exit:Reason:Stacktrace -> + String = + lists:flatten( + io_lib:format( + "Request" + "~n ~p" + "~nto manager (~p) from ~p failed:" + "~n ~p" + "~n ~p", + [Request, ServerRef, self(), Reason, Stacktrace])), + error_logger:warning_report(String), + {error, Reason} end. count_children(Sup) -> diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl index 26327a256750..9231c5e584ae 100644 --- a/lib/inets/src/http_server/httpd_request_handler.erl +++ b/lib/inets/src/http_server/httpd_request_handler.erl @@ -137,34 +137,42 @@ continue_init(Manager, ConfigDB, SocketType, Socket, Peername, Sockname, socket_type = SocketType, socket = Socket, init_data = InitData}, - - MaxHeaderSize = max_header_size(ConfigDB), - MaxURISize = max_uri_size(ConfigDB), - NrOfRequest = max_keep_alive_request(ConfigDB), + + MaxHeaderSize = max_header_size(ConfigDB), + MaxURISize = max_uri_size(ConfigDB), + NrOfRequest = max_keep_alive_request(ConfigDB), MaxContentLen = max_content_length(ConfigDB), Customize = customize(ConfigDB), MaxChunk = max_client_body_chunk(ConfigDB), - - {_, Status} = httpd_manager:new_connection(Manager), - - MFA = {httpd_request, parse, [[{max_uri, MaxURISize}, {max_header, MaxHeaderSize}, - {max_version, ?HTTP_MAX_VERSION_STRING}, - {max_method, ?HTTP_MAX_METHOD_STRING}, - {max_content_length, MaxContentLen}, - {customize, Customize} - ]]}, - - State = #state{mod = Mod, - manager = Manager, - status = Status, - timeout = TimeOut, - max_keep_alive_request = NrOfRequest, - mfa = MFA, - chunk = chunk_start(MaxChunk)}, - setopts(Socket, SocketType, [binary, {packet, 0}, {active, once}]), - NewState = data_receive_counter(activate_request_timeout(State), httpd_util:lookup(ConfigDB, minimum_bytes_per_second, false)), - gen_server:enter_loop(?MODULE, [], NewState). + {Result, Status} = httpd_manager:new_connection(Manager), + case Result of + error -> + httpd_util:error_log(ConfigDB, + httpd_logger:error_report('TLS', Status, + Mod, ?LOCATION)), + exit({shutdown, Status}); + _ -> + MFA = {httpd_request, parse, [[{max_uri, MaxURISize}, {max_header, MaxHeaderSize}, + {max_version, ?HTTP_MAX_VERSION_STRING}, + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, MaxContentLen}, + {customize, Customize} + ]]}, + + State = #state{mod = Mod, + manager = Manager, + status = Status, + timeout = TimeOut, + max_keep_alive_request = NrOfRequest, + mfa = MFA, + chunk = chunk_start(MaxChunk)}, + setopts(Socket, SocketType, [binary, {packet, 0}, {active, once}]), + NewState = + data_receive_counter(activate_request_timeout(State), + httpd_util:lookup(ConfigDB, minimum_bytes_per_second, false)), + gen_server:enter_loop(?MODULE, [], NewState) + end. %%==================================================================== %% gen_server callbacks