Can fastcgi_index be used with multiple filenames?

Switching over to fastcgi php…

We use parse both .php and .shtml as php files. From looking at the
syntax for fastcgi_index it looks like just one filename can follow it,
e.g.:

fastcgi_index index.shtml;

but can it be

fastcgi_index index.shtml index.php;

On Sat, Mar 08, 2008 at 02:28:52AM -0500, Ian M. Evans wrote:

fastcgi_index index.shtml index.php;
No.

The problem is that if fastcgi is on remote server, nginx does not what
index file should be choosed for “…/”. See $fastcgi_script_name
variable
http://wiki.codemongers.com/NginxHttpFcgiModule#var_fastcgi_script_name

If php root and static root are the same, then you can use following:

location / {
    index   index.shtml   index.php;
    # static
}

location \.(php|shtml)$ {
    fastcgi_pass  ...
    # fastcgi_index is not needed here at all
}

When nginx finds index.shtml or index.php in “location /”, it does
internal redirect and request will be processed in “location
.(php|shtml)$”.

Hi,

On Sam 08.03.2008 05:01, Ian M. Evans wrote:

I guess I should never do config changes at 4:42 AM! Luckily, I can
just “cp oldconfig nginx.conf” and -HUP and the site’s back and
running while I tweak some more.

Currently anything that’s not a static file gets passed to an Apache
backend and run as a PHP file.

So index.php, index.shtml and even extensionless files are PHP
files. For example, /galleries/123/1 is a php file called galleries
that works with the /123/1 path info.

Maybe this help you, what I have seen yesterday was:

index index.php;

and a request like ‘GET / …’ have not called index.php, after I have
changed to

index /index.php;

everything was fine.

Cheers

Aleks

On Sat, Mar 08, 2008 at 11:24:08AM +0100, Aleksandar L. wrote:

   fastcgi_pass  ...

So index.php, index.shtml and even extensionless files are PHP
index /index.php;

everything was fine.

No, “index /index.php” means that all /'s will be handled by
single root /index.php. The absolute index may be used as last resort:

  index  index.php  /index.php;

Igor S. wrote:

}

I guess I should never do config changes at 4:42 AM! Luckily, I can just
“cp oldconfig nginx.conf” and -HUP and the site’s back and running while
I tweak some more.

Currently anything that’s not a static file gets passed to an Apache
backend and run as a PHP file.

So index.php, index.shtml and even extensionless files are PHP files.
For example, /galleries/123/1 is a php file called galleries that works
with the /123/1 path info.

I’m moving to fastcgi so I can drop Apache. Right now my test config
file for fastcgi is doing fine serving the extensionless PHP files but
giving me "No input file specified on the .php and .shtml files. I added
your suggestions above but I must have broken something somewhere else.
Here’s a snippet of my fastcgi config test:

server {
listen 80;
root /usr/local/apache/htdocs;
server_name www.example.com;
index index.shtml index.php;
error_page 404 /dhe404.shtml;

location /stub_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}

location / {
root /usr/local/apache/htdocs;
index index.shtml index.php;
include /usr/local/nginx/conf/fastcgi.conf;
fastcgi_pass 127.0.0.1:10004;
}

location .(php|shtml)$ {
include /usr/local/nginx/conf/fastcgi.conf;
fastcgi_pass 127.0.0.1:10004;
}

location ~*
^.+.(jpg|jpeg|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|mov)$
{
root /usr/local/apache/htdocs;
error_page 403 /dhe403.shtml;
valid_referers none blocked *.example.com example.com ;
if ($invalid_referer) {
return 403;
}
}

location ~* ^.+.(gif|js)$ {
root /usr/local/apache/htdocs;
}
}

The included fastcgi.conf contains:
#fastcgi.conf
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param PATH_INFO $fastcgi_script_name;

PHP only, required if PHP was built with --enable-force-cgi-redirect

fastcgi_param REDIRECT_STATUS 200;

As I said, the extensionless files are being run through fastcgi just
fine, so I’m assuming I just put something in the wrong order.

Thanks!

On Sat, Mar 08, 2008 at 05:01:58AM -0500, Ian M. Evans wrote:

   # fastcgi_index is not needed here at all

For example, /galleries/123/1 is a php file called galleries that works
with the /123/1 path info.

I’m moving to fastcgi so I can drop Apache. Right now my test config
file for fastcgi is doing fine serving the extensionless PHP files but
giving me "No input file specified on the .php and .shtml files. I added
your suggestions above but I must have broken something somewhere else.
Here’s a snippet of my fastcgi config test:

Probably, you need

  • location .(php|shtml)$ {
  • location ~ .(php|shtml)$ {

but the .php and .shtml files should be anyway handled by “location /”.

allow 127.0.0.1;
location .(php|shtml)$ {
if ($invalid_referer) {
#fastcgi.conf
fastcgi_param DOCUMENT_ROOT $document_root;
As I said, the extensionless files are being run through fastcgi just
fine, so I’m assuming I just put something in the wrong order.

It’s surprise for me that PHP sees

SCRIPT_FILENAME /usr/local/apache/htdocs/galleries/123/1
SCRIPT_NAME /galleries/123/1
PATH_INFO /galleries/123/1

and understands that it needs to look script in /galleries, but not
in /galleries/123/1.

Igor S. wrote:

It’s surprise for me that PHP sees

SCRIPT_FILENAME /usr/local/apache/htdocs/galleries/123/1
SCRIPT_NAME /galleries/123/1
PATH_INFO /galleries/123/1

and understands that it needs to look script in /galleries, but not
in /galleries/123/1.

My PATH_INFO is just the text after the script. Here’s a grab from
phpinfo():

REQUEST_URI /test.php/123/1

SCRIPT_FILENAME /usr/local/apache/htdocs/test.php
SCRIPT_NAME /test.php
PATH_INFO /123/1

That’s how it’s always been for me.

On Sat, Mar 08, 2008 at 04:18:29PM -0500, Ian M. Evans wrote:

My PATH_INFO is just the text after the script. Here’s a grab from
phpinfo():

REQUEST_URI /test.php/123/1

SCRIPT_FILENAME /usr/local/apache/htdocs/test.php
SCRIPT_NAME /test.php
PATH_INFO /123/1

That’s how it’s always been for me.

I wander how can it be with settings:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param PATH_INFO $fastcgi_script_name;

and $fastcgi_script_name == /test.php/123/1 ?

Aleksandar L. wrote:

Maybe this help you, what I have seen yesterday was:
index index.php;
and a request like ‘GET / …’ have not called index.php, after I have
changed to
index /index.php;
everything was fine.

I think that might have worked…will test further today after I catch a
few Zzzzzz’s…it’s 5:39AM here. Thanks.

On Sat, Mar 08, 2008 at 04:44:09PM -0500, Ian M. Evans wrote:

Could it be the cgi.fix-pathinfo = 1 in the php.ini?

May be, I did not look too much in php sources.
If it’s so it really simplifies migration of PHP scripts using PATH_INFO
from Apache to FastCGI.

Igor S. wrote:

Probably, you need

  • location .(php|shtml)$ {
  • location ~ .(php|shtml)$ {

but the .php and .shtml files should be anyway handled by “location /”.

I need coffee! :slight_smile:

As suggested, I changed it to:

location ~ .(php|shtml)$

For whatever reason, it’s still giving “No input file specified.” when
trying to find either an index.shtml or index.php. It’s like it’s
ignoring the:

index index.shtml index.php

Igor S. wrote:

I wander how can it be with settings:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param PATH_INFO $fastcgi_script_name;

and $fastcgi_script_name == /test.php/123/1 ?

Could it be the cgi.fix-pathinfo = 1 in the php.ini?

Igor S. wrote:

May be, I did not look too much in php sources.
If it’s so it really simplifies migration of PHP scripts using PATH_INFO
from Apache to FastCGI.

Well, when I tried out lighttpd before finding nginx (thanks!) their
docs said you need it with php fastcgi, so that’s why I set it.

According to PHP: Description of core php.ini directives - Manual

“Provides real PATH_INFO/PATH_TRANSLATED support for CGI. PHP’s previous
behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
what PATH_INFO is. For more information on PATH_INFO, see the cgi specs.
Setting this to 1 will cause PHP CGI to fix it’s paths to conform to the
spec. A setting of zero causes PHP to behave as before. Default is zero.
You should fix your scripts to use SCRIPT_FILENAME rather than
PATH_TRANSLATED.”