File 4381-inets-Implement-HTTP-308-Permanent-Redirect.patch of Package erlang

From 112cf5843a52fa6a57865faea5b7e60ec1a7e141 Mon Sep 17 00:00:00 2001
From: DataTriny <datatriny@gmail.com>
Date: Tue, 4 Oct 2022 22:25:41 +0200
Subject: [PATCH] inets: Implement HTTP 308 Permanent Redirect

---
 lib/inets/doc/src/httpd_util.xml             |  5 ++-
 lib/inets/src/http_client/httpc_response.erl | 20 ++++++-----
 lib/inets/src/http_server/httpd_util.erl     |  1 +
 lib/inets/test/httpc_SUITE.erl               | 36 ++++++++++++++++++++
 lib/inets/test/httpd_poll.erl                |  1 +
 lib/inets/test/httpd_time_test.erl           |  1 +
 6 files changed, 54 insertions(+), 10 deletions(-)

diff --git a/lib/inets/doc/src/httpd_util.xml b/lib/inets/doc/src/httpd_util.xml
index 3ab3d7c163..a334ec9f86 100644
--- a/lib/inets/doc/src/httpd_util.xml
+++ b/lib/inets/doc/src/httpd_util.xml
@@ -264,7 +264,10 @@
       <name since="">reason_phrase(StatusCode) -> Description</name>
       <fsummary>Returns the description of an HTTP 1.1 status code.</fsummary>
       <type>
-        <v>StatusCode = 100| 200 | 201 | 202 | 204 | 205 | 206 | 300 | 301 | 302 | 303 | 304 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 410 411 | 412 | 413 | 414 415 | 416 | 417 | 500 | 501 | 502 | 503 | 504 | 505</v>
+        <v>StatusCode = 100 | 200 | 201 | 202 | 204 | 205 | 206 | 300 | 301 | 
+          302 | 303 | 304 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 
+          410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 500 | 501 | 502 | 
+          503 | 504 | 505</v>
         <v>Description = string()</v>
       </type>
       <desc>
diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl
index 79895e447e..2c421c5969 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.erl
@@ -122,17 +122,19 @@ result(Response = {{_, Code, _}, _, _},
                            (Code =:= 303) ->
     redirect(Response, Request#request{method = get});
 result(Response = {{_, Code, _}, _, _}, 
-       Request = #request{settings =
-              #http_options{autoredirect = true},
-              method = post}) when (Code =:= 307) ->
+        Request = #request{settings =
+            #http_options{autoredirect = true},
+                method = post}) when (Code =:= 307) orelse
+                    (Code =:= 308) ->
     redirect(Response, Request);
 result(Response = {{_, Code, _}, _, _}, 
-       Request = #request{settings = 
-			  #http_options{autoredirect = true},
-			  method = Method}) when (Code =:= 301) orelse
-					       (Code =:= 302) orelse
-					       (Code =:= 303) orelse
-					       (Code =:= 307) ->
+        Request = #request{settings = 
+			#http_options{autoredirect = true},
+                method = Method}) when (Code =:= 301) orelse
+                    (Code =:= 302) orelse
+                    (Code =:= 303) orelse
+                    (Code =:= 307) orelse
+                    (Code =:= 308) ->
     case lists:member(Method, [get, head, options, trace]) of
     true ->
         redirect(Response, Request);
diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl
index c1f273af79..07fc553f70 100644
--- a/lib/inets/src/http_server/httpd_util.erl
+++ b/lib/inets/src/http_server/httpd_util.erl
@@ -129,6 +129,7 @@ reason_phrase(304) ->   "Not Modified" ;
 reason_phrase(305) ->   "Use Proxy" ;
 reason_phrase(306) ->   "(unused)" ;
 reason_phrase(307) ->   "Temporary Redirect" ;
+reason_phrase(308) ->   "Permanent Redirect" ;
 reason_phrase(400) ->   "Bad Request";
 reason_phrase(401) ->   "Unauthorized";
 reason_phrase(402) ->   "Payment Required";
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 1c1e642714..32dbf6b97b 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -181,6 +181,7 @@ only_simulated() ->
      redirect_found,
      redirect_see_other,
      redirect_temporary_redirect,
+     redirect_permanent_redirect,
      redirect_relative_uri,
      port_in_host_header,
      redirect_port_in_host_header,
@@ -758,6 +759,26 @@ redirect_temporary_redirect(Config) when is_list(Config) ->
 	= httpc:request(post, {URL307, [],"text/plain", "foobar"},
 			[], []).
 %%-------------------------------------------------------------------------
+redirect_permanent_redirect() ->
+    [{doc, "The server SHOULD generate a Location header field in the response "
+      "containing a preferred URI reference for the new permanent URI. "
+      "The user agent MAY use the Location field value for automatic redirection. "
+      "The server's response content usually contains a short hypertext note with "
+      "a hyperlink to the new URI(s)."}].
+redirect_permanent_redirect(Config) when is_list(Config) ->
+
+    URL308 =  url(group_name(Config), "/308.html", Config),
+
+    {ok, {{_,200,_}, [_ | _], [_|_]}}
+	= httpc:request(get, {URL308, []}, [], []),
+
+    {ok, {{_,200,_}, [_ | _], []}}
+	= httpc:request(head, {URL308, []}, [], []),
+
+    {ok, {{_,200,_}, [_ | _], [_|_]}}
+	= httpc:request(post, {URL308, [],"text/plain", "foobar"},
+			[], []).
+%%-------------------------------------------------------------------------
 redirect_relative_uri() ->
     [{doc, "The server SHOULD generate a Location header field in the response "
       "containing a preferred URI reference for the new permanent URI.  The user "
@@ -2601,6 +2622,21 @@ handle_uri(_,"/307.html",Port,_,Socket,_) ->
 	"Location:" ++ NewUri ++  "\r\n" ++
 	"Content-Length:" ++ integer_to_list(length(Body))
 	++ "\r\n\r\n" ++ Body;
+handle_uri("HEAD","/308.html",Port,_,Socket,_) ->
+    NewUri = url_start(Socket) ++
+	integer_to_list(Port) ++ "/dummy.html",
+    "HTTP/1.1 308 Permanent Redirect \r\n" ++
+	"Location:" ++ NewUri ++  "\r\n" ++
+	"Content-Length:0\r\n\r\n";
+handle_uri(_,"/308.html",Port,_,Socket,_) ->
+    NewUri = url_start(Socket) ++
+	integer_to_list(Port) ++ "/dummy.html",
+    Body = "<HTML><BODY><a href=" ++ NewUri ++
+	">New place</a></BODY></HTML>",
+    "HTTP/1.1 308 Permanent Redirect \r\n" ++
+	"Location:" ++ NewUri ++  "\r\n" ++
+	"Content-Length:" ++ integer_to_list(length(Body))
+	++ "\r\n\r\n" ++ Body;
 
 handle_uri(_,"/404.html",_,_,_,_) ->
     "HTTP/1.1 404 not found\r\n" ++
diff --git a/lib/inets/test/httpd_poll.erl b/lib/inets/test/httpd_poll.erl
index f86e3a979b..d28a68c0c6 100644
--- a/lib/inets/test/httpd_poll.erl
+++ b/lib/inets/test/httpd_poll.erl
@@ -332,6 +332,7 @@ status_to_message(303) -> "Section 10.3.4: See Other";
 status_to_message(304) -> "Section 10.3.5: Not Modified";
 status_to_message(305) -> "Section 10.3.6: Use Proxy";
 status_to_message(307) -> "Section 10.3.8: Temporary Redirect";
+status_to_message(308) -> "RFC 9110, Section 15.4.9: Permanent Redirect";
 status_to_message(400) -> "Section 10.4.1: Bad Request";
 status_to_message(401) -> "Section 10.4.2: Unauthorized";
 status_to_message(402) -> "Section 10.4.3: Peyment Required";
diff --git a/lib/inets/test/httpd_time_test.erl b/lib/inets/test/httpd_time_test.erl
index 87a913fce4..d00dc40e61 100644
--- a/lib/inets/test/httpd_time_test.erl
+++ b/lib/inets/test/httpd_time_test.erl
@@ -450,6 +450,7 @@ status_to_message(303) -> "Section 10.3.4: See Other";
 status_to_message(304) -> "Section 10.3.5: Not Modified";
 status_to_message(305) -> "Section 10.3.6: Use Proxy";
 status_to_message(307) -> "Section 10.3.8: Temporary Redirect";
+status_to_message(308) -> "RFC 9110, Section 15.4.9: Permanent Redirect";
 status_to_message(400) -> "Section 10.4.1: Bad Request";
 status_to_message(401) -> "Section 10.4.2: Unauthorized";
 status_to_message(402) -> "Section 10.4.3: Peyment Required";
-- 
2.35.3

openSUSE Build Service is sponsored by