I have the following config on 0.7.26:
server {
…
location / {
error_page 404 = @cms;
}
location @cms {
fastcgi_pass 127.0.0.1:1234;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /www_root/index.php;
fastcgi_param SCRIPT_NAME /index.php;
}
location ~ .php$ {
fastcgi_pass 127.0.0.1:1234;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /www_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_intercept_errors on;
error_page 404 = @cms;
}
…
}
This should pass all requests to non-existent paths to /index.php so
“clean
URLs” will work and the CMS will display the corresponding pages. Indeed
it
works if I try to access a URI that is first handled by the “location /”
block,
such as http://my.com/2008/12/my-blog-post.
However, when I access a URI that is first handled by the “location ~
.php$”
block, such as http://my.com/non-existent.php, theoretically nginx will
first
pass this request to FastCGI, then PHP sends back 404 because it can’t
find the
non-existent.php file, then nginx should honor the error_page directive
and send
the request to @cms. In reality it results in a 502 Bad Gateway. The
error log
says “upstream sent invalid header while reading response header from
upstream”.
But if I used the following:
location ~ .php$ {
error_page 404 = /index.php;
}
Then it will work as intended.
Why can’t I use a named location for error_page if the location block
contains a
fastcgi_pass directive? (I assume this is the case for proxy_pass too,
but I
didn’t test that one.)