Still necessary to use 'Status: 404 Not Found' for FCGI? - php

Usually, when sending a http status header from PHP, one would send the HTTP header like this:
header("HTTP/1.0 404 Not Found");
However, the PHP manual says that for FCGI hosts, one would need to send a "Status" header that is then converted into a HTTP header by the FCGI module:
header("Status: 404 Not Found");
I am running apache 2.2 with PHP using mod_fcgi on a Windows 7 machine and sending the header using just header("HTTP/1.0 404 Not Found"); seems to work fine.
Is this something that has changed recently? Do I still need to send a Status header for FCGI hosts? Could anyone also confirm this for other platforms (solaris, linux) and other webservers (nginx, lighttp)?

I don't believe you need to use the 'Status' style header unless you have the option cgi.rfc2616_headers enabled.
The description of that option is http://php.net/manual/en/ini.core.php
"Tells PHP what type of headers to use when sending HTTP response
code. If it's set 0, PHP sends a Status: header that is supported by
Apache and other web servers. When this option is set to 1, PHP will
send ยป RFC 2616 compliant headers. Leave it set to 0 unless you know
what you're doing."
Basically you're sending HTTP style headers to PHP and then PHP converts these to the 'Status' style headers where necessary. It seems there were various bugs over the years where either these were either converted incorrectly or multiple 'Status' headers were sent at once - however all those bugs seem to be fixed now. So I think you're safe just setting the HTTP style headers and letting PHP convert them.
Also I just tested and sending the header("HTTP/1.0 404 Not Found"); works fine on my dev environment using FastCGI

Related

Sending correct HTTP 404 header using PHP [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
404 header - HTTP 1.0 or 1.1?
I have a simple PHP code which send 404 using the header
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
echo $_SERVER["SERVER_PROTOCOL"];
But when using the curl command and force 1.0, it return..
curl -0 -v 'http://www.example.com/test.php'
> GET /test.php HTTP/1.0
< HTTP/1.1 404 Not Found
< Server: nginx
< Date: Sat, 27 Oct 2012 08:51:27 GMT
< Content-Type: text/html
< Connection: close
<
* Closing connection #0
HTTP/1.0
As you can see $_SERVER["SERVER_PROTOCOL"] is 1.0 but header give me 1.1, what is the reason?
Great question.
You have to understand that this is not something specific to PHP so don't think there is a bug or something. It's specific to:
A web server's configuration
A client's (think browser) configuration
Usually clients, when sending a request to a web server, indicate which protocol they support. The web server then responds with the protocol it supports or it is configured to.
In your PHP code, when you flush that 404 header you are hinting to the server which protocol to use. You can't force it - at least I am not aware of a way to force it from PHP. The web server will ultimately settle for the highest protocol supported by both itself and the requesting client.
Unless the client forces it to, nginx will always respond over HTTP/1.1. I am not aware of a method of configuring it like Apache for example. But that is the reason for the behavior you are seeing.
Maybe you should edit your question, or open a new question, to be more specific to nginx since, like I explained this is not a problem with PHP. That way more people might be able to find the question and help out.
If you're using FastCGI (which you probably are) between nginx and PHP, you should instead use
header("Status: 404 Not Found");
as advised by PHP's documentation for header.

Setting custom HTTP response headers in LiteSpeed with PHP

I'm trying to set a custom HTTP 1.0 status code in order to return more descriptive error messages via AJAX (using jQuery).
In PHP I have something like:
header( 'HTTP/1.0 909 Hello World' );
exit;
This works as expected on my development environment using Apache 2.2.15 but it does not work on the production webserver running LiteSpeed 5.5. LiteSpeed instead returns a 200 OK.
Using this:
header( 'HTTP/1.0 404 Hello World' );
exit;
Apache returns the 404 with the text above. LiteSpeed replaces the custom text with the default 'Not Found'.
Any idea how to override this feature in LiteSpeed to make it work the same way as Apache? I understand they are supposed to be comparable webservers.
Any ideas, please do let me know.
-P.
First, why HTTP 1.0 and not 1.1?
Second, you're trying to do things that aren't defined in the HTTP spec. LiteSpeed probably checks the headers its being asked to send and replaces values it doesn't recognise with some default value.
You shouldn't be trying to force HTTP to behave in a non-standard way, as soon as you do, it ceases to be HTTP. The specifications are there to make sure that software implemented at different times by different people can interoperate, and how it should behave if you don't follow the spec is completely undefined.
Apache letting a header it doesn't know through is perfectly acceptable behaviour, and so is LiteSpeed's behaviour of refusing to let it through. Making demons fly out of your nose would also be a valid thing for the server to do in this case. And what is the client meant to do with an HTTP response code it doesn't recognise?
If you need to send additional information in the header, why not add a new header? The following should do.
header ('X-My-App-Header: Hello World!');

How to disable the Content-Length response header with Apache?

Let me preface this question by stating that I only want to temporarily disable the header and am fully aware of the implications to browsers, cache mechanisms, etc if the header is not present.
I have need to test some caching behavior when the Content-Length header is not present in an HTTP response. Is there a way to disable the header?
My first attempt was to simply try to set it to 0 using PHP and header("Content-Length: 0", true); but this is not the same as completely removing the header from the response.
Is it possible to disable/remove the header?
Adding Content-Length is something marked in RFC 2616 (HTTP 1.1) as SHOULD. That means web servers generally are designed not to leave it out.
For instance with Apache HTTP Server you have to modify modules/http/http_filters.c. Searching for Content-Length from the source file practically shows you how to unset it forcibly (take a closer look at around line 1255). Just add the unset to the end of the filter chain and you're set.
Your other alternative is to use an other web server besides Apache that is either easier to modify or doesn't respect RFC 2616 as well.

Difference in sending HTTP status codes from php

what is the difference from setting the responce status in php
header("HTTP/1.0 404 Not Found");
and
header("Status: 404 Not Found");
What is the difference from the client point of view (aka browser or a client implementation for RESTful WS). I understood that the second one has to do something with CGI.
HTTP/1.0 404 Not Found is the HTTP response code, it's what allows clients to determine whether a request succeeded or not.
Status: 404 Not Found just sets an extra header field called Status with the value of 404 Not Found. It has no intrinsic meaning, it's like setting header('Foo: Bar'). It may mean something to somebody, but it's not officially specified what it should mean. The HTTP response code will be a normal 200 OK.
There seems to be a special case when running PHP through FastCGI. Apparently you can't set the HTTP/ status directly when invoking PHP with this method. Instead you have to set this unofficial header, which will be converted to a real HTTP/ code before it's send back to the client (apparently a limitation of how PHP can talk to the web server when invoked via CGI). In all other cases, it'll just be send as-is (with no meaning) and the real HTTP response code will be 200 OK.
That's what I could gather from the description in the manual at least, I've never had to use this. Also, you're insane if you run PHP through CGI, so hopefully nobody needs this in this day and age. ;o)

PHP 404 error page won't display content

I'm having a problem implementing custom 404 error pages on my Windows/IIS/PHP webhost. Whenever I try to send the 404 status message in the header, no content is sent to the client and a blank page is displayed instead.
Here is a very simple script I'm using:
<?php
header('HTTP/1.1 404 Not Found');
header('Status: 404 Not Found');
var_dump(headers_list());
?>
On my dev machine the output (displayed in a browser) is
array(2) { [0]=> string(23) "X-Powered-By: PHP/5.2.6" [1]=> string(21) "Status: 404 Not Found" }
On my host there is no output. I can't seem to generate anything but a blank page regardless of what content is echoed by PHP, or included below as normal HTML, though PHP processing e.g. logging, database writes etc continue as normal.
Can anyone suggest what the problem might be or how to resolve it?
'blank page' smells like error_reporting(0) hiding the error messages you would get. Maybe there is some output before your headers and that raises an error. Check that.
If PHP is configured at your host to run through CGI, it may be impossible to generate 404 error pages in IIS (except by lying and returning 200 OK, which is a Bad Thing). Certainly I've been unable to persuade IIS 4-6.0 to allow my CGI 404 errors through to browsers.
You generally don't want PHP to run CGI anyway, there are other related problems as well as it being slow. On IIS, the PHP ISAPI extension should be preferred (though as I've not tried it I can't confirm it solves this specific problem).
What if you put text after the PHP tags?
Also, make sure your script isn't erroring out on your host, whether checking apache error logs, running php -l on your script or turning error_reporting on and display_errors on.
I have the same problem with PHP 5.2.6 on Linux. I find that the first 8109 bytes are not printed by the web server.
IE6 ignores custom error pages < 512 bytes in length. This could be an explanation for this problem, but probably you have tested in more than one browser anyway.
Check that your host allows you to change headers on the fly with PHP. My host doesn't allow me to set the 404 header through PHP, though other headers (301, content-type) are fine.
My advice is to not set the HTTP/1.1 404 header yourself and let the web server do it for you.
Traditionally, this is done through the Status header, which the web server should take and turn into an HTTP/1.0 or 1.1 404 Not Found header.
(Side Note: The Status header is not a real HTTP header and is used solely to communicate information from an app to the server itself.)

Categories