Bug #70273 [Nab]: header(): Setting the Location header will set a status code of 202 to 302.
| From: | jeff at nd4c dot com | Date: | Thu, 20 Aug 2015 15:14:09 +0000 |
| Subject: | Bug #70273 [Nab]: 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-195374@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: Not a bug
Type: Bug
Package: HTTP related
Operating System: Any
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
@ab
As far as the "generic use case serving HTTP redirect", I'm not fully convinced that
setting the Location header signifies a generic use case redirect. It's very clear in the
documentation (expressed in previous posts) that the Location header is used for many distinct cases
that do not involve a redirect. Being that 302 is the most likely I admit that it's close to a
generic use case, so I guess it's just my dislike for micro-management. Surprising since I am
a programmer.
However, in the interests of BC and because there is a sufficiently simple workaround, I would agree
that this is best left alone.
Sorry, for the bother. I will now have to concentrate on a framework 'bug-fix' to make
sure the workaround is available and that there are no incorrect assumptions on how the header()
function handles Location headers.
Previous Comments:
------------------------------------------------------------------------
[2015-08-20 13:54:08] ab@php.net
@jeff, thanks for the follow up.
It's hard to see how the PHP implementation doesn't comply with the HTTP spec. The PHP
implementation is focused on the generic use case serving HTTP redirect. At the same time
- it doesn't prevent using any other status
- changing it to set no HTTP status is an incommensurable BC break to the gain it would bring for
the async operations in REST
Thanks.
------------------------------------------------------------------------
[2015-08-19 15:21:37] jeff at nd4c dot com
@ab
I fully agree with your arguments, but not with your deduction.
The reference to:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3
Does not state anywhere that a Location header MUST NOT be used. It also states, as requinix
pointed out, that it SHOULD have some indication of its current status and a pointer (Location?) to
a status monitor.
http://tools.ietf.org/html/rfc7231#section-7.1.2
This description of the Location header does not even insinuate that only a 302 status code must be
used. It clearly indicates that the Location header is used for several different status codes.
There is also nothing to suggest that, as you said, "some status should be set" - it does
not say that anywhere!
Your statement, "there is no single definition about status 202" is mute. This is about
the Location header and any status code. The 202 was only used a valid and current example of
usage.
Your statement, "the status can be overridden in PHP implementation, which gives the full
freedom to set it to whatever a programmer wants" is flawed. It would be more accurate if
written: "the status HAS TO BE overridden in PHP implementation, which REMOVES the full freedom
to set it to whatever a programmer wants"
The PHP implementation is definitely NOT a generic one. It is dedicated to forcing a 302 status
code for a Location header, contradicting all current RFC and similar documentation. A generic one
would simply let the programmer decide.
https://en.wikipedia.org/wiki/Software_bug
Wikipedia states: "A software bug is an error, flaw, failure, or fault in a computer program or
system that causes it to produce an incorrect or unexpected result, or to behave in unintended
ways."
The current implementation of the header() function produces an incorrect and unexpected result when
a Location header is set. It's definitely a bug.
------------------------------------------------------------------------
[2015-08-19 15:04:16] jeff at nd4c dot com
@cmb
7.1.2. Location
The "Location" header field is used in some responses to refer to a
specific resource in relation to the response. The type of
relationship is defined by the combination of request method and
status code semantics.
Neither is there mention of 302. The references to 201 and 3xx are explaining how the Location
header would typically be used IF the 201 and 3xx status codes are used.
Also, to be clear, 3xx does NOT mean 302 specifically. So why force the status code to 302? Where
does it say that?
I repeat:
I have not found any documentation, RFC or the like to infer that whenever a Location header is set
it MUST have a status of 302. I have not found anything to suggest that whenever a Location header
is set it SHOULD have a status of 302. It definitely COULD, but it COULD also have ANY OTHER status
code. There is no documentation to state otherwise. It's true that a status code of 302 SHOULD
(or even MUST) have a Location header, but that does not logically infer the reverse.
So why does the PHP header function force a 302 as a 'magic' side-effect?
------------------------------------------------------------------------
[2015-08-19 10:34:57] ab@php.net
@jeff,
http://www.ietf.org/rfc/rfc2119.txt
"3. SHOULD This word, or the adjective "RECOMMENDED", mean that there
may exist valid reasons in particular circumstances to ignore a
particular item, but the full implications must be understood and
carefully weighed before choosing a different course."
Taking in account also the to paragraphs quoted by @cmb and @requinix
- some status should be set, in the PHP implementation it's set 302 by default. In PHP
implementation the "particular item" is not ignored
- there is no single definition about status 202 and Location header combination
- the status can be overridden in PHP implementation, which gives the full freedom to set it to
whatever a programmer wants
Further - the REST specification has chosen to set the status 202+Location under some circumstances.
That is perfectly valid with the HTTP specification too, because the Location header is not bound to
any specific status.
However where your position is not valid - the PHP implementation is a generic one, it is not
dedicated specifically to REST, AJAX, anything else. But, the PHP implementation makes possible to
implement whatever a programmer needs. It were valid if you were filing a ticket about a REST
specific implementation, maybe. Or if there were no possibility to override the status. Given this
and also with the regard to the backward compatibility it doesn't look like a bug. There are
many REST frameworks which could be probably more of use for you, if you don't want to
implement it yourself.
Thanks.
------------------------------------------------------------------------
[2015-08-18 16:07:00] jeff at nd4c dot com
It's definitely a bug. Whether it will be fixed or not is another question.
1. https://bugs.php.net/bug.php?id=25044 was
fixed, but IMO not correctly. The proper fix would have been to remove the 'magic'
side-effect of setting a Location header.
Quote from bug report 25044:
It may even be appropriate to not change the status for any value other than 200 (the default). As
a result, if a user explicitly sets the status to something other than 200, then setting the
Location header should not change that value again (even if the combination of the status and header
do not make sense). The reasoning here is that HTTP status codes are extensible, meaning that new
specifications can add new status codes that may use the Location header. If only testing for the
above list, new codes would be overlooked and therefore automatically changed.
2. https://bugs.php.net/bug.php?id=51749 turned
into a flame war with the developers - obviously it was rejected as not a bug. ;-) The developer
stated the following:
[2010-05-18 09:47 UTC] mike@php.net
...
You are writing *pages* about code that's *years* old and worked that way for a long long time,
and there's very little chance to become that changed. You know, PHP is an acronym for BC, or
was it the other way round...
I find that a little disheartening. I'm guessing that quote's been pasted up in many
closed source companies' boardrooms! ;-)
I have not found any documentation, RFC or the like to infer that whenever a Location header is set
it MUST have a status of 302. I have not found anything to suggest that whenever a Location header
is set it SHOULD have a status of 302. It definitely COULD, but it COULD also have ANY OTHER status
code. There is no documentation to state otherwise. It's true that a status code of 302 SHOULD
(or even MUST) have a Location header, but that does not logically infer the reverse.
So why does the PHP header function force a 302 as a 'magic' side-effect?
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=70273
--
Edit this bug report at https://bugs.php.net/bug.php?id=70273&edit=1