Subject: NEW ISSUE: Clarify whether request must be processed before responding with redirection codes

From: cowwoc <[email-masked]>
Date: Wed, 03 Jul 2013 15:16:27 -0400

Hi,

Now that status code 303 and others no longer imply GET, we need to
clarify whether the server MUST or MUST NOT process the request before
returning a status code. For example, if a client invokes HTTP PUT and a
server returns 303, can the client assume that the request was processed? I
believe the intent is yes, but this should be explicitly clarified.

For each status code in the 300 range please clarify which HTTP methods are
acceptable (e.g. is 304 acceptable for methods other than GET?) and whether
the server MUST or MUST NOT process the request before responding with that
code.

Thank you,
Gili

---

From: Martin Thomson <[email-masked]>
Date: Wed, 3 Jul 2013 13:31:08 -0700

> the server MUST or MUST NOT process the request before responding with that

We just discussed a more general version of the same issue for
HTTP/2.0.  Whether the request has been processed or not is implicit
in the description of some of the codes.

For instance: 303 says:

   The response to the request can be found under a different URI and
   SHOULD be retrieved using a GET method on that resource.

That says to me that the response can be retrieved.  If the request
implies some action, and the only way to observe whether that action
has occurred is to GET the identified resource, then the exact time
that said action occurs need only be between receipt of the first (the
POST) request and the response to the redirected GET.  That allows
some freedom to servers that I'd be opposed to giving up.

If the results of the action can be observed in other ways, then those
ways need to be consistent with what the server has reported.  That is
entirely up to the server, though.

If there is a specific case where you believe this to be necessary,
because it creates an ambiguity, then by all means let us know.  My
read of the 3xx series says that only 303 has this potential for
interesting behavior.

---

From: cowwoc <[email-masked]>
Date: Wed, 03 Jul 2013 18:08:43 -0400

> read of the 3xx series says that only 303 has this potential for

Hi Martin,

     If a tree falls in a forest but no one is around to see it, does it 
make a sound? :)

     I think that ambiguity is dangerous from a threading point of view. 
Consider the following made-up scenario:

  * A user visits a website.
  * index.html causes the browser to queue 100 different HTTP operations
    (as a result of DOM or Javascript operations that run onLoad).
  * The current HTTP operation (say, an HTTP PUT) results in HTTP 303
    pointing to a different domain.
  * Is the browser forced to invoke HTTP GET in response to the HTTP 303
    right away? Or can it defer this action to the end of the queue?
  * If the browser invokes the operation right away, it risks losing the
    open connection to the first server (HTTP pipelining). If it defers
    the operation, it risks introducing race conditions from the point
    of view of the Javascript code.

     Also, please read http://stackoverflow.com/a/13755096/14731 in 
which I posted quotes from theRESTful Web Services 
<http://shop.oreilly.com/product/9780596529260.do> book regarding this 
topic.

     Finally, I've got a second (slightly related) topic I'd like to 
bring to your attention: http://stackoverflow.com/q/13867129/14731

Thanks,
Gili

---

From: Martin Thomson <[email-masked]>
Date: Wed, 3 Jul 2013 15:19:53 -0700

On 3 July 2013 15:08, cowwoc <[email-masked]> wrote:
>     If a tree falls in a forest but no one is around to see it, does it make
> a sound? :)

Exactly my point.  Except that I think we are drawing dramatically
different conclusions from a pragmatic perspective.

I'm not sure that any of your questions are especially hard to answer,
though I don't see how pipelining plays into this at all.

---

From: cowwoc <[email-masked]>
Date: Thu, 04 Jul 2013 02:14:37 -0400

> though I don't see how pipelining plays into this at all.

     I was going to respond with a concrete example but couldn't come up 
with one. On the flip side, what do you think we would lose by mandating 
that a server had to carry out the operation before returning HTTP 303? 
I mean, can you come up with a concrete optimization that would benefit 
from leaving this unspecified?

Thanks,
Gili

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 4 Jul 2013 18:22:47 +1000

On 04/07/2013, at 4:14 PM, cowwoc <[email-masked]> wrote:

>    I was going to respond with a concrete example but couldn't come up with one. On the flip side, what do you think we would lose by mandating that a server had to carry out the operation before returning HTTP 303? I mean, can you come up with a concrete optimization that would benefit from leaving this unspecified?

Hi Gili,

<https://svn.tools.ietf.org/svn/wg/httpbis/draft-ietf-httpbis/latest/p2-semantics.html#status.3xx> starts:

> The 3xx (Redirection) class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request.

So, we already say that the request isn't fulfilled when you see a 3xx. The server, by issuing a 303, is making an assertion that there's something useful at the other end; if there isn't, it's not telling the truth, and the client will have to deal with that. 

Making an explicit binding between receiving the entire request and the state of a completely separate resource seems like unnecessary coupling to me; how would doing so help interop?

Cheers,

--
Mark Nottingham   http://www.mnot.net/

---

From: Julian Reschke <[email-masked]>
Date: Thu, 04 Jul 2013 11:36:34 +0200

On 2013-07-03 21:16, cowwoc wrote:
 > ...

How so?

303 always implied GET. 301, 302, and 307 never implied GET.

The only change we made is to allow 301 and 302 to rewrite POST to GET 
(because that's what UAs do).

Best regards, Julian

---

From: cowwoc <[email-masked]>
Date: Thu, 04 Jul 2013 09:44:32 -0400

> (because that's what UAs do).

     I think you misunderstood what I meant. In HTTP 2.0, the following 
sentence was added to the description of HTTP 303: "This status code is 
applicable to any HTTP method."

     Meaning, although it was originally meant to be returned in 
response to HTTP POST, it is now legal to return from HTTP 
GET/PUT/DELETE as well. At least, that is my interpretation.

Gili

---

From: cowwoc <[email-masked]>
Date: Thu, 04 Jul 2013 10:00:26 -0400

On 04/07/2013 4:22 AM, Mark Nottingham wrote:
> So, we already say that the request isn't fulfilled when you see a 3xx.
Hi Mark,

     That isn't strictly true. The language of the new specification is 
a little loosy goosy.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4 says 
the client "SHOULD" respond to HTTP 303 by issuing HTTP GET on the 
returned URL.
https://svn.tools.ietf.org/svn/wg/httpbis/draft-ietf-httpbis/latest/p2-semantics.html#status.303 
says the client "ought to" respond by doing the same.

     First of all, "ought to" isn't as well defined as "should". 
Secondly, both imply to me that issuing a subsequent HTTP GET is an 
optional operation. If it's an optional operation, then I am 
interpreting it as meaning that the original request may or may not be 
fulfilled because from the client's point of view, its job is finished 
(I am not required to issue an HTTP GET to hold up my end of the contract).

> The server, by issuing a 303, is making an assertion that there's something useful at the other end; if there isn't, it's not telling the truth, and the client will have to deal with that.
>

     I guess I agree with you. I just don't like see any sort of 
ambiguity in specifications I read.

     I'd like the specification to explicitly state: "The request is 
only guaranteed to have been processed after the client issues HTTP GET 
on a returned URL and is no longer redirected using HTTP 3xx". 
Obviously, you'd have to clean up the language but you get my point. 
That way there is no longer any ambiguity as to the client's 
responsibility (HTTP 303 will imply "MUST" instead of "SHOULD" if the 
client wishes to complete the original request) and you get to keep the 
flexibility you wanted on the server end.

Gili

---

From: Julian Reschke <[email-masked]>
Date: Thu, 04 Jul 2013 16:01:00 +0200

> applicable to any HTTP method."

You are referring to the revision of HTTP/1.1, not HTTP/2.0, right?

> GET/PUT/DELETE as well. At least, that is my interpretation.

It was always legal to return it for something different than POST. The 
change that we made was in order to clarify that

"This method exists primarily to allow the output of a POST-activated 
script to redirect the user agent to a selected resource." (RFC 2616)

does not imply that it's for POST only. See 
<http://lists.w3.org/Archives/Public/ietf-http-wg/2007JulSep/0048.html> 
for context.

Best regards, Julian

---

From: cowwoc <[email-masked]>
Date: Thu, 04 Jul 2013 10:05:40 -0400

> You are referring to the revision of HTTP/1.1, not HTTP/2.0, right?

     Yes. Comparing 
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4 to 
https://svn.tools.ietf.org/svn/wg/httpbis/draft-ietf-httpbis/latest/p2-semantics.html#status.303 
I see this new sentence.

> It was always legal to return it for something different than POST. 
> The change that we made was in order to clarify that
>
> <http://lists.w3.org/Archives/Public/ietf-http-wg/2007JulSep/0048.html> for 
> context.
>
> Best regards, Julian
>

     I understand. I'm saying that the 
http://en.wikipedia.org/wiki/Post/Redirect/Get paradigm is well 
understood but once you open the door to HTTP GET/PUT/DELETE it brings 
up the question of what it all means. It's not that this wasn't possible 
in the past. It's that returning HTTP 303 from these other methods isn't 
common or well understood yet.

Gili

---

From: Julian Reschke <[email-masked]>
Date: Thu, 04 Jul 2013 16:42:22 +0200

> Making an explicit binding between receiving the entire request and the state of a completely separate resource seems like unnecessary coupling to me; how would doing so help interop?

I can understand why people are uneasy about too much wiggle room.

My understanding (coming from WebDAV) for a PUT and a 301/302/307 
response always was: "the server understood what you want to do, but 
asks you to apply the request to the redirect target instead". That is, 
the actual PUT operation was not executed.

Right? Wrong?

For 303 the situation obviously is more complicated though.

Best regards, Julian

---

From: cowwoc <[email-masked]>
Date: Thu, 04 Jul 2013 11:10:24 -0400

On 04/07/2013 10:42 AM, Julian Reschke wrote:
> asks you to apply the request to the redirect target instead". That 
> is, the actual PUT operation was not executed.
>
> Right? Wrong?
>
Hi Julian,

     That's been my understanding as well.

     Honestly, I think the explanation provided by the RESTful Web 
Services book was the best: http://stackoverflow.com/a/13636991/14731

     It explains HTTP 307 as follows:

For GET requests, where the only thing being requested is that the 
server send a representation, this status code is identical to 303 ("See 
Other"). A typical case where 307 is a good response to a GET is when 
the server wants to send a client to a mirror site. But for*POST, PUT, 
and DELETE requests*, where the server is expected to take some action 
in response to the request, this status code is significantly different 
from 303.

A 303 in response to a*POST, PUT, or DELETE*means that the operation has 
succeeded but that the response entity-body is not being sent along with 
this request. If the client wants the response entity-body, it needs to 
make a GET request to another URI. A 307 in response to a POST, PUT, or 
DELETE means that the server has not even tried to perform the 
operation. The client needs to resubmit the entire request to the URI in 
the|Location|header.

     This explanation removes all ambiguity from both HTTP 303 and HTTP 
307 for all methods. I wish the specification was equally clear.

Gili

---

From: Amos Jeffries <[email-masked]>
Date: Fri, 05 Jul 2013 03:27:27 +1200

On 5/07/2013 2:00 a.m., cowwoc wrote:
>>> The 3xx (Redirection) class of status code indicates that further 
>>> action needs to be taken by the user agent in order to fulfill the 
>>> request.

Define "fulfilled".

The specification uses it to mean the server has completely received, 
operated on and finished with the request. What has not happened is 
delivery of any response payload. It is for origin server use when the 
payload is not particularly important and clients may optionally ignore 
it, some can benefit greatly from not receiving it. Clients which 
believe otherwise will followup with the GET mentioned - but *that* part 
is optional.

The other redirection codes are unsafe to use with some methods as the 
existing middleware implementations use them freely and there is no 
indication that the origin server has even received the request, let 
alone processed it fully.

https://svn.tools.ietf.org/svn/wg/httpbis/draft-ietf-httpbis/latest/p1-messaging.html#introduction
paragraph 3 "an HTTP request can be considered in isolation rather than 
being associated with a specific type of client or a predetermined 
sequence of application steps"

Thusly by replacing "SHOULD" with "ought to" the protocol is now placing 
no binding requirements on clients following any multi-stage 
request/reply sequence.

>
>> The server, by issuing a 303, is making an assertion that there's 
>> something useful at the other end; if there isn't, it's not telling 
>> the truth, and the client will have to deal with that.
>>
>> Making an explicit binding between receiving the entire request and 
>> the state of a completely separate resource seems like unnecessary 
>> coupling to me; how would doing so help interop?
>
> only guaranteed to have been processed after the client issues HTTP 
> GET on a returned URL

Define "processed". It *has* been processed as far as the server 
POST/PUT/DELETE/WHATEVER processing is willing or able to go. That is a 
guarantee. With a lot more certainty than any of the other redirect 
codes offer.

> and is no longer redirected using HTTP 3xx". Obviously, you'd have to 
> clean up the language but you get my point. That way there is no 
> longer any ambiguity as to the client's responsibility (HTTP 303 will 
> imply "MUST" instead of "SHOULD" if the client wishes to complete the 
> original request) and you get to keep the flexibility you wanted on 
> the server end.

There is no ambiguity about the clients _responsibility_. It is 100% 
responsible for deciding to (or not) fetch the indicated payload.
What is ambiguous is whether any given client will make said choice. It 
is up to the implementer to decide that.

Amos

---

From: cowwoc <[email-masked]>
Date: Thu, 04 Jul 2013 12:47:20 -0400

On 04/07/2013 11:27 AM, Amos Jeffries wrote:
> First of all, "ought to" isn't as well defined as "should". Secondly, 
> both imply to me that issuing a subsequent HTTP GET is an optional 
> operation. If it's an optional operation, then I am interpreting it as 
> meaning that the original request may or may not be fulfilled because 
> from the client's point of view, its job is finished (I am not 
> required to issue an HTTP GET to hold up my end of the contract).
>
> Define "fulfilled".
>
> payload is not particularly important and clients may optionally 
> ignore it, some can benefit greatly from not receiving it. Clients 
> which believe otherwise will followup with the GET mentioned - but 
> *that* part is optional.

     So now you're telling me that a server must fulfill the request 
before HTTP 303? Or did I misunderstand you?

> paragraph 3 "an HTTP request can be considered in isolation rather 
> than being associated with a specific type of client or a 
> predetermined sequence of application steps"
>
> Thusly by replacing "SHOULD" with "ought to" the protocol is now 
> placing no binding requirements on clients following any multi-stage 
> request/reply sequence.

     Isn't "MAY" more appropriate in this situation? "In order to 
satisfy the original request, a user agent MAY perform a retrieval 
request using the Location URI [...] and present the eventual result as 
an answer to the original request"

> POST/PUT/DELETE/WHATEVER processing is willing or able to go. That is 
> a guarantee. With a lot more certainty than any of the other redirect 
> codes offer.

     In my opinion, that part is vague. My understanding of the current 
specification is that the operation is guaranteed to get processed 
before I issue HTTP GET on the final URL. I am asking for (but don't 
see) a guarantee that the POST/PUT/DELETE/WHATEVER operation must be 
fulfilled before returning HTTP 303. If you are implying that the 
specification meant to guarantee this, I would ask you to be more 
explicit about it.

> What is ambiguous is whether any given client will make said choice. 
> It is up to the implementer to decide that.

     You're right, I misspoke. There is no ambiguity about the client's 
responsibility. There is ambiguity about the *server's* responsibility 
as to whether the operation must take place before returning HTTP 303 or 
whether it defers the operation until the client invokes HTTP GET on the 
Location URI.

Gili

---

From: Amos Jeffries <[email-masked]>
Date: Fri, 05 Jul 2013 19:41:15 +1200

On 5/07/2013 4:47 a.m., cowwoc wrote:
>> operation. If it's an optional operation, then I am interpreting it 
>> as meaning that the original request may or may not be fulfilled 
>> because from the client's point of view, its job is finished (I am 
>> not required to issue an HTTP GET to hold up my end of the contract).
>>
>> Define "fulfilled".
>>
>> delivery of any response payload. It is for origin server use when 
>> the payload is not particularly important and clients may optionally 

Any request needs to be fulfilled before the reponse is sent. At least 
sufficiently to provide the guarantees the status code requires. The 
difference with 3xx is that there is a *second* request which has not 
necessarily been fulfilled yet. The followup to 303 may *never* reach 
the server or any system associated with it simply because the GET 
response is cacheable - some ISP over in the back of beyond may have 
cached it and be delivering the response to the client you just sent 303 to.

There are other protocol features for scoping the responsibilities and 
determinism better. But it is the implementations responsibility to use 
those other features to tune the open possibilities of 303 semantics.

>
>>
>> The other redirection codes are unsafe to use with some methods as 
>> the existing middleware implementations use them freely and there is 
>> no indication that the origin server has even received the request, 
>> let alone processed it fully.
>>
> request using the Location URI [...] and present the eventual result 
> as an answer to the original request"

Well it was  SHOULD, and there were reasons for that (though I'm not 
aware which). The WG practice has been to replace overly restrictive 
SHOULD with a phrase that lacks the normative strictness while still 
conveying some importance for the instruction - "ought to".

>>> and is no longer redirected using HTTP 3xx". Obviously, you'd have 
>>> to clean up the language but you get my point. That way there is no 
>>> longer any ambiguity as to the client's responsibility (HTTP 303 
>>> will imply "MUST" instead of "SHOULD" if the client wishes to 
>>> complete the original request) and you get to keep the flexibility 
>>> you wanted on the server end.
>>
> as to whether the operation must take place before returning HTTP 303 
> or whether it defers the operation until the client invokes HTTP GET 
> on the Location URI.
>
> Gili
>