Make 303 redirects do GET like Net Framework (#49095)
authorTimothyByrd <55807828+TimothyByrd@users.noreply.github.com>
Tue, 9 Mar 2021 23:29:00 +0000 (15:29 -0800)
committerGitHub <noreply@github.com>
Tue, 9 Mar 2021 23:29:00 +0000 (15:29 -0800)
* Make 303 redirects do GET like Net Framework

In Net Framework, PUT redirects on a 303 do a GET.
Net 5.0 breaks compatibility with this.
See https://github.com/dotnet/runtime/issues/28998
This commit causes redirects of a 303 to do a GET for all methods except HEAD.

Co-authored-by: Timothy Byrd <timothy.byrd@laserfiche.com>
src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AutoRedirect.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs

index ee41dbb..b7f9110 100644 (file)
@@ -44,8 +44,15 @@ namespace System.Net.Http.Functional.Tests
             foreach (int statusCode in new[] { 300, 301, 302, 303, 307, 308 })
             {
                 yield return new object[] { statusCode, "GET", "GET" };
-                yield return new object[] { statusCode, "POST", statusCode <= 303 ? "GET" : "POST" };
                 yield return new object[] { statusCode, "HEAD", "HEAD" };
+
+                yield return new object[] { statusCode, "POST", statusCode <= 303 ? "GET" : "POST" };
+
+                yield return new object[] { statusCode, "DELETE", statusCode == 303 ? "GET" : "DELETE" };
+                yield return new object[] { statusCode, "OPTIONS", statusCode == 303 ? "GET" : "OPTIONS" };
+                yield return new object[] { statusCode, "PATCH", statusCode == 303 ? "GET" : "PATCH" };
+                yield return new object[] { statusCode, "PUT", statusCode == 303 ? "GET" : "PUT" };
+                yield return new object[] { statusCode, "MYCUSTOMMETHOD", statusCode == 303 ? "GET" : "MYCUSTOMMETHOD" };
             }
         }
         public HttpClientHandlerTest_AutoRedirect(ITestOutputHelper output) : base(output) { }
index cf16936..856b4e6 100644 (file)
@@ -142,9 +142,10 @@ namespace System.Net.Http
             {
                 case HttpStatusCode.Moved:
                 case HttpStatusCode.Found:
-                case HttpStatusCode.SeeOther:
                 case HttpStatusCode.MultipleChoices:
                     return requestMethod == HttpMethod.Post;
+                case HttpStatusCode.SeeOther:
+                    return requestMethod != HttpMethod.Get && requestMethod != HttpMethod.Head;
                 default:
                     return false;
             }