How does try_files work?

Solution 1:

try_files tries the literal path you specify in relation to the defined root directive and sets the internal file pointer. If you use for instance try_files /app/cache/ $uri @fallback; with index index.php index.html; then it will test the paths in this order:

  1. $document_root/app/cache/index.php
  2. $document_root/app/cache/index.html
  3. $document_root$uri

before finally internally redirecting to the @fallback named location. You can also use a file or a status code (=404) as your last parameter but if using a file it must exist.

You should note that try_files itself will not issue an internal redirect for anything but the last parameter. Meaning you cannot do the following: try_files $uri /cache.php @fallback; as that will cause nginx to set the internal file pointer to $document_root/cache.php and serve it, but since no internal redirect takes place the locations aren't re-evaluated and as such it will be served as plain text. (The reason it works with PHP files as the index is that the index directive will issue an internal redirect)

Solution 2:

Here's another convenient use of try_files, as unconditional redirects to named locations. The named locations are effectively acting as subroutines, saving duplication of code. When the first argument to try_files is _ the fallback redirect is always taken (assuming that _ is not an existing filename). Because nginx needs a goto statement but doesn't have one.

    location =/wp-login.php { try_files _ @adminlock; }
    location ^~ /wp-admin/  { try_files _ @adminlock; }
    location @adminlock  {
            allow 544.23.310.198;
            deny all;
            try_files _ @backend;
            # wp-admin traffic is tiny so ok to send all reqs to backend 
    }
    location ~ \.php {  try_files _ @backend; }
    location / { try_files $uri $uri/ =403; }
    location @backend {
            fastcgi_pass 127.0.0.1:9000;
            include snippets/fastcgi-php.conf;
    }

Tags:

Nginx