Two Wrongs

Reading Notes: Understanding Nginx Location Selection

Reading Notes: Understanding Nginx Location Selection

I’ve always had a cargo cult approach to nginx configuration, as I’m sure many others do as well. But this time, I couldn’t get the behaviour I wanted by just trying different permutations of the configuration directives I know, so I did some quick reading.

I’ll skip over the parts about server blocks because they don’t interest me at the moment. I did have to read about them once, when doing some slightly more advanced rewriting, but that was for a previous job, and thus irrelevant now. I know I can find the information again should I need to.

Location Block

The location block is selected in the following order.

  1. Exact matches (specified with location = /some/thing/or.other).
  2. Regular expression matches11 First match encountered is used first – but any regular expression matches embedded inside prefix matches are chosen preferentially … (specified with location ~ /some/.*other).
  3. Prefix matches (specified with location /some/thing), where longest match goes first.

Internal Redirect Directives

The index directive causes an internal redirect22 Internal redirect means that it doesn’t send a 302 response to the client, it simply performs an implicit rewrite of the url and attempts to process it as though the user typed the new url originally., which means nginx will restart its processing of location blocks with the new path. The new path may very well end up matching a different location block than the one with the index directive in it.

On the other hand, try_files is relatively primitive. When encountered, nginx will look for any of the specified files physically in the directory matched by the location block. If they don’t exist, nginx does an internal redirect to the last entry in the directive.

You can also specify an internal redirect with the rewrite directive: when the last flag is specified (as in rewrite ^/defaults/(.*) /etc/defaults/$1 last), nginx will look up the new url among your defined locations without redirecting the user.