Skip to content

[5.7] Remove fastcgi_split_path_info from nginx config #4867

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 27, 2018

Conversation

0xb4lint
Copy link

Hello @taylorotwell!

You've probably missed my previous PR's (#4847) comments, let me summarize to create a whole picture.

fastcgi_split_path_info

What is purpose of the fastcgi_split_path_info nginx directive?

It constructs the $fastcgi_path_info variable from the given regex (with exactly 2 capture groups).
Most widely used value is ^(.+\.php)(/.+)$. (nginx docs)

What is effect of using fastcgi_split_path_info?

The $fastcgi_path_info value will be set to the processed path's portion after the .php extension.
Example: https://laravel.com/test.php/foo/bar => /foor/bar.

How can I use the $fastcgi_path_info variable?

Now we may have some value assigned to $fastcgi_path_info, but we have to pass it to PHP via the PATH_INFO variable (the default /etc/nginx/fastcgi_params file does not handle it).
The standard way to do that: fastcgi_param PATH_INFO $fastcgi_path_info.

What is prerequisite of using fastcgi_split_path_info?

Since the only use-case is getting the substring (routing) after the .php file, we have to create a location block which handles such paths.
Most widely used location block to do that:

location ~ [^/]\.php(/|$) {
    ...
}

Should I use the fastcgi_split_path_info?

Only if you have to deal with /index.php/foo/bar style routes (or slash arguments as Moodle calls it).
Typical applications which require it: Moodle, older Joomla!, Drupal (only update route), Magento (only update route) or any legacy stuff.
Some applications which support it: Symfony (note the internal directive), Slim (note the missing $)
Some applications which don't support it: Yii 2, Zend, CodeIgniter, CakePHP, WordPress

Can I see some example?

Example reques #1: https://laravel.com/test.php

  • without fastcgi_split_path_info:
    • $fastcgi_script_name: /test.php
    • $fastcgi_path_info: no value
  • with fastcgi_split_path_info (value: ^(.+\.php)(/.+)$):
    • $fastcgi_script_name: /test.php
    • $fastcgi_path_info: no value

Example request #2: https://laravel.com/test.php/foo/bar

  • without fastcgi_split_path_info:
    • $fastcgi_script_name: /test.php/foo/bar
    • $fastcgi_path_info: no value
  • with fastcgi_split_path_info (value: ^(.+\.php)(/.+)$):
    • $fastcgi_script_name: /test.php
    • $fastcgi_path_info: /foo/bar

fastcgi_split_path_info × Laravel

What's the issue with nginx configuration?

The Deployment documentation of Laravel suggests the following nginx PHP location block:

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}

Issues:

  1. The location regex restricts the processed path to end with .php (e.g. /test.php), so it won't process a route with slash arguments (e.g. /test.php/foo/bar).
  2. If only the .php$ paths will be processed the there is no point of using fastcgi_split_path_info.
  3. Even if we are using the fastcgi_split_path_info directive, the generated $fastcgi_path_info (without value in this case) isn't used anywhere.

Solutions

#1 Get rid of fastcgi_split_path_info

The most obvious way to handle this anomaly is removing the fastcgi_split_path_info directive, as I suggested in this PR.
The final location block would be:

location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}

#2 Allow slash arguments

Another way to make the configuration useful is extending the location regex to: [^/]\.php(/|$)
The final location block would be:

location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}

(#3 Hybrid solution)

Laravel's Illuminate\Http\Request class extends Symfony\Component\HttpFoundation\Request class, which handles the PATH_INFO variable if present, but also can construct it from the url. We can get rid of fastcgi_split_path_info directive (since we currently do not pass the PATH_INFO variable to PHP) and allow the slash arguments processing location regex.

location ~ [^/]\.php(/|$) {
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}

Thanks for reading this.
What do you think @taylorotwell?

P.S. Sorry for the duplicate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants