Immediately post-access
following the stage is the try-files
stage. This phase is specifically designed to implement standard configuration Directive Try_files, and does not support Nginx module registration handlers. Since the Try_files directive is useful in the configuration of many FastCGI applications, let's take a brief look here.
The try_files instruction accepts more than two arguments of any number, each specifying a URI. Assuming that N
a parameter is configured, Nginx will try-files
N-1
then map the previous parameter to the object on the filesystem (file or directory), and then check that the objects exist. Once Nginx discovers that a file system object exists, it overwrites the URI of the try-files
current request into the parameter URI for that object (but does not contain the trailing slash character or "internal Jump"). If N-1
the file system object that corresponds to the previous parameter does not exist, the try-files
stage immediately initiates the URI specified by the "internal jump" to the last parameter (that is, the first N
parameter).
As already seen in (vi) and (vii), the static Resource Service module maps the URI of the current request to the file system, which is mapped by the "document Root" specified by the root configuration directive. For example, when the "document Root" is /var/www/
the case, the request URI is /foo/bar
mapped to a file /var/www/foo/bar
, and the request URI is /foo/baz/
mapped to a directory /var/www/foo/baz/
. Notice how this is distinguished by the presence of a slash character at the end of the URI to distinguish between "directory" and "file". The try_files configuration directive we are discussing uses the same rules to complete the mapping of its individual parameter URIs to file system objects.
Consider the following example:
root /var/www/;
location /test {
try_files /foo /bar/ /baz;
echo "uri: $uri";
}
location /foo {
echo foo;
}
location /bar/ {
echo bar;
}
location /baz {
echo baz;
}
The root command here configures the document root directory /var/www/
so that if you have important data in the path in your system, you /var/www/
can replace it with any other path, but this path has at least read access to the system account that is running the Nginx worker process. We location /test
used the try_files configuration directive in, and provided three parameters, /foo
/bar/
and /baz
. According to the introduction of the front-facing try_files directive, we can know that it will try-files
check the first two parameters in sequence /foo
and /bar/
Whether the corresponding file system object exists.
You might want to do a set of experiments first. Assuming that the /var/www/
path is empty now, the file that the first parameter /foo
is mapped to /var/www/foo
does not exist, and the directory that the second parameter is /bar/
mapped to /var/www/bar/
does not exist. The Nginx then initiates the try-files
/baz
"internal jump" in the stage to the URI specified by the last parameter. The actual request results confirm this:
$ Curl Localhost:8080/test
Baz
Obviously, the request is eventually location /baz
bound together to perform the baz
work of the output string. The above example is defined location /foo
and location /bar/
will not participate in the running process here, because for the previous N-1
parameter of Try_files, Nginx will only check the file system, and will not do the URI and location
match between.
For the above request, Nginx will produce a "debug log" similar to the following:
$ grep trying Logs/error.log
[Debug] 3869#0: * Trying to use file: "/foo" "/var/www/foo"
[Debug] 3869#0: * Trying to use dir: "/bar" "/var/www/bar"
[Debug] 3869#0: * Trying to use file: "/baz" "/var/www/baz"
This information allows you to clearly see what try-files
happens during the phase: Nginx examines the files /var/www/foo
and directories /var/www/bar
in turn, and finally processes the last parameter /baz
. Here the last "debugging information" is prone to misunderstanding, will make people mistakenly think Nginx also put the last parameter It is not true that the c4/> is mapped to a file system object for inspection. When the try_files instruction is processed to its last parameter, it always executes the "internal jump" directly, regardless of whether its corresponding file system object exists.
Next, do a set of experiments: /var/www/
under Create a file named foo
, the content is hello world
(note you need to have /var/www/
write permission in the directory):
$ Echo ' Hello World ' >/var/www/foo
Then request the /test
interface:
$ Curl Localhost:8080/test
URI:/foo
What's going on here? In our view, the first parameter of the Try_files directive /foo
can be mapped to a file /var/www/foo
, and Nginx discovers that the try-files
file does exist at the stage, and immediately overwrites the URI of the current request with the value of the parameter, i.e. /foo
, and no longer checks for subsequent arguments. and run the subsequent request processing phase directly.
The try-files
"debug log" generated by the above request in the stage is as follows:
$ grep trying Logs/error.log
[Debug] 4132#0: * Trying to use file: "/foo" "/var/www/foo"
Obviously, in the try-files
stage, Nginx does only check and deal with /foo
this parameter, and the subsequent parameters are "shorted" out.
Similarly, let's say we delete the /var/www/foo
file you just created, and /var/www/
create a subdirectory named bar
:
$ mkdir/var/www/bar
The result of the request is /test
similar:
$ Curl Localhost:8080/test
URI:/bar
In this case, Nginx in the try-files
stage found that the first parameter /foo
corresponding to the file does not exist, will be turned to check the second parameter corresponding to the file system object (here is the directory /var/www/bar/
). Because this directory exists, Nginx overwrites the URI of the current request with the value of the second parameter, i.e. /bar
(note that the original parameter value is /bar/
, but try_files automatically removes the trailing slash character).
The "debug log" generated by this set of experiments is as follows:
$ grep trying Logs/error.log
[Debug] 4223#0: * Trying to use file: "/foo" "/var/www/foo"
[Debug] 4223#0: * Trying to use dir: "/bar" "/var/www/bar"
We see that the Try_files directive only checks and deals with its first two parameters here.
It is not difficult to see through the previous groups of experiments that the Try_files directive essentially only conditionally overwrites the URI of the current request, and the "condition" here is actually the existence of an object on the filesystem. When "condition" is not satisfied, it will unconditionally initiate a specified "internal jump". Of course, in addition to the unconditional launch of an "internal jump", the try_files directive also supports the HTTP error page that returns the specified status code directly, for example:
try_files/foo/bar/= 404;
This line of configuration means that the /foo
/bar/
error page is returned directly when the file system object that corresponds to the parameter does not exist 404 Not Found
. Notice how it uses the equals character prefix to identify the HTTP status code.
Execution order of Nginx configuration directives (11)