Forum: NGINX fastcgi server variables vs. apache

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
2974d09ac2541e892966b762aad84943?d=identicon&s=25 androo (Guest)
on 2009-04-07 02:02
(Received via mailing list)
First of all, thank you for Nginx. It is a breath of fresh air after
Apache. And though it has taken some getting used to, I've discovered
that I like the config file syntax better in Nginx.

Second, there are three server variables whose values are not the same
under Nginx as under Apache: PATH_INFO, PATH_TRANSLATED, and
SCRIPT_NAME. Obviously this makes trouble when trying to use
applications designed for Apache. In addition, because the
"fastcgi_param" directive cannot be used inside an "if" statement, it is
impossible to write a general rule to set their values the same as under
Apache. This is an issue when using URIs of the form
"/directory/script.php/blah".

PATH_INFO: Under Apache, it doesn't exist unless using URIs of the above
form; then it equals "/blah". Under Nginx, it never exists.

PATH_TRANSLATED: Under Apache, it doesn't exist unless using URIs of the
same form; then it equals "/document/root/blah" (note: not
"/document/root/directory/blah"). Under Nginx, it exists when using such
URIs, but it equals "/document/root".

SCRIPT_NAME: Under Apache, when using URIs of the same form, it equals
"/directory/script.php". Under Nginx, it equals
"/directory/index.php/blah".

So far I haven't been able to find a general rule to fix this. What I
would like to do is put something like this at the end of
fastcgi_params:

if ($document_uri ~ "^/(.+)\.php/(.*)") {
    fastcgi_param PATH_INFO /$2;
    fastcgi_param PATH_TRANSLATED $document_root/$2;
    fastcgi_param SCRIPT_NAME /$1.php;
}

If someone called a URI that matched the pattern, these values would
kick in; otherwise, the defaults would be used. But this can't be done
because "fastcgi_param" isn't allowed inside "if". Next I tried the
following at the end of fastcgi_params:

if ($document_uri ~ "^/(.+)\.php/(.*)") {
    set $apache_path_info /$2;
    set $apache_path_translated $document_root/$2;
    set $apache_script_name /$1.php;
}
fastcgi_param  PATH_INFO          $apache_path_info;
fastcgi_param  PATH_TRANSLATED    $apache_path_translated;
fastcgi_param  SCRIPT_NAME        $apache_script_name;

But this sets PATH_INFO, PATH_TRANSLATED, and (most problematically)
SCRIPT_NAME to empty values even for URIs that don't match the pattern.

Has anyone found a way around this? I.e. a way of writing a general rule
(i.e., one that is not hard-coded for specific URIs) that will normalize
the three variables to their Apache values?

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,866,866#msg-866
0c31ca11d92038571de52b53c8ad4a8a?d=identicon&s=25 Denis F. Latypoff (Guest)
on 2009-04-07 04:58
(Received via mailing list)
Hello androo,

Tuesday, April 7, 2009, 6:55:15 AM, you wrote:

> First of all, thank you for Nginx. It is a breath of fresh air
> after Apache. And though it has taken some getting used to, I've
> discovered that I like the config file syntax better in Nginx.

> Second, there are three server variables whose values are not the
> same under Nginx as under Apache: PATH_INFO, PATH_TRANSLATED, and
> SCRIPT_NAME. Obviously this makes trouble when trying to use
> applications designed for Apache. In addition, because the
> "fastcgi_param" directive cannot be used inside an "if" statement,
> it is impossible to write a general rule to set their values the
> same as under Apache. This is an issue when using URIs of the form 
"/directory/script.php/blah".

> PATH_INFO: Under Apache, it doesn't exist unless using URIs of the
> above form; then it equals "/blah". Under Nginx, it never exists.

> PATH_TRANSLATED: Under Apache, it doesn't exist unless using URIs
> of the same form; then it equals "/document/root/blah" (note: not
> "/document/root/directory/blah"). Under Nginx, it exists when using
> such URIs, but it equals "/document/root".

> SCRIPT_NAME: Under Apache, when using URIs of the same form, it
> equals "/directory/script.php". Under Nginx, it equals "/directory/index.php/blah".

> So far I haven't been able to find a general rule to fix this. What
> I would like to do is put something like this at the end of fastcgi_params:

> if ($document_uri ~ "^/(.+)\.php/(.*)") {
>     fastcgi_param PATH_INFO /$2;
>     fastcgi_param PATH_TRANSLATED $document_root/$2;
>     fastcgi_param SCRIPT_NAME /$1.php;
> }

> If someone called a URI that matched the pattern, these values
> would kick in; otherwise, the defaults would be used. But this can't
> be done because "fastcgi_param" isn't allowed inside "if". Next I
> tried the following at the end of fastcgi_params:

> if ($document_uri ~ "^/(.+)\.php/(.*)") {
>     set $apache_path_info /$2;
>     set $apache_path_translated $document_root/$2;
>     set $apache_script_name /$1.php;
> }
> fastcgi_param  PATH_INFO          $apache_path_info;
> fastcgi_param  PATH_TRANSLATED    $apache_path_translated;
> fastcgi_param  SCRIPT_NAME        $apache_script_name;

> But this sets PATH_INFO, PATH_TRANSLATED, and (most
> problematically) SCRIPT_NAME to empty values even for URIs that don't match the pattern.

> Has anyone found a way around this? I.e. a way of writing a general
> rule (i.e., one that is not hard-coded for specific URIs) that will
> normalize the three variables to their Apache values?

Since version 0.7.31 use may use fastcgi_split_path_info:

    location ~ ^(.+\.php)(.*)$ {

        fastcgi_split_path_info         ^(.+\.php)(.*)$;
        fastcgi_param  SCRIPT_FILENAME
/path/to/php$fastcgi_script_name;
        fastcgi_param  PATH_INFO        $fastcgi_path_info;
        fastcgi_param  PATH_TRANSLATED
$document_root$fastcgi_path_info;
        ...
    }
2974d09ac2541e892966b762aad84943?d=identicon&s=25 androo (Guest)
on 2009-04-08 05:08
(Received via mailing list)
Brilliant! Many thanks. --Androo


Since version 0.7.31 use may use fastcgi_split_path_info:

location ~ ^(.+\.php)(.*)$ {

fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param SCRIPT_FILENAME /path/to/php$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
...
}


> Posted at Nginx Forum:
> http://forum.nginx.org/read.php?2,866,866#msg-866


Posted at Nginx Forum: http://forum.nginx.org/read.php?2,866,908#msg-908
3cfefffa747cab36a4befb41d13d20b2?d=identicon&s=25 My SchizoBuddy (myschizobuddy)
on 2009-12-10 15:28
what is /path/to/php?
is it where the root index.php is

for links like dev.flow3.local/index.php/flow3/welcome
the path_translated is C:/nginx/html/flow3/Web/flow3/welcome which is
wrong cause there is no folder flow3 inside the Web folder. flow3 and
welcome are query parameters not folders.
0f7a1240e82f744c6c607fa7081b99f7?d=identicon&s=25 Igor Sysoev (Guest)
on 2009-12-19 15:25
(Received via mailing list)
On Thu, Dec 10, 2009 at 03:28:17PM +0100, My SchizoBuddy wrote:

> what is /path/to/php?
> is it where the root index.php is
>
> for links like dev.flow3.local/index.php/flow3/welcome
> the path_translated is C:/nginx/html/flow3/Web/flow3/welcome which is
> wrong cause there is no folder flow3 inside the Web folder. flow3 and
> welcome are query parameters not folders.

location ~ ^(.+\.php)(.*)$ {
    fastcgi_split_path_info         ^(.+\.php)(.*)$;
    fastcgi_param  SCRIPT_FILENAME  C:/nginx/html$fastcgi_script_name;
    fastcgi_param  PATH_INFO        $fastcgi_path_info;
    ...
}

For dev.flow3.local/index.php/flow3/welcome
SCRIPT_FILENAME will be "C:/nginx/html/index.php"
PATH_INFO - "/flow3/Web/flow3/welcome"


--
Igor Sysoev
http://sysoev.ru/en/
2974d09ac2541e892966b762aad84943?d=identicon&s=25 spirit (Guest)
on 2009-12-19 15:25
(Received via mailing list)
@shizobuddy: /path/to/php is usually $document_root if set properly so
you come up with the following generic config:

fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;

@androo: instead of setting fastcgi_param in a if (in fact you can't),
you can still set variables to do so. Example


        set $script index.php;
        set $path_info "";
        if ($uri ~ "^(.+\.php)(.*)") {
            set $script $1;
            set $path_info $2;
        }
        fastcgi_param PATH_INFO $path_info;
        ....


Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,866,30886#msg-30886
0f7a1240e82f744c6c607fa7081b99f7?d=identicon&s=25 Igor Sysoev (Guest)
on 2009-12-19 15:25
(Received via mailing list)
On Wed, Dec 16, 2009 at 08:40:17AM -0500, spirit wrote:

> @shizobuddy: /path/to/php is usually $document_root if set properly so you come up with 
the following generic config:
>
> fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;

The slash is not needed:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

>         ....
It's better to use fastcgi_split_path_info:

    location ~ ^(.+\.php)(.*)$ {
        fastcgi_split_path_info         ^(.+\.php)(.*)$;
        fastcgi_param  SCRIPT_FILENAME
/path/to/php$fastcgi_script_name;
        fastcgi_param  PATH_INFO        $fastcgi_path_info;

or named captures:

    location ~ ^(?<script_name>.+\.php)(?<path_info>.*)$ {

        fastcgi_param  SCRIPT_FILENAME  /path/to/php$script_name;
        fastcgi_param  PATH_INFO        $path_info;


--
Igor Sysoev
http://sysoev.ru/en/
2974d09ac2541e892966b762aad84943?d=identicon&s=25 locojohn (Guest)
on 2011-07-07 15:22
(Received via mailing list)
Dear Igor,

According to my understanding, either way PATH_INFO is set to
url-encoded string, while according to CGI 1.1 specification, it should
contain the url-decoded string.  Which brings troubles when there are
spaces in file names, for instance.

I am using nginx 1.0.4 and this still seems like an issue.  Is there a
way to pass url-decoded strings over to fastcgi applications?

Thank you in advance for response!

Andrejs


Igor Sysoev Wrote:
-------------------------------------------------------

> >             set $script $1;
>         fastcgi_param  SCRIPT_FILENAME
> /path/to/php$script_name;
> nginx@nginx.org
> http://nginx.org/mailman/listinfo/nginx

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,866,212002#msg-212002
This topic is locked and can not be replied to.