I'm using the Redirect
class to send non-logged-in users to the login page, with a 401 status code:
return Redirect::to('login', 401);
This sends the correct location header, but the status code is set to 302.
I've traced it all the way to the base Response
class in
laravel/vendor/Symfony/Component/HttpFoundation/Response.php
and it's calling:
$this->setStatusCode($status);
with the correct 401 code.
I also tried dumping the object:
var_dump( Redirect::to('login', 401)->foundation );
and I can see the protected statusCode
property is correctly set to 401.
Still, the generated response's HTTP status code is set to 302.
What gives? Am I using it wrong?
P.S. I also posted this on Laravel's forums, to no avail.
This is not because of laravel, you can reproduce this with just (php 5.4 in windows):
<?php
header("HTTP/1.1 401 Unauthorized");
header("Location: http://www.google.com");
It appears php sets it to 302:
$ php-cgi "test.php"
Status: 302 Moved Temporarily
Location: http://www.google.com
Content-type: text/html; charset=UTF-8
In PHP source code main/SAPI.C:
} else if (!STRCASECMP(header_line, "Location")) {
if ((SG(sapi_headers).http_response_code < 300 ||
SG(sapi_headers).http_response_code > 307) &&
SG(sapi_headers).http_response_code != 201) {
/* Return a Found Redirect if one is not already specified */
if (http_response_code) { /* user specified redirect code */
sapi_update_response_code(http_response_code TSRMLS_CC);
} else if (SG(request_info).proto_num > 1000 &&
SG(request_info).request_method &&
strcmp(SG(request_info).request_method, "HEAD") &&
strcmp(SG(request_info).request_method, "GET")) {
sapi_update_response_code(303 TSRMLS_CC);
} else {
sapi_update_response_code(302 TSRMLS_CC);
}
}
As you can see, when you do header()
with "Location"
, the http status code is modified to 302
You can make it work if you do it the other way around:
<?php
header("Location: http://www.google.com");
header("HTTP/1.1 401 Unauthorized");
This will give:
$ php-cgi "test.php"
Status: 401 Unauthorized
Location: http://www.google.com
Content-type: text/html; charset=UTF-8
But laravel sets the location after setting status, so the status is set back to 302 anyway. But this is a moot point, even if you successfully set status to 401 with a location header, the redirect is not followed by browsers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With