Try_files and location blocks
António P. P. Almeida
appa at perusio.net
Fri Jun 24 02:02:06 MSD 2011
On 23 Jun 2011 22h37 WEST, dave at jetcafe.org wrote:
> Hello. :) Could someone please correct my understanding of location
> blocks and try files? I'm trying to get http errors to be very
> graceful, normally being handled by php but in extreme cases
> returning the proper numeric error. For my example, just consider
> 404:
My take on it.
> server {
> ...
> try_files $uri $uri/ /error.php?c=404
>
> error_page 404 = @error_404;
> location @error_404 {
> try_files /error.php @not_found;
> rewrite ^ $scheme://$server_name/error.php?c=404
> }
> location @not_found {
> return 404;
> }
> }
There are no "regular" locations, meaning, regex or others. Only
"special" named locations. They must be invoked explicitly in your
config.
NGX_HTTP_TRY_FILES_PHASE happens at server level. Tries to serve the requested
URI either as a file or a dir. Fallbacks to error.php with arg c=404;
If the file is not found then signals a 404, error_page directive
redirects to @error_404 location.
@error_404 location runs rewrite phase directive, rewriting to
$scheme://$server_name/error.php?c=404
Try files phase runs again and serves the URI /error.php with arg c=404.
> I'm not clear why this does not work. I rewrite the above example
> as:
>
> server {
> ...
> location / {
> try_files $uri $uri/ /error.php?c=404;
> }
>
> location /error.php {
> try_files /error.php @not_found;
> }
>
> error_page 404 = @not_found;
> location @not_found {
> return 404;
> }
> }
Now the processing will try to find a matching location. If none is
found than use the '/' "catch-all" location.
Any URI != error.php will be served by handlers you have specified in
the '/' location and those that are inherited from outside (the rule
with some exceptions).
In this case runs the try_files directive like above, fallbacks to
error.php with arg c=404.
Now enters /error.php location, runs try_files again, tries error.php
fallbacks to @not_found. Location @not_found runs rewrite phase
directive return 404. Status 404 is returned. No more processing here.
Note that the error_page directive is only invoked if you don't have
the error.php file in place. Otherwise it will never run.
> and it appears to work. I think the downside of this is that
> I have to have the location /error.php explicitly invoke php.
>
> While I enjoy hacking at something, I also enjoy understanding
> something just as well. So what am I confused about?
HTH,
--- appa
PS: You can verify this flow in your error log by using the debug flag
with the error_log directive.
More information about the nginx
mailing list