Bug #70273 [Opn]: header(): Setting the Location header will set a status code of 202 to 302.

From: Date: Mon, 17 Aug 2015 16:35:08 +0000
Subject: Bug #70273 [Opn]: header(): Setting the Location header will set a status code of 202 to 302.
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-195259@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=70273&edit=1 ID: 70273 User updated by: jeff at nd4c dot com Reported by: jeff at nd4c dot com Summary: header(): Setting the Location header will set a status code of 202 to 302. Status: Open Type: Bug Package: HTTP related Operating System: Any PHP Version: Irrelevant Block user comment: N Private report: N New Comment: After some more thought and research, I've again changed my mind. I do believe that there is a real bug with header() function. But the bug description is now different... header(): Setting the Location header will set the status code to 302 even if the status code has been passed as the third parameter with any previous header call. Test scripts: // This format would only // require knowing if we want to force the status code // Passing status code 202 as a "forced" status code header("HTTP/1.1 202 Accepted", true, 202); // This will still set the status code to 302, // even though the 202 was forced. header('Location: /some/arbitrary/uri'); // This format would require knowing both: // if we want to force the status code AND // also knowing when we are passing a header // that might change the status code // Passing status code 202 as a "forced" status code header("HTTP/1.1 202 Accepted", true, 202); // This will work as expected with a forced 202 status code. header('Location: /some/arbitrary/uri', false, 202); // Current solution: To force the status code as the last header. // This format would only require // knowing if we want to force the status code // This will still set the status code to 302 header('Location: /some/arbitrary/uri'); // Passing status code 202 as a "forced" status code as the last header header("HTTP/1.1 202 Accepted", true, 202); I believe that since settings header should be allowed in any order since the RFC on headers does not set any requirements on the order of setting headers. I also believe that passing in a Status Code as a forced status code, it should remain 'forced' and not be overwritten by any following header calls unless a status code is passed in as a new forced header. I also question the benefit of having a Location header automatically setting the status code to a 302. The setting of a Location header would always be done in a context where the program would know whether or not to set the status code. There is no need or even desire for a 'magic' side effect. These are typically frowned upon!! So, at this point, I now consider this a bug. I hope that helps. Previous Comments: ------------------------------------------------------------------------ [2015-08-14 23:32:03] requinix@php.net Actually, I think this is alright. RFC 2616 says <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3> > 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 could reasonably interpret "pointer to a status monitor" to include a Location header. But what do the major browsers do? Do they follow the redirect? ------------------------------------------------------------------------ [2015-08-14 22:23:33] jeff at nd4c dot com Agreed. After some more research, it appears that the use of the Location header for a 202 response is non-standard. There is nothing in any RFCs that I could find on the subject that would suggest using a Location header for a 202 response. On the other hand, none of them, in any way, suggest that it should not be used. There are several forum replies and the "http://restcookbook.com/" recommends it, but I don't at this time think this is a bug. Sorry for any time wasted or headaches about this. ------------------------------------------------------------------------ [2015-08-14 21:42:54] cmb@php.net RFC 7231, section 7.1.2 states[1]: | For 201 (Created) responses, the Location value refers to the | primary resource created by the request. For 3xx (Redirection) | responses, the Location value refers to the preferred target | resource for automatically redirecting the request. No mention of 202 responses in this section. IMHO, this is not a bug. [1] <http://tools.ietf.org/html/rfc7231#section-7.1.2> ------------------------------------------------------------------------ [2015-08-14 19:45:01] jeff at nd4c dot com Description: ------------ Setting the Location header will set a status code of 202 to 302. From the online documentation: (http://php.net/manual/en/function.header.php) ... 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. ... The auto redirect ignores status codes: 201 and 3xx, but it SHOULD also ignore status code: 202. Using the Location header for a 202 response is now the standard for a RESTful api. According to: http://restcookbook.com/Resources/asynchroneous-operations/ ...you can then issue at 202 (Accepted) response code. This informs the client that the request has been accepted and understood by the server, but the resource is not (yet) created. Send the temporary resource inside the Location header. Request: POST /blogs HTTP/1.1 <xml> blogdata </xml> Response: HTTP/1.1 202 Accepted Location: /queue/12345 ... Test script: --------------- header("HTTP/1.1 202 Accepted"); header('Location: /some/arbitrary/uri'); // This will change the status code to 302, but it shouldn't header('Location: /some/arbitrary/uri'); header("HTTP/1.1 202 Accepted", true, 202); // This works, always forcing the status code prevents the defaults redirect handling. Expected result: ---------------- Status code 202 should remain as 202 after a Location header is set. ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=70273&edit=1

« previous php.bugs (#195259) next »