When Does Location Block Evaluation Jump to Other Locations?
When a location block is selected to serve a request, the request is handeled intirely within that context from that point onward. Only the selected location and the inherited directives determine how the request is processed, without interference from sibling location blocks.
Some directives that lead to internal redirect types:
index
try_files
rewrite
error_page
index
The index
directive always leads to an internal redirect if it is used to handle the request. Exact location matches are often used to speed up the selection process by immediately ending the execution of the algorithm. However, if you make an exact location match that is a directory, there is a good chance that the request will be redirected to a different location for actual processing.
The first location is matched by a request URI of /exact
, but in order to handle the request, the index
directive inherited by the block initiates an internal redirect to the second block:
index index.html;
location = /exact {
. . .
}
location / {
. . .
}
try_files
Another instance where the processing location may be reevaluated is with the try_files
directive. This directive tells Nginx to check for the existence of a named set of files or directories. The last parameter can be a URI that Nginx will make an internal redirect to.
Consider the following configuration:
root /var/www/main;
location / {
try_files $uri $uri.html $uri/ /fallback/index.html;
}
location /fallback {
root /var/www/another;
}
In the above example, if a request is made for /blahblah
, the first location will initially get the request. It will try to find a file called blahblah
in /var/www/main
directory. If it cannot find one, it will follow up by searching for a file called blahblah.html
. It will then try to see if there is a directory called blahblah/
within the /var/www/main
directory. Failing all of these attempts, it will redirect to /fallback/index.html
. This will trigger another location search that will be caught by the second location block. This will serve the file /var/www/another/fallback/index.html
.
re_write
Another directive that can lead to a location block pass off is the rewrite
directive. When using the last
parameter with the rewrite
directive, or when using no parameter at all, Nginx will search for a new matching location based on the results of the rewrite
.
For example, if we modify the last example to include a rewrite, we can see that the request is sometimes passed directly to the second location without relying on the try_files directive:
root /var/www/main;
location / {
rewrite ^/rewriteme/(.*)$ /$1 last;
try_files $uri $uri.html $uri/ /fallback/index.html;
}
location /fallback {
root /var/www/another;
}
In the above example, a request for /rewriteme/hello
will be handled initially by the first location block. It will be rewritten to /hello
and a location will be searched. In this case, it will match the first location again and be processed by the try_files
as usual, maybe kicking back to /fallback/index.html
if nothing is found (using the try_files
internal redirect we discussed above).
error_page
The error_page
directive can lead to an internal redirect similar to that created by try_files
. This directive is used to define what should happen when certain status codes are encountered.
root /var/www/main;
location / {
error_page 404 /another/whoops.html;
}
location /another {
root /var/www;
}
Every request (other than those starting with /another
) will be handled by the first block, which will serve files out of /var/www/main
. However, if a file is not found (a 404 status), an internal redirect to /another/whoops.html
will occur, leading to a new location search that will eventually land on the second block. This file will be served out of /var/www/another/whoops.html
.