I'm switching from Apache to Nginx/fcgi and I'm having a small issue while attempting to setup the applications rewrite rules.
The code handles routes via the use of PATH_INFO, e.g., example.com/foo/bar/ will be routed to example.com/index.php/foo/bar/
I've modified the server configuration to pass PATH_INFO:
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param SCRIPT_FILENAME /var/www/public$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
}
And the rewrite handler:
location / {
root /var/www/public;
index index.html index.htm index.php;
if (!-f $request_filename) {
rewrite ^(.*)/(.*)$ /index.php/$2 break;
}
}
With 'rewrite_log on', the url's appear to be routing properly:
[error]: *2 open() "/var/www/public/index.php/test" failed (20: Not a directory), client: 192.168.0.254, server: example.com, request: "GET /test HTTP/1.1", host: "example.com", referrer: "http://example.com/index.php"
However, it appears to be looking for the directory "test". How can I force it to request index.php, passing '/test' to the script?
Looks like you're following a poor tutorial which is severely outdated (
if (!-f
is generally not recommended, withtry_files
offered as a better replacement). You have numerous problems:First you have directives in
location /
context which should be inserver
context, so you can avoid path duplication in theSCRIPT_FILENAME
variable.Secondly, you use the
break
flag in your rewrite; this means it should not re-evaluate the location matching. This effectively makes the request never leave thelocation /
block and is instead treated as a static file request.Thirdly, have a look at your
location ~ \.php$ {
: Nginx matches locations against the URI and you're specifically telling Nginx to only handle URIs which end in.php
, but if you rewrite toindex.php/test/
then it won't trigger.Lastly, you're using
PATH_INFO
while you should be usingREQUEST_URI
. The difference is that to make PATH_INFO work you have to tell Nginx to pass any request with.php
in it to PHP, and PHP has to then find the right file.This means that you allow requests like
example.org/uploads/image.jpg/index.php
to be sent to PHP and you also allow PHP to execute the file/uploads/image.jpg
. If a malicious user uploaded that file with PHP in it they now have arbitrary code execution on your server. This is a very real exploit that I have personally seen people be vulnerable to.Please stop using randomly Googled tutorials because 90% of them are utter garbage, instead go read the wiki. It might be a bother having to actually learn about the web server you're using, but the alternative is to have your server compromised.