File 0801-inets-httpd-avoid-function_clause-during-startup.patch of Package erlang

From 245b210e368d9d930b8fff0e8bbdb1b083112dc0 Mon Sep 17 00:00:00 2001
From: Jakub Witczak <kuba@erlang.org>
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 d198bc8fbf..fe7f721345 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 26327a2567..9231c5e584 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
-- 
2.35.3

openSUSE Build Service is sponsored by