Status codes set in callback don't persist if EE serves a template
Closed this issue · 3 comments
I'm doing some 404/410 routing on a site, and I'm running into cases where the status codes I set in the callback aren't actually delivered to the browser if EE's template system gets involved:
Works (browser sees 404):
$router->setHttpStatus(410);
return "404: nothing here";
Doesn't work (browser sees 200):
$router->setHttpStatus(410);
$router->setTemplate('pages/410');
Doesn't work (redirect is successful, but browser sees 200):
$router->redirect('pages/410', 410);
Interestingly, this issue arises whether the template in question actually exists or not: The browser sees a 200 OK instead of a 404 Not Found.
(EE 2.7.2, Resource Router 1.0.2, PHP 5.3.27)
Just pushed a fix to the develop branch, can you test that out and let me know if it works?
Regarding the redirect w/ 410: I don't think that it's possible. I believe the web server will automatically send a 302 if you attempt to set a Location: header without a 3XX status code. The fix in develop should make it so it's not a 200 OK.
Yes, your fix does seem to solve the status code issue! (Although, will turning off send_headers altogether prevent EE from sending other useful headers? A cursory glance through the core seems to suggest that EE always sends a Content-Type, but all other headers get shut down. The usefulness of those other headers is questionable, I guess.)
And you're right, a redirect has to be a 3XX, and the server will default to a 302 if you give it something out-of-bounds.
It's definitely a bit hacky, but it's the only way to prevent the Output class from sending its own 200 status.
The good thing, as you say, is that it still sends its Content-Type headers regardless of the send_headers setting. You lose a few default headers:
- "Expires: Mon, 26 Jul 1997 05:00:00 GMT"
- "Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"
- "Pragma: no-cache"
Furthermore I believe it will break {stylesheet=foo} tags. And if your template type is set to RSS, you will lose some Last-Modified/Expires headers, too.
Those are the only implications I found in my research. I think if you are changing status codes via setHttpStatus, these implications are a-ok. For most users, they'll never need to set a custom status on a template AND retain the core EE headers.
Keep in mind that config->set_item only changes the send_headers value for that particular http request, it doesn't actually change your send_headers value in your config db/file. On the next page load send_headers will be back to its original value.