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

From: Date: Tue, 18 Aug 2015 16:07:02 +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-195298@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:

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?


Previous Comments:
------------------------------------------------------------------------
[2015-08-18 12:10:44] cmb@php.net

According to bug #51749 this ticket is not a bug either (or maybe
"won't fix").

------------------------------------------------------------------------
[2015-08-17 16:35:01] jeff at nd4c dot com

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.

------------------------------------------------------------------------
[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>

------------------------------------------------------------------------


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


Thread (12 messages)

« previous php.bugs (#195298) next »