Project

General

Profile

Actions

Bug #948

closed

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

Added by Anonymous about 17 years ago. Updated about 16 years ago.

Status:
Fixed
Priority:
Normal
Category:
mod_fastcgi
Target version:
-
ASK QUESTIONS IN Forums:

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.[BR]

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.

-- bobo

Actions #1

Updated by darix about 17 years ago


$ 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
Actions #2

Updated by Anonymous about 17 years ago

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.

-- boom

Actions #3

Updated by Anonymous about 17 years ago

Replying to :

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
Actions #4

Updated by Anonymous about 17 years ago

Sorry, the preceding reply was mine.

-- bobo

Actions #5

Updated by Anonymous about 17 years ago

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

-- bobo

Actions #6

Updated by darix about 17 years ago

try:

header('Status: 404 Not found')

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

Actions #7

Updated by Anonymous about 17 years ago

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

-- bobo

Actions #8

Updated by darix about 17 years ago


$ 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?

Actions #9

Updated by Anonymous about 17 years ago

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

-- bobo

Actions #10

Updated by darix about 17 years ago

can you please join #lighttpd on freenode?

Actions #11

Updated by Anonymous almost 17 years ago

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

-- bobo

Actions #12

Updated by darix almost 17 years ago

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.

Actions #13

Updated by darix almost 17 years ago


 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;
Actions #14

Updated by Anonymous almost 17 years ago

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.

-- bobo

Actions #15

Updated by darix almost 17 years ago

  • Status changed from New to Fixed
  • Resolution set to fixed

fixed in all active branches.

Actions #16

Updated by glen over 16 years ago

  • Status changed from Fixed to Need Feedback
  • Resolution deleted (fixed)

i believe this change broke possibility to return other than 404 status code from {{{server.error-handler-404}}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

Actions #17

Updated by darix over 16 years ago

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

Actions #18

Updated by glen over 16 years ago

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)

Actions #19

Updated by darix over 16 years ago

hmm ... indeed that broke the old behavior.

can you send me your error.php again please?

Actions #20

Updated by darix over 16 years ago

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.

Actions #21

Updated by glen over 16 years ago

  • Status changed from Need Feedback to Fixed
  • 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
Actions

Also available in: Atom