Several third-party module directives allows direct jump to named location, e.g. ngx.exec
from the lua-nginx-module or echo_exec
from the echo-nginx-module (both modules are bundled with the OpenResty package). However using the "vanilla" nginx the only way to do it is to use the try_files
directive trick. Unfortunately the @VictorSchröder assumption of using /dev/null
as the try_files
argument will eliminate the performance penalty due to the system stat
call is wrong, it is the /webroot/dev/null
file that will be stat
'ed in that case. Everyone can check it and see for themselves using the following instruction. So it makes no difference with the commonly used solution like
try_files /nonexistent @app;
However it is possible to pass an empty sting as the try_files
parameter:
try_files "" @app;
This will not eliminate the stat
system call. However it is the webroot directory that will be stat
'ed in this case and checked to be an existing physical file on your filesystem, what it most likely isn't (well, at least unless you point your server or location root to such a file, but why would you do such a wild thing?) By my assumption, modern kernels should cache stat
system call results for the existing filesystem objects more effectively than for non-existing ones. This is only an assumption, so if someone reading this knows better how kernel behaves in this situation, I'll be glad to listen for any clarifications.
I think the last part needs some clarification. Why the try_files
directive checks the web root to be a physical file and not a directory? That's because the ""
argument is not ended with a slash. An argument ended with a slash makes try_files
testing it to be a directory, and an argument not ended with a slash makes try_files
testing it to be a file. That is, the try_files "/" ...
first check will always succeed (and an explicit or implicit index
directive will take a job for an index file searching on the next request processing stage, assuming the location has static content handler) if the location root is pointing to the existing directory, and the try_files "" ...
first check will always fail in that case.
It is also possible that the server webroot would be a non-existent directory, for example when nginx is used for reverse proxying only. Like many other nginx directives the root
directive, if not being inherited from the previous configuration levels, has a default value of /html
relative to the nginx prefix. That prefix is specified during the build time and can be checked with the nginx -V
command (see the --prefix=...
configure argument). If by example this prefix is equal to /etc/nginx
(a common case), the default server webroot will be /etc/nginx/html
which is unlikely to be an existing directory for most environments.
Still I'd prefer try_files "" ...
rather that try_files /nonexistent ...
. If by any mean the nonexistent
file will appear in the webroot directory (think about some kind of defacing hacker attack), the first one will continue to work while the second one will not.
There can be use cases for the try_files "" ...
construction when the webroot directory is specified using the alias
directive, especially for the exact or regex matching locations. However I can't see any possible use case for it being placed inside the location using root
one, so I think nginx development team may consider to update the try_files
module source code to totally eliminate that extra stat
call in case of such a usage. It will made possible "unconditional" location jumps without any extra performance penalty at all while keeping compatibility with the any existing configuration.
location
.@app
throughout the file./api/
location?try_files $uri @app;
the same as the rest of the server block.