ZF-5633: Wrong response code when header location is used

Description

When setting location header, and when this header is not the first, the responseCode is ignore because header ($header['name'], . ': ' . $header['value'], $header['replace']) modify the response code if $header['name'] == 'location'

Comments

I guess this is because for php, the location header is a special case:

{quote} 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 some 3xx status code has already been set. www.php.net/manual/en/function.header.php" rel="nofollow">PHP: header - Manual {quote}

Currently: The responseCode that Zend_Controller_Response sets will depend on whether or not the location header is the first header that Zend comes across. If the location header was the first header that was set, _httpResponseCode if set will override the location header. If the location header is not the first header that was set, php's standard behavior will be followed (overriding _httpResponseCode if it was anything other than 201 or 3xx).

I don't think what Symetrix thought was a problem should be a problem but I think there is another potential problem: A user sets a responseCode, then later sets the location header (this is the only header that the user sets). The user's location header will essentially be overruled by the prior set responseCode:


$response = new Zend_Controller_Response_Http();
$response->setHttpResponseCode(200);
$response->setHeader('location', 'http://www.php.net');
$response->sendHeaders();
//result = HTTP/1.1 200 OK

$response = new Zend_Controller_Response_Http();
$response->setHttpResponseCode(200);
$response->setHeader('X-test', 'test');
$response->setHeader('location', 'http://www.php.net');
$response->sendHeaders();
//result = HTTP/1.1 302 Found

Either the httpResponseCode should be the code that is always sent back or we should let location override the response code regardless of whether it was the first or second set header.

Calling setHeader('Location', '...') will not set the response code (unless, of course, PHP does when it detects the Location header). If you call setRedirect(), however, you have the option of providing a response code -- and in that case, it will set the response code.

There are reasons for this. For instance, with REST, when a new item is POST'd, you should specify a "201: Created" header, but also include a "Location" header pointing to the URI for the newly created resource. If setHeader('Location', ...') actually set the response code automatically, this would be problematic

How i can fix this problem? WebDav-classes do not work with this problem.