Debugging `try_files` with 404 as a last resort

petecooper nginx-forum at forum.nginx.org
Tue Nov 13 22:23:41 UTC 2018


Hello.

I've got into knots with `try_files` inside `location` when PHP is
involved.

Ideally, I would like the following route for `try_files` (in order):

* $uri (requested URI)
* $uri/ (requested URI, trailing slash)
* /index.php?$args (use root `index.php` with args)
* =404 (Nginx returns 404)

Here is my current code:

        location / {
                index index.html index.php;
                limit_except GET HEAD POST {
                        deny all;
                }
                try_files $uri $uri/ /index.php?$args;
        }
        location ~ ^.+\.php(?:/.*)?$ {
                fastcgi_hide_header "X-Powered-By";
                fastcgi_index index.php;
                fastcgi_keep_conn on;
                fastcgi_next_upstream error timeout;
                fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
                fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                include fastcgi_params;
                try_files $uri =404;
        }

Note there is no `=404` on the first `location`. PHP is installed and
running, and the PHP CMS works fine. I am somewhat confused as to why things
start to misbehave when I add a `=404` to the first location block. I will
explain…

== Using `try_files $uri $uri/ /index.php?$args;` ==

* https://example.com (200 OK)
* https://example.com/index.php (200 OK)
* https://example.com/articles (200 OK)
* https://example.com/index.php?s=articles (200 OK)
* https://example.com/non-existent-uri/ (404 Not Found, rendered by CMS via
`index.php`)
* https://example.com/non-existent-uri (404 Not Found, rendered by CMS via
`index.php`)

== Using `try_files $uri $uri/ /index.php?$args =404;` ==

* https://example.com (200 OK)
* https://example.com/index.php (200 OK)
* https://example.com/articles (404 Not Found, rendered by Nginx)
* https://example.com/index.php?s=articles (200 OK)
* https://example.com/non-existent-uri/ (404 Not Found, rendered by Nginx)
* https://example.com/non-existent-uri (404 Not Found, rendered by Nginx)

I do not fully understand why https://example.com/articles results in a 404
Not Found when `index.php?$args` generates a valid page (200 OK) and
precedes `=404`. Does the `=` carry some weight?

I would greatly appreciate a pointer for further reading so I can better
understand.

Thank you in advance.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,281938,281938#msg-281938



More information about the nginx mailing list