Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
Following a 303 after a PUT requests uses PUT instead of GET #5237
I know you had issues opened with this kind of title, and people were using
I did this
( 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 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
Linux arceus 5.4.30-1-MANJARO #1 SMP PREEMPT Thu Apr 2 17:31:45 UTC 2020 x86_64 GNU/Linux
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 :
MDN says :
And of the official specifications states :
(sorry for the short reply and lack of formating, I'm on mobile)
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.
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:
It states :
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
I have a few comments on this thread:
And here's a handy table: