This is somewhat a re-issue (hope this won't sound annoying) as I found this problem already treated in some of his aspects here:
http://drupal.org/node/81752
http://drupal.org/node/64645
http://drupal.org/node/117756
http://drupal.org/node/6678
Going straight to the point, the root problem is that if PHP is using the CGI/FastCGI server API to interface itself with the web server, the HTTP status header will not be correctly set. This is due to the CGI specification which does not allow directly setting the HTTP status code
(see http://cgi-spec.golux.com/draft-coar-cgi-v11-03.txt, section 7.2.1.3).
This fact leds to multiple problems on a CGI-based system:
- [SEO] 404 pages, 403 pages and 503 pages have 200 OK status (bad, multiple URLs with the same content)
- [user] 401 pages do not cause the browser to show up the authentication dialog
- [user] 304 pages display nothing (I think this is the cause of many of the Blank pages - The White Screen of Death)
And so on...
Someone was pointing out this is not a Drupal bug but a PHP one, and that using CGI sapi is a poor choice under the performance aspect. I agree, but not always we can choose our system. I think the more Drupal is adaptable to system configurations the better is.
By the way, one of the most popular hosting solutions provider in Italy is using this configuration and I do not think I am the only one that has experienced this kind of problems.
I am providing a patch with my solution but I am pretty new to Drupal and I am sure that a real D-guy can find one better ;)
Comment | File | Size | Author |
---|---|---|---|
#17 | cgi-headers-175855-D7.patch | 906 bytes | Dave Reid |
#15 | http_header_175855_15.patch | 4.7 KB | Pancho |
#14 | http_header_175855_14.patch | 4.65 KB | Pancho |
#13 | 175855-head_1.patch | 7.59 KB | plach |
#10 | 175855-head_0.patch | 7.59 KB | plach |
Comments
Comment #1
plachSorry, I have just read the priority guidelines...
Comment #2
moshe weitzman CreditAttribution: moshe weitzman commentedLooks good.
Seems like you should use drupal_set_header within the new drupal_http_status().
Comment #3
plachthis is exactly the kind of good advice I needed, thank you :)
here's the revised patch
Comment #4
plachthe revised patch
Comment #5
moshe weitzman CreditAttribution: moshe weitzman commentedComment #6
drummI would like to see this API change get into Drupal 6.x before consideration in 5.x.
Comment #7
Gábor Hojtsy- Please do the diff with
diff -up
, so we see where the changes take effect.- Please observe coding standards about concatenation, eg. look inside drupal_http_status(), things shuld be like
.' '.
without the spaces)- Also look at phpdoc formatting conventions and use that: one line function summary at the start, @param broken to multiple lines
- Your second drupal_http_status() call seems to be badly indented
Apart from these, the code generally looks good, and reminds me of the approach we took on php.net, when I was active in the webmaster team.
Comment #8
plachI had to move the new
drupal_http_status()
function intobootstrap.inc
in order to make 304 and 403 calls to work: in those cases the function (as the old code) uses the nativeheader()
function. I tested the patched code on both PHP Server APIs and it seems to work correctly. The tests were conducted on a plain 5.2 installation and on a plain HEAD installation.@drumm: I am attaching a 6.x version of the patch.
@Gábor Hojtsy: I am using TortoiseCVS to make the patches and it actually uses
diff -u
. I corrected the source following your advices, I think it is ok now.Comment #9
plachhere is the 5.2 version
Comment #10
plachand here is the
diff -up
versionComment #11
plachAny feedback out there?
Comment #12
plachAgain, anyone available to review the code?
Comment #13
plachthis an updated patch against the HEAD
Comment #14
PanchoStill to be considered for D6.
Patch was broken by centralizing _db_error_page() to database.inc.
Rerolled the patch against HEAD. Didn't test it on CGI/Fast-CGI though.
Comment #15
PanchoSlightly modified patch:
Comment #16
Dave ReidThis hasn't been bumped in a while, and after my attempt to get this fixed in #81752: Incorrect headers when using PHP as CGI, this would probably best be fixed by modifing the $_SERVER['SERVER_PROTOCOL'] variable to "Status:" within drupal_initialize_variables.
Comment #17
Dave ReidHere's a patch that doesn't require a new function and only makes the change in the drupal_initialize_varibables function.
Comment #18
Anonymous (not verified) CreditAttribution: Anonymous commented@Dave Reid: Is this patch for D7 as it indicates in the file name? If so, please change the version to indicate that.
Comment #19
Dave ReidThanks earnie, I overlooked that.
Comment #21
Dave ReidFailed due to #74645: modify file_scan_directory to include a regex for the nomask.. Setting back to code needs review.
Comment #22
c960657 CreditAttribution: c960657 commentedIsn't this fixed by adjusting cgi.rfc2616_headers? As you can see in the PHP source code, PHP already translates the status code into a Status: header (the linked source is that of PHP 5.2.0 - it has been updated several times since then).
If adjusting cgi.rfc2616_headers does not fix the problem, what is the PHP bug number? There are a number of bugs that sound like this that have already been fixed in recent PHP versions.
Comment #23
catchWe need a comment here to the PHP bug number so we can remove the workaround later on when it's fixed (if it hasn't been already).
Comment #24
toomanypets CreditAttribution: toomanypets commentedI just spent far too many hours tracking this problem down with D6.1 in a CGI/FastCGI environment. In this case users were getting 500's instead of 404's. I do not believe this is a PHP bug. While setting cgi.rfc2616_headers to 0 in php.ini resolves the problem, this workaround is impractical for many who do not have access to php.ini, or who can't override php.ini settings in an .htaccess file. Additionally, it seems to me that making the headers non-compliant is (a) counter-intuitive and (b) may break other applications.
Until a permanent fix is available, I hacked the /includes/common.inc file as suggested in many other posts, but this only addresses 404 problems:
Comment #25
kenorb CreditAttribution: kenorb commentedSimilar problem.
The same website with the same code, but different responses:
Tested with PHP 5.2.8, 5.2.9 and latest CVS snapshot
There is something wrong with headers when using php-cgi
I even can't log in.
Tested on Drupal 6.11
Fix in #24 fixed only Page Not Found, but there are some problem with redirection as well.
Voting for patch #24 to be in the core.
Comment #26
kenorb CreditAttribution: kenorb commentedIt's related to following PHP bugs, none of them have proper solution:
http://bugs.php.net/bug.php?id=20943
http://bugs.php.net/bug.php?id=3884
http://bugs.php.net/bug.php?id=11375
http://bugs.php.net/bug.php?id=20416
http://bugs.php.net/bug.php?id=41661
Proper link to: RFC3875
http://www.ietf.org/rfc/rfc3875
See section:
6.3.3. Status
Comment #27
kenorb CreditAttribution: kenorb commentedhttp://bugs.php.net/bug.php?id=40472
Comment #28
Damien Tournoud CreditAttribution: Damien Tournoud commentedThis is a configuration issue. When using PHP in CGI/FastCGI mode with CGI/1.1 compliant servers (Apache, Lighttpd, etc.) you *have* to set cgi.rfc2616-headers = 0 (which is the default).
The PHP manual has a wise word of caution: