]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: 308 redirects should use the previous hop's body
authorDamien Neil <dneil@google.com>
Wed, 6 Nov 2024 19:08:51 +0000 (11:08 -0800)
committerDamien Neil <dneil@google.com>
Wed, 6 Nov 2024 21:01:09 +0000 (21:01 +0000)
On a 301 redirect, the HTTP client changes the request to be
a GET with no body.

On a 308 redirect, the client leaves the request method and
body unchanged.

A 308 following a 301 should preserve the rewritten request
from the first redirect: GET with no body. We were preserving
the method, but sending the original body. Fix this.

Fixes #70180

Change-Id: Ie20027a6058a82bfdffc7197d07ac6c7f98099e2
Reviewed-on: https://go-review.googlesource.com/c/go/+/626055
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/net/http/client.go
src/net/http/client_test.go

index 67b2a89ac91b35431f6270db58026b9c457b3763..fda7815436c25c0b874b089e366530df92b57a5c 100644 (file)
@@ -611,7 +611,7 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) {
 
                // Redirect behavior:
                redirectMethod string
-               includeBody    bool
+               includeBody    = true
        )
        uerr := func(err error) error {
                // the body may have been closed already by c.send()
@@ -728,11 +728,16 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) {
                        return nil, uerr(err)
                }
 
-               var shouldRedirect bool
-               redirectMethod, shouldRedirect, includeBody = redirectBehavior(req.Method, resp, reqs[0])
+               var shouldRedirect, includeBodyOnHop bool
+               redirectMethod, shouldRedirect, includeBodyOnHop = redirectBehavior(req.Method, resp, reqs[0])
                if !shouldRedirect {
                        return resp, nil
                }
+               if !includeBodyOnHop {
+                       // Once a hop drops the body, we never send it again
+                       // (because we're now handling a redirect for a request with no body).
+                       includeBody = false
+               }
 
                req.closeBody()
        }
index 04e2e32cf07777dfb862f07f0139c33de63dacee..429b8f1d2cd556045e7bc1e0c4e4c30e3a2b0251 100644 (file)
@@ -346,7 +346,7 @@ func TestPostRedirects(t *testing.T) {
                `POST /?code=307&next=303,308,302 "c307"`,
                `POST /?code=303&next=308,302 "c307"`,
                `GET /?code=308&next=302 ""`,
-               `GET /?code=302 "c307"`,
+               `GET /?code=302 ""`,
                `GET / ""`,
                `POST /?code=308&next=302,301 "c308"`,
                `POST /?code=302&next=301 "c308"`,
@@ -376,7 +376,7 @@ func TestDeleteRedirects(t *testing.T) {
                `DELETE /?code=301&next=302,308 "c301"`,
                `GET /?code=302&next=308 ""`,
                `GET /?code=308 ""`,
-               `GET / "c301"`,
+               `GET / ""`,
                `DELETE /?code=302&next=302 "c302"`,
                `GET /?code=302 ""`,
                `GET / ""`,
@@ -385,7 +385,7 @@ func TestDeleteRedirects(t *testing.T) {
                `DELETE /?code=307&next=301,308,303,302,304 "c307"`,
                `DELETE /?code=301&next=308,303,302,304 "c307"`,
                `GET /?code=308&next=303,302,304 ""`,
-               `GET /?code=303&next=302,304 "c307"`,
+               `GET /?code=303&next=302,304 ""`,
                `GET /?code=302&next=304 ""`,
                `GET /?code=304 ""`,
                `DELETE /?code=308&next=307 "c308"`,