Is the use of Location header in HTTP 202 response RFC-compliant?
Asked Answered
C

5

34

I have a great conceptual discussion with my coworkers about the use of Location header in 202 Accepted response.

The story began analyzing the behavior of PHP header() function from here. The interesting excerpt:

The second special case is the "Location:" header. Not only does it send this header back to the browser, but it also returns a REDIRECT (302) status code to the browser unless the 201 or a 3xx status code has already been set.

They didn't include 202 status code in this default behavior. It seems like they don't expect that 202 response has a Location and indeed:

header("HTTP/1.1 202");
header("Location: http://example.com");

redirect the client to Location URL. Of course, it is possible to change this behavior with third parameter of header() function but what attracted my attention was: Why they understood that by default 202 is not expected to hold a Location header?

Then I review the RFC looking for the official meaning of 202 status. The interesting excerpt:

The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.

It doesn't explicitly refer to Location header like previous (in the same RFC doc) 201 response does. That would probably be the reason why PHP guys understood that 202 response should not hold Location header. Would a pointer be interpreted as Location header or PHP guys made a wrong assumption? If the standard allow Location header with 202 response: should not be the official documentation more explicit like 201 response definition?

Finally I reviewed the most recently RFC version and find a little change in redaction:

The representation sent with this response ought to describe the request's current status and point to (or embed) a status monitor that an provide the user with an estimate of when the request will be fulfilled.

Again it is not explicit enough to assume that point to means Location header.

In short, after above revisions: Am I being RFC-compliant using Location header with 202 response?

Customhouse answered 5/10, 2014 at 3:3 Comment(0)
C
32

Finally, I received a response from R. Fielding:

enter image description here

202 is a success status. The pointer mentioned is just hypertext in the body of the response. A 303 should be sent if you want to use Location to redirect the client to another resource. The result of the redirected request can be a 202.

....Roy

So, the Location header should not be used in 202 Accepted response. The PHP guys did the right interpretation.

Edit March, 2017: Sorry, I forgot to add other messages we exchanged in the same thread at that moment so I am posting now for the record:

me: On the section 4.1 of the RFC 7240 the author (J. Snell) give an example using Location header in 202 Accepted response. Is he wrong? It is like many people understand this behavior from RFC 7231. Can you send me any reference about this controversial issue?

Roy: The example is given without instruction, so he is not wrong because he doesn't say what it means. Location can be sent in any message. What it means is only defined for certain status codes.

For example, if he had said that the user agent would make use of that Location field to provide a status indicator to the user, then he would have been wrong. It might be a good idea, but it isn't part of the standard.

PHP makes a wrong assumption that Location is only used in 201 and 3xx responses, but it is allowed to do so because its internal API is not HTTP; it translates the stream to HTTP instead.

There is no controversy. In order to be part of the standard, at least two independent implementations would have to show the same behavior. In this case, none do.

Customhouse answered 6/10, 2014 at 16:20 Comment(1)
I am not sure I follow Fielding’s argument: 201 is also a success status code (not a redirection status code), yet the Location header field is allowed for it.Tinder
T
9

From RFC-2616:

The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.

I think the key here is, "the entity", since the question here is whether we include the status indication in the response headers or in the response body. Almost everywhere an entity is referred to, it seems to imply the response body. For example:

10.5 Server Error 5xx

Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. User agents SHOULD display any included entity to the user. These response codes are applicable to any request method.

I haven't seen a browser ever display response headers to a user. And for 303s:

10.3.4 303 See Other

The different URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).

You won't get a hypertext response in headers.

However, section 7 is quite clear about what the entity refers to:

An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.

I think that in your case, what you are doing is RFC-2616-compliant. However, realistically this all comes down to client implementation. Can the client receiving your 202 response handle a Location: header for a 2xx response? That should be your litmus test for how to respond, and is also the test used to drive standards during their standardization/documentation.

Townsman answered 5/10, 2014 at 3:17 Comment(4)
Follow your explanation I should take entity concept as entity-body. Great! but if this is right then RFC 2616: The entity returned with this response... means that status indication should be placed in entity-body, NOT in Location. Every possible use of Location header has been explicitly mentioned across the whole RFC as I have seen. Yes I know that it would be as simple as just include the Location, then read it from client but my question is actually if it is conceptually correct according to RFC.Customhouse
I think it is compliant with the text of the RFC.Townsman
Thanks for your explanation. I voted. This issue is not clear enough form me. I really believe that RFC should be a little more explicit or may be I need a response from the RFC authors (LOL).Customhouse
My tests show that Chrome and HTTPIE re-interprets a 202 response with Location header as 302 response with Location header.Anamariaanamnesis
G
5

Actually, as per the rfc 7240 https://www.rfc-editor.org/rfc/rfc7240#section-4.1 you can send a 202 Status Code along with a Location header. That would be in an asynchronous response, though ,apparently, PHP won't allow you to do so.

Gould answered 24/10, 2014 at 14:16 Comment(1)
Great!!! I am contacting Roy to help me clarifying this. Maybe I will update my response. I voted your answer.Customhouse
P
1

From Microsoft Learn - Web API design best practices (Azure Architecture Center):

If you wait for completion before sending a response to the client, it may cause unacceptable latency. If so, consider making the operation asynchronous. Return HTTP status code 202 (Accepted) to indicate the request was accepted for processing but is not completed.

You should expose an endpoint that returns the status of an asynchronous request, so the client can monitor the status by polling the status endpoint. Include the URI of the status endpoint in the Location header of the 202 response. For example:

HTTP/1.1 202 Accepted
Location: /api/status/12345

If the client sends a GET request to this endpoint, the response should contain the current status of the request. Optionally, it could also include an estimated time to completion or a link to cancel the operation.

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status":"In progress",
    "link": { "rel":"cancel", "method":"delete", "href":"/api/status/12345" }
}

If the asynchronous operation creates a new resource, the status endpoint should return status code 303 (See Other) after the operation completes. In the 303 response, include a Location header that gives the URI of the new resource:

HTTP/1.1 303 See Other
Location: /api/orders/12345
Philanthropist answered 21/3 at 19:34 Comment(0)
B
0

The RFC admittly is vague on that concept. This means that the spec currently doesn't say how "Location" is used with 202, but on the other hand, it's not a license for libraries to simply replace the status code. So this is definitively a PHP bug.

Betatron answered 5/10, 2014 at 7:22 Comment(5)
It's not a bug, it's well-documented and intended functionality. That doesn't mean you have to like it or agree with the decision that the PHP authors made.Townsman
I don't believe that it is a bug but just a implementation decision based on the assumption that solely 201 response and 300 response family need the Location header. Therefore by default they assign 302 status code for response you put Location header in unless you define more specific Location-related response (201 or 3xx). I suppose they tried "to help us" preventing the creation of non-compliant RFC or nonsense response, e.g. 200 response with Location header doesn't make sense. In the same way they assumed that 202 response doesn't make sense, therefore they override status code with 302.Customhouse
I sent an email to Roy Fielding to clarify this issue. I will keep you posted.Customhouse
Don't email Roy, email the IETF HTTP Working Group.Betatron
I am not sure I follow Fielding’s argument: 201 is also a success status code (not a redirection status code), yet the Location header field is allowed for it.Tinder

© 2022 - 2024 — McMap. All rights reserved.