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
Following a 303 after a PUT requests uses PUT instead of GET #5237
Comments
I'm pretty sure that applies only to POST, @jzakrzewski's comment seems wrong. libcurl has CURLOPT_POSTREDIR but there is no similar option for redirection on PUT. edit: See 8b7fff3, #4859 (comment) |
Yes, I don't see any reference to changing the method to GET on PUT redirects. So I stand corrected on that one.
For me it means the redirects must work the same for POST and PUT. |
According to most resources and documentation, a user agent following a 303 redirect must use the HEAD or GET verb : Wikipedia:
https://en.m.wikipedia.org/wiki/HTTP_303 MDN says :
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303 And of the official specifications states :
https://tools.ietf.org/html/rfc7231#section-6.4.4 (sorry for the short reply and lack of formating, I'm on mobile) |
I don't see anything in rfc7231#section-6.4.4 which says this applies to anything else, but |
For me it's a bit unclear. Yes, section 6.4 only names POST specifically but there's also:
And in 4.2.1:
From the other hand in 4.2.2:
So it should at least be safe to issue PUT after redirection. |
When it doubt, file an issue: https://github.com/httpwg/http-core. Here is a similiar one, applies to |
Oh, I think I've found the key phrase.
So I guess curl's behaviour is at least correct according to this specs. Even if a bit surprising for the user. |
Section 6.4.4 is saying :
And few lines below :
About this :
I don't get you point, it is probably safe to issue a PUT request with the same parameters to the same URL, but it doesn't means anything about using the PUT verb to issue a redirect to another URI. |
My point is that PUT is not among safe methods what would imply the method should be changed to GET on redirect but being idempotent not changing the method is at least safe, so it's not a dangerous bug (if a bug at all). In any case my next comment citing section 4.3.4 seems to make it clear that not changing the method is in fact an allowed behaviour (unless I don't understand / miss something). |
I really don't see anything about changing the verb or not in 4.3.4, it only states the server MUST send a 3xx redirect if the resource has changed URI and the user agent MAY follow or not that redirection. But nothing is said about verbs. In other hand, there is a specific 307/308 redirect status code designed to redirect without changing verb in any case. I'm really confused about where is the ambiguity here as the spec clearly states in 6.4.4 : A user agent can perform a retrieval request targeting that URI (a GET or HEAD request if using HTTP) [...] This status code is applicable to any HTTP method Maybe I'm getting this wrong but it seems to be clear that the specs are saying : a 303 redirect can be followed by user agent, with a GET or HEAD request. I will probably |
I sent an email regarding this issue to their mailing list. I'll let you know if I get any answers By the way I also stumbled upon the specs of the fetch standard: https://fetch.spec.whatwg.org/#http-redirect-fetch It states :
|
fetch is for browsers, not sure whether this applies here. |
I'm pretty sure following redirect in fetch is basic http implementation. I'm not sure while it would differ. fetch is after all, implementing the http spec as any user agent would. |
In 4.3.4 it says "appropriate" 3xx response you can keep PUT, but is not more specific than that. Since PUT is meant to replace the specified resource one could argue 303 is not appropriate since a 303 server redirect is to something that represents (but isn't AFAICT) the resource, in other words see this other resource. OTOH the current behavior has been in place a long time and I don't think anybody has brought this up before. |
RFC2616 does say something really interesting about this :
And few lines before, in 10.3.3 302 Found :
I'm kind of lost on which RFC is the latest we should follow, but it seems to me :
I do understand no-one has brought this up, as it might not be a common use case, although many ressources on the web claims REST APIs, or server implementations should respond with a 303 redirect after a ressource was updated with post or put. I just found RFC7231 (dated June 2014 and seems to be be latest spec) seems to aknowledge this kind of issues.
If I understand this correctly (English is not my native language) :
For the record, in the same document 307 redirect are defined as follow :
|
Prior to this change if there was a 303 reply to a PUT request then the subsequent request to respond to that redirect would also be a PUT. It was determined that was most likely incorrect based on the language of the RFCs. Basically 303 means "see other" resource, which implies it is most likely not the same resource, therefore we should not try to PUT to that different resource. Refer to the discussion in curl#5237 for more information. Fixes curl#5237 Closes #xxxx
Please let me know if #5248 solves it. |
I have a few comments on this thread:
In summary:
And here's a handy table:
|
@awwright why did you mark 303 and POST to GET as "No"? |
@michael-o You're right |
I know you had issues opened with this kind of title, and people were using
-X PUT
to force PUT, but not this time.I did this
touch somefile.txt
curl -T 'somefile.txt' -v -L https://httpstat.us/301 > /dev/null
( as adviced here : #578 (comment) )
I expected the following
curl should send somefile.txt with a PUT request, then follow the 303 redirect with a GET request. Instead it uses the PUT verb.
Issue does not occur when server returns a 301 or 302 redirect.
If it isn't the right way to send a put request and follow a 303 response, I'm sorry to have bothered you, and would be glad to know how to do that !🙂
Output of the command
(some tls and progress bar logs have been redacted for readability)
curl/libcurl version
curl 7.69.1 (x86_64-pc-linux-gnu) libcurl/7.69.1 OpenSSL/1.1.1f zlib/1.2.11 libidn2/2.3.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh2/1.9.0 nghttp2/1.40.0
Release-Date: 2020-03-11
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets
operating system
Linux arceus 5.4.30-1-MANJARO #1 SMP PREEMPT Thu Apr 2 17:31:45 UTC 2020 x86_64 GNU/Linux
The text was updated successfully, but these errors were encountered: