Ticket #948 (closed defect: fixed)

Opened 1 year ago

Last modified 2 months ago

PHP header('Status: 404') doesn't work outside a server.error-handler-404

Reported by: bobo@elbrigante.it Assigned to: jan
Priority: normal Milestone:
Component: mod_fastcgi Version: 1.4.13
Severity: major Keywords: php header status
Cc: Blocking:
Need Feedback: 0

Description

It's impossible to return a 404 status code from php scripts executed in normal mode (not server.error-handler-404). Other status code works, for example:

<?php
	header('Status: 301');
	
	print_r($_SERVER);
?>

this page does return the right HTTP/1.1 301 Moved Permanently header, but

<?php
	header('Status: 404');
	
	print_r($_SERVER);
?>

does return the HTTP/1.1 200 OK header.

Someone argued that I don't need to have PHP scripts return 404 status codes, but this is incorrect. If I remove one record from my database and a search engine spider tries to access the now outdated url pointing to that record, I need to be able to show a 404 error so it won't index that page, and eventually remove it from its index.

Attachments

Change History

12/29/2006 07:03:52 AM changed by darix

$ cat test.php ; curl -v http://localhost/~darix/test.php
<?php
  header("Status: 404");
  header("Content-Type: text/plain" );
  print("not found\n");
?>

* About to connect() to localhost port 80
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 80
> GET /~darix/test.php HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-unknown-linux) libcurl/7.15.5 OpenSSL/0.9.8a zlib/1.2.3 libidn/0.6.0
> Host: localhost
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< Transfer-Encoding: chunked
< X-Powered-By: PHP/5.2.0
< Content-Type: text/plain
< Date: Fri, 29 Dec 2006 07:01:58 GMT
< Server: lighttpd (1.4.x.svn.r1387/SuSE)
not found
* Connection #0 to host localhost left intact
* Closing connection #0

$  lighttpd -v
lighttpd-1.4.13 (ssl) - a light and fast webserver
Build-Date: Dec  2 2006 21:52:11

(follow-up: ↓ 3 ) 12/29/2006 09:05:12 AM changed by boom@bamex.ru

On PHP 5.2.0 all ok

< HTTP/1.1 404 Not Found < Transfer-Encoding: chunked < X-Powered-By: PHP/5.2.0 < Set-Cookie: PHPSESSID=10499b9e4e84616a12406f67e6ca5eaa; path=/ < Expires: Thu, 19 Nov 1981 08:52:00 GMT < Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 < Pragma: no-cache < Content-type: text/html; charset=utf-8 < Date: Fri, 29 Dec 2006 09:02:36 GMT < Server: lighttpd/1.5.0

Please write your version of PHP.

(in reply to: ↑ 2 ) 12/29/2006 10:23:12 AM changed by anonymous

Replying to boom@bamex.ru:

Please write your version of PHP.

I'm using PHP 5.2.0 on Mac OS X for my development

PHP 5.2.0 (cgi-fcgi) (built: Dec 16 2006 19:07:00)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2006 Zend Technologies

and PHP 5.2.0 with Zend Optimizer on Linux for deployment on the server

PHP 5.2.0 (cgi-fcgi) (built: Dec 17 2006 16:01:19)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2006 Zend Technologies
    with Zend Extension Manager v1.0.11, Copyright (c) 2003-2006, by Zend Technologies
    with Zend Optimizer v3.2.0, Copyright (c) 1998-2006, by Zend Technologies

with the code of the report I always get (on server and locally):

bobohome:~ bobo$ curl --head "http://www.pensieriparole.it/prova.php"
HTTP/1.1 200 OK
X-Powered-By: PHP/5.2.0
Content-type: text/html
Date: Fri, 29 Dec 2006 10:17:29 GMT
Server: lighttpd/1.4.13

12/29/2006 10:24:15 AM changed by bobo@elbrigante.it

Sorry, the preceding reply was mine.

03/04/2007 01:24:51 PM changed by bobo@elbrigante.it

Any news on this report? Will it be fixed? When?

In the meantime I'm using 410 instead of 404, this mitigates the problem since it is correctly returned as the http status code, but the user doesn't see anything, it always returns an empty page. So: 404 => page ok, status wrong 410 => page empty, status ok I now have php 5.2.1 but the problem persists.

You can try it on your own requesting http://www.pensieriparole.it/prova.php for 404 and http://www.pensieriparole.it/prova410.php for 410.

Please answer, thanks

03/04/2007 04:52:05 PM changed by darix

  • blocking changed.

try:

header('Status: 404 Not found')

are you sure this is an lighttpd problem and not a general problem of php?

03/04/2007 05:03:59 PM changed by bobo@elbrigante.it

I tried and the response is the same.

It's definitely a lighttpd problem, because my website was running on Apache before lighttpd, and there it was working as I wanted: status 404 returned and special error page.

Thanks

03/04/2007 07:17:53 PM changed by darix

$ cat test.php
<?php
        header('Status: 404 Not Found');
        header('Content-Type: text/plain');
        print("not found here\n");
?>
$ curl -kv https://localhost/test.php
> GET /test.php HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-unknown-linux) libcurl/7.15.5 OpenSSL/0.9.8a zlib/1.2.3 libidn/0.6.0
> Host: localhost
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Transfer-Encoding: chunked
< X-Powered-By: PHP/5.2.1
< Content-Type: text/plain
< Date: Sun, 04 Mar 2007 19:14:10 GMT
< Server: lighttpd (1.4.x.svn.r1524/SuSE)
not found here

i would say ... works for me ... or do you expect to see the 404 page from lighttpd?

03/04/2007 07:30:15 PM changed by bobo@elbrigante.it

I tried your code but I'm out of luck... No I don't want the 404 page from lighttpd, I expect the correct status code and my personal error page (in the website, here's only a test code).

$ cat prova.php 
<?php
        header('Status: 404 Not Found');
        header('Content-Type: text/plain');
        print("not found here\n");
?>
$ curl -kv http://www.pensieriparole.it/prova.php
* About to connect() to www.pensieriparole.it port 80
*   Trying 212.35.215.120... connected
* Connected to www.pensieriparole.it (212.35.215.120) port 80
> GET /prova.php HTTP/1.1
> User-Agent: curl/7.15.5 (i686-pc-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8d zlib/1.2.3 libidn/0.6.5
> Host: www.pensieriparole.it
> Accept: */*
> 
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< X-Powered-By: PHP/5.2.1
< Content-Type: text/plain
< Date: Sun, 04 Mar 2007 19:27:28 GMT
< Server: lighttpd/1.4.13
not found here
* Connection #0 to host www.pensieriparole.it left intact
* Closing connection #0

03/04/2007 07:35:09 PM changed by darix

can you please join #lighttpd on freenode?

05/03/2007 07:29:30 PM changed by bobo@elbrigante.it

I talked to darix in the irc channel and through some tests found out this: the issue arises only if you use the

server.error-handler-404 = "/error.php"

code in the configuration, which of course I use... I correctly handled the error.php page returning the 404 Not found status header (in fact if choosing a non existent real file the page correctly shows and the status code is 404).

The bug is still there with lighttpd 1.4.15.

Thanks again

05/03/2007 07:33:41 PM changed by darix

the longer version: index.php returns 404. lighty sends it to the 404 handler. and the 404 handler returns 404 again. than lighty converts it into a 200.

05/03/2007 07:51:21 PM changed by darix

 1427           } else if (con->in_error_handler) {
 1428             /* error-handler is a 404 */
 1429
 1430             con->http_status = con->error_handler_saved_status;
 1431           }
 1432         } else if (con->in_error_handler) {
 1433           /* error-handler is back and has generated content */
 1434           /* if Status: was set, take it otherwise use 200 */
 1435         }

as we see. the 2nd elseif doesnt restore the old code.

can you try:

Index: connections.c
===================================================================
--- connections.c       (revision 1820)
+++ connections.c       (working copy)
@@ -1432,6 +1432,7 @@
                                } else if (con->in_error_handler) {
                                        /* error-handler is back and has generated content */
                                        /* if Status: was set, take it otherwise use 200 */
+                                       con->http_status = con->error_handler_saved_status;
                                }

                                if (con->http_status == 0) con->http_status = 200;

05/03/2007 08:30:31 PM changed by bobo@elbrigante.it

YES it works! Thank you! I already patched the lighttpd on my production server, if I ever see something strange happen because of this I will notify to you. Hope to see the patch applied in the next release of lighttpd.

05/10/2007 03:24:43 PM changed by darix

  • status changed from new to closed.
  • resolution set to fixed.

fixed in all active branches.

07/18/2007 01:45:12 AM changed by glen

  • status changed from closed to reopened.
  • resolution deleted.
  • pending changed.

i believe this change broke possibility to return other than 404 status code from server.error-handler-404

at least in 1.4.13 it worked, and NEWS says:

1.3.16 - 2005-07-31
* error-handler-404 defaults to Status: 200 and static files work now

lighttpd conf:

server.error-handler-404 = "/404.php"

404.php:

<?

Header('Status: 200');

?>
it's mee
# curl -kv lighttpd/no_such_file
* About to connect() to lighttpd port 80 (#0)
*   Trying 192.168.2.27... connected
* Connected to lighttpd (192.168.2.27) port 80 (#0)
> GET /no_such_file HTTP/1.1
> User-Agent: curl/7.16.1 (x86_64-pld-linux-gnu) libcurl/7.16.1 OpenSSL/0.9.7l zlib/1.2.3 libidn/0.6.10 libssh2/0.11
> Host: lighttpd
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Transfer-Encoding: chunked
< Content-type: text/html
< Date: Wed, 18 Jul 2007 01:43:24 GMT
< Server: lighttpd
it's mee
* Connection #0 to host lighttpd left intact
* Closing connection #0
# curl -kv lighttpd/404.php
* About to connect() to lighttpd port 80 (#0)
*   Trying 192.168.2.27... connected
* Connected to lighttpd (192.168.2.27) port 80 (#0)
> GET /404.php HTTP/1.1
> User-Agent: curl/7.16.1 (x86_64-pld-linux-gnu) libcurl/7.16.1 OpenSSL/0.9.7l zlib/1.2.3 libidn/0.6.10 libssh2/0.11
> Host: lighttpd
> Accept: */*
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Content-type: text/html
< Date: Wed, 18 Jul 2007 01:43:46 GMT
< Server: lighttpd
it's mee
* Connection #0 to host lighttpd left intact
* Closing connection #0

07/18/2007 02:34:37 AM changed by darix

first of all you quoted 1.3.16 changelog. intended? furthermore... are you sure you 404 handler got called at all?

07/18/2007 09:41:14 AM changed by glen

yes, i quoted NEWS file where at 1.3.16 it noted that it's expected to return 200 code. so it must be a bug :)

and yes it got called. check the responses i pasted in previous note (http://lighttpd/no_such_file is inexistent file)

08/13/2007 02:22:57 PM changed by darix

hmm ... indeed that broke the old behavior.

can you send me your error.php again please?

08/14/2007 01:33:25 PM changed by darix

can you please test svn r1904 of the 1.4.x branch?

I checked in a fix that now passes the 404-handler testsuite and fixes both #1270 and #948 . See this link how to get the svn branch.

08/17/2007 07:42:36 AM changed by glen

  • status changed from reopened to closed.
  • resolution set to fixed.

seems ok now (i can use 200 status code in 404 handler)

# wget -O /dev/null -S --cache=off http://lighttpd/no_such_file 2>&1|grep HTTP/
  HTTP/1.0 200 OK
# wget -O /dev/null -S --cache=off http://lighttpd/404.php 2>&1|grep HTTP/
  HTTP/1.0 200 OK
# cat /www/htdocs/localhost/404.php
<?

Header('Status: 200');

?>
it's mee

Add/Change #948 (PHP header('Status: 404') doesn't work outside a server.error-handler-404)




Change Properties
Action