Nginx-0.7.31

Changes with nginx 0.7.31 19 Jan
2009

*) Change: now the "try_files" directive tests files only and 

ignores
directories.

*) Feature: the "fastcgi_split_path_info" directive.

*) Bugfixes in an "Expect" request header line support.

*) Bugfixes in geo ranges.

*) Bugfix: in a miss case ngx_http_memcached_module returned the 

“END”
line as response body instead of default 404 page body; the bug
had
appeared in 0.7.18.
Thanks to Maxim D…

*) Bugfix: while SMTP proxying nginx issued message "250 2.0.0 OK"
   instead of "235 2.0.0 OK"; the bug had appeared in 0.7.22.
   Thanks to Maxim D..

Nginx 0.7.31 for Windows is now available: http://cli.gs/731

Thanks,
Kevin

Kevin W.

Igor S. <is@…> writes:

Changes with nginx 0.7.31 19 Jan 2009

*) Change: now the "try_files" directive tests files only and ignores 
   directories.

This seems to cause problems with index.php inside directories. For
example:

index index.php;
location / {
try_files $uri @php;
}
location @php {
fastcgi_pass …;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
location ~ .php$ {
fastcgi_pass …;
fastcgi_param SCRIPT_FILENAME $document_root$uri;
}

With 0.7.30 if you request http://example.com/test/ ,
$document_root/test/index.php is served. However with 0.7.31,
$document_root/index.php is served.

And if you do this:

try_files $uri $uri/index.php @php;

then nginx will serve index.php as a static file, without passing it to
FastCGI.
I know this is the intended behavior, as internal rewrite is only issued
for the
last parameter of try_files. So how should we let try_files detect
index.php
inside a directory if directories are ignored?

Igor S. <is@…> writes:

location ~ (/|.php)$ {
fastcgi_pass …;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

This works for the most part, but if I implement a try_files alternative
within the location block like this:

location ~ (/|.php)$ {
if (!-f $document_root$fastcgi_script_name) {
rewrite ^ @php last;
}
fastcgi_pass …;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Then nginx will segfault when example.com/test/ is requested.
So I can only do this:

location ~ (/|.php)$ {
if (!-e $document_root$uri) {
rewrite ^ @php last;
}
fastcgi_pass …;

}

But this doesn’t take care of the case where index.php doesn’t exist
inside a directory. Is $fastcgi_script_name not properly set when
used as “if” condition?

On Mon, Jan 19, 2009 at 04:47:33PM +0000, cynix wrote:

fastcgi_param SCRIPT_FILENAME $document_root$uri;
then nginx will serve index.php as a static file, without passing it to FastCGI.
I know this is the intended behavior, as internal rewrite is only issued for the
last parameter of try_files. So how should we let try_files detect index.php
inside a directory if directories are ignored?

The change has been apperaed due to Mongrel-type configuration:

location / {
try_files /system/maintenance.html
$uri $uri/index.html $uri.html
@mongrel;
}

location @mogrel {
proxy_pass http://mongrel;
}

when “/” exists, but /index.html is not exist, then request was handled
locally and return 403.

I will look how to resolve the issue.

One possible solution:

location / {
try_files $uri @php;
}

location @php {
fastcgi_pass …;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}

location ~ (/|.php)$ {
fastcgi_pass …;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Would it make sense for wordpress now instead of doing this:

error_page 404 = /wordpress/index.php?q=$request_uri;

To do something with a try_files directive? Now that it is there I
want to try to take advantage of it :slight_smile:

On Tue, Jan 20, 2009 at 02:32:27AM +0000, cynix wrote:

This works for the most part, but if I implement a try_files alternative

But this doesn’t take care of the case where index.php doesn’t exist
inside a directory. Is $fastcgi_script_name not properly set when
used as “if” condition?

This is a bug in 0.7.31, I will fix it soon.

As to your configuraiton, you should use:

location ~ (/|.php)$ {

  • if (!-f $document_root$fastcgi_script_name) {
  • rewrite ^ @php last;
  • }
  • try_files $uri $uri/index.php @php;

    fastcgi_pass …;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

On Tue, Jan 20, 2009 at 01:10:07AM -0800, mike wrote:

Would it make sense for wordpress now instead of doing this:

error_page 404 = /wordpress/index.php?q=$request_uri;

To do something with a try_files directive? Now that it is there I
want to try to take advantage of it :slight_smile:

Yes.

oh i see in the russian docs

would this be identical to below?

try_files $uri /wordpress/index.php?q=$request_uri;

and is try_files now the recommended method instead of using the
error_page 404? is it faster/less intensive?

On Tue, Jan 20, 2009 at 01:41:03AM -0800, mike wrote:

oh i see in the russian docs

would this be identical to below?

try_files $uri /wordpress/index.php?q=$request_uri;

If you do not need PATH_INFO, then:

location / {
try_files $uri @wordpress;
}

location ~ .php {
try_files $uri @wordpress;

fastcgi_pass   ...;

fastcgi_param  SCRIPT_FILENAME  /path/to$fastcgi_script_name;
fastcgi_param  QUERY_STRING     $query_string;  # or $args

# other fastcgi_param's

}

location @wordpress {
fastcgi_pass …;

fastcgi_param  SCRIPT_FILENAME  /path/to/index.php;
fastcgi_param  QUERY_STRING     q=$request_uri;

# other fastcgi_param's

}

On Mon, Jan 19, 2009 at 08:44:48PM +0300, Igor S. wrote:

location ~ .php$ {
try_files $uri $uri/index.php @php;
$uri $uri/index.html $uri.html
I will look how to resolve the issue.
I think we can say explicitly that we want to test directory existance
using trailing slash:

try_files $uri $uri/ @php;

On Tue, Jan 20, 2009 at 10:22:32AM -0200, Juan Fco. Giordana wrote:

This approach seems interesting, but why did the functionality changed
in first place?

The reason has been in the same e-mail above. Here is a copy:

The change has been appeared due to Mongrel-type configuration:

location / {
try_files /system/maintenance.html
$uri $uri/index.html $uri.html
@mongrel;
}

location @mogrel {
proxy_pass http://mongrel;
}

when “/” exists, but /index.html is not exist, then request was handled
locally and return 403.

This approach seems interesting, but why did the functionality changed
in first place?

On Tue, Jan 20, 2009 at 01:48:21PM +0000, cynix wrote:

Igor S. <is@…> writes:

  • try_files $uri $uri/index.php @php;

Thanks, this is working indeed.

I like your idea about testing the existence of directory with “$uri/”.

The attached patch enables trailing slash as directory flag.

Igor S. <is@…> writes:

  • try_files $uri $uri/index.php @php;

Thanks, this is working indeed.

I like your idea about testing the existence of directory with “$uri/”.