-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http: 302 redirect of DELETE to GET isn't RFC compliant #41377
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thank you for filing this issue @ncw! So back in 2016, I implemented this change (on a fun working weekend collaboration with @bradfitz) and the basis for that unconditional change of DELETE->GET was an advisory from Microsoft on how Internet Explorer and other implementations changed the game despite being non-RFC complaint, and here is what guided us https://docs.microsoft.com/en-us/archive/blogs/ieinternals/http-methods-and-redirect-status-codes and RFC 2616 does talk about the UNCONDITIONAL->GET caveat as per https://tools.ietf.org/html/rfc2616#section-10.3.3 and for posterity here is our guiding research that led us down that road https://docs.google.com/document/d/1LnWicNarwSdVWQ5RcgUOdHEGVcdR--Lravn6G0Hkg6c/ Suggestions to fixThis case clearly lands on the caveat of a modern server not handling the raised caveat, but in the 4+ years since, no one had reported this problem. Thus:
|
Thanks for the history of this change :-)
My first instinct was to create a bug report for onedrive asking for them to change the redirect to 307. However on reading the RFC I decided that I didn't really have a strong case - they would surely say that the Go http client is behaving strangely. What do you think? Note that the RFC you referenced 2616 is obsoleted by the one I referenced 7231 and 7231 doesn't contain the wording here from 2616 as far as I can see
I don't think that will be a good solution in this case. The server responds to GET requests just fine, however it returns a very unexpected error.
I think you can do that with |
seems unfortunate but working as intended. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
We used http.Client against a Microsoft Ondrive service.
When we issued a DELETE response the server responded with a 302 redirect and http.Client retried with a GET request.
We issue a DELETE request
The server responds with a 302 redirect
We then do a GET request on the redirected URL which doesn't work.
What did you expect to see?
I expected http.Client to redirect with a DELETE request.
According to RFC7231
I note that this only talks about POST to GET and not other methods in the historical reasons section.
So I'm not sure Go's implementation is RFC compliant here - the RFC doesn't say that user agents may change any other sort of method from POST to GET.
The code is here:
go/src/net/http/client.go
Lines 496 to 512 in 66e66e7
Which says for all methods other than GET or HEAD, change them to GET, whereas the RFC says you can change POST to GET only.
So I think backwards compatibility might demand that POST becomes GET so something like this would be more RFC compliant.
The current code seems to think the major distinction between 301/302 and 307/308 is whether the body is resent. I'm not sure the RFC supports that, but using that distinction I think the code code could look like
Reading the RFC it says nothing about request bodies vs headers. So I think to be most useful and most RFC compliant the 301,302 redirects should work just like the 307,308 redirects now we have the capability to resend the body if needed.
See: #18570
See: https://forum.rclone.org/t/purge-command-fails-on-onedrive/19048
The text was updated successfully, but these errors were encountered: