Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: 301 redirects after a 303 redirect from a POST request don't work #9348

Closed
conradkdotcom opened this issue Dec 16, 2014 · 5 comments

Comments

Projects
None yet
6 participants
@conradkdotcom
Copy link

commented Dec 16, 2014

Hello everyone (reading this) 馃槂

I'm building a tool that fetches a URL from a POST endpoint, which returns a 303 - See other response with the wanted URL in the Location header. Sometimes this Location itself returns a 301.

Here's the issue: Go seems to process the redirect from the 303 just fine, per line 253 of the source:
http://golang.org/src/net/http/client.go

But once we get to the 301, Go still checks if it should redirect with the function used for POST requests. So it doesn't actually redirect the 301, even though it got there through a GET request (see line 341 of the source).

This seems odd to me. Seems like it could be a bug. Am I missing something? If this is a bug, would a fix for this make sense considering BC?

I'm posting this on behalf of my current employer, shopping24 GmbH.

@bradfitz bradfitz changed the title 301 redirects after a 303 redirect from a POST request don't work net/http: 301 redirects after a 303 redirect from a POST request don't work Dec 17, 2014

@bradfitz bradfitz added this to the Go1.5Maybe milestone Dec 17, 2014

@akavel

This comment has been minimized.

Copy link
Contributor

commented Feb 9, 2015

Also an additional related question, as I couldn't find it stated explicitly in sources, and after googling around I'm still not certain: are 301 and 307 not followed in http.Post() (and .Do() with POST) specifically because they Require Interaction From User as per the RFCs? If so, could this possibly be noted explicitly in the comment above http.Post(), that this is left as an excercise for the reader?

tx

@ademarre

This comment has been minimized.

Copy link

commented Mar 27, 2015

@akavel, Here's my understanding of it...

RFC 2616 (HTTP/1.1 June 1999) does state that clients must not automatically redirect POST requests that return 301 or 307. (Only GET and HEAD may be automatically redirected.) But it also says the same thing for 302.

I think the underlying principle of the matter is that if the client is going to resend the POST request body data, then RFC 2616 wants clients to get the user's consent. The trouble is that most client implementations did not resend the POST data when following 301 or 302 redirects. So the principle of getting user consent doesn't really apply.

RFC 7231 (HTTP/1.1 June 2014) changes this. It ratifies the common behavior of 301 and 302 (to not re-POST), and in doing so it leaves it up to the client to determine when it is safe to automatically redirect.

http://tools.ietf.org/html/rfc7231#appendix-B

   The set of request methods that are safe to automatically redirect is
   no longer closed; user agents are able to make that determination
   based upon the request method semantics.  The redirect status codes
   301, 302, and 307 no longer have normative requirements on response
   payloads and user interaction.  (Section 6.4)

   The status codes 301 and 302 have been changed to allow user agents
   to rewrite the method from POST to GET.  (Sections 6.4.2 and 6.4.3)

I think good default behavior for net/http would be to automatically follow redirects only for status codes where data is not re-POSTed. Consequently, if it handles 301s as POST/301/GET, then it should have no reason to not automatically follow the redirect.

I'm not sure what net/http/client does in every scenario, but I believe all of the following would be technically legal behaviors, paired with the auto-redirect behavior I'd expect of each client behavior:

POST/301/GET  - auto follow
POST/301/POST - get user consent
POST/302/GET  - auto follow
POST/302/POST - get user consent
POST/303/GET  - auto follow
POST/307/POST - get user consent

   */3**/GET  - auto follow
   */3**/POST - get user consent

Getting back to this bug report...

POST/303/GET/301/GET - auto follow
POST/303/GET/307/GET - auto follow
@rsc

This comment has been minimized.

Copy link
Contributor

commented Jun 29, 2015

Too late for Go 1.5.

@gopherbot

This comment has been minimized.

Copy link

commented Oct 29, 2016

CL https://golang.org/cl/29852 mentions this issue.

@gopherbot

This comment has been minimized.

Copy link

commented Dec 20, 2016

CL https://golang.org/cl/34657 mentions this issue.

gopherbot pushed a commit that referenced this issue Dec 20, 2016

net/http, doc: more redirect documentation
Updates #18347
Updates #9348

Change-Id: I115203b0be3eb2e7e269ff28e2f3c47eeca86038
Reviewed-on: https://go-review.googlesource.com/34657
Reviewed-by: Russ Cox <rsc@golang.org>

@golang golang locked and limited conversation to collaborators Dec 20, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can鈥檛 perform that action at this time.