In this tutorial, we will discuss about location block and how the Nginx decides which location block will handle the request. I will recommend you to find out how the Nginx choose the server block first before this tutorial, because location block is reside inside the server block. Please read my tutorial here: Understanding Nginx Server Block.
If you already done that, let’s continue!
Nginx Location Block Structure
The Nginx location block generally structured like this:
location modifier location_match {
. . .
}
There are 5 type of modifier
that affect how nginx treat the location_match
parameter:
- No modifier, it means that the
location_match
is interpreted as a URI prefix. Nginx will matched thelocation_match
with the beginning of the requested URI. ^~
, the carat followed by tilde means that thelocation_match
is interpreted as a URI prefix. Same with not using modifier, but has higher priority.~
, the tilde means thelocation_match
will be interpreted as a case-sensitive Regular Expression (RegEx).~*
, the tilde followed by an asterisk means thelocation_match
will be interpreted as a case-insensitive Regular Expression (RegEx).=
, the equal sign means thelocation_match
needs to be exact same with the request URI.
So if we have a location blok like this:
location ^~ /pulic/img {
. . .
}
That mean this location block has modifier: ^~
and a location_match: /pulic/img
How Nginx Decide Which Location Block is Chosen
This is step by step how the Nginx decide which location will be choosen:
- First Nginx will search location block with
=
modifier. If the requested URI is matching exactly with thelocation_match
with this modifier, then the block is chosen right away. - If no matches are found, Then Nginx will search location block with prefix type modifier (
^~
or no modifier). There are 2 cases when Nginx matching thelocation_match
with the request URI:- In case if the longest matching
location_match
has the^~
modifier, then the block is chosen right away. - In case if the longest matching
location_match
has no modifier, then the location block is stored for the moment, and Nginx will continue search location block with RegEx typemodifier
.
- In case if the longest matching
- After the location block with no modifier is stored, Nginx will evaluate the location block with
~
and~*
typemodifier
from top to the bottom of the configuration file. The first regular expression location block that matches the request URI will be chosen right away. Notes: so, mind your location block placement when using These modifier. - If no RegEx type location block matches are found, then the stored location (that has no modifier) will be chosen.
Nginx Location Block Usage Example
To have better understanding of how the Nginx evaluate and choose the location block, we will provide some example for you.
First Example
Let’s assume this configuration in Nginx:
location /public {
...
}
location /img {
...
}
location /public/img {
...
}
If we have request URI like /public/img/mountain.jpg
, it will match the first and third location block, but the third location block will be chosen because it is the longest prefix match. If the request URI like /public/js/home.js
, the first location block will be chosen because it only match with the first location block.
Second Example
Let’s assume this configuration in Nginx:
location ~ \.(js|css)$ {
...
}
location = /private/js/location.js {
...
}
location /private/js {
...
}
If we have request URI like /private/js/location.js
, you will think that it matches all the location block in this example. But as we explained before, Nginx will search location block with =
modifier first. Because the second location block is matching exactly with the request URI, the the second location block is chosen.
Still in this example, if we have request URI like /private/js/store.js
, it matches the first and third location block. But as we now that ~
modifier has more priority than the one that has no modifier, so the first location block is chosen.
Third Example
Let’s assume this configuration in Nginx:
location ~ \.(js|css)$ {
...
}
location = /private/js/location.js {
...
}
location ^~ /private/js {
...
}
This example is almost similar with the second example, but this time we have ^~
modifier on the third block. If we have request URI like /private/js/store.js
, it match the first and the third location block. But as we know that ^~
~modifier has more priority than ~
modifier, so third location block is chosen
Fourth Example
Let’s assume this configuration in Nginx:
location ~ /assets/video/(.*) {
...
}
location ~ \.(mp4|mkv|flv)$ {
...
}
If we have request URI like /assets/video/mycars.mp4
, it matches the first and second block from RegEx perspective. But, nginx evaluate RegEx type modifier from top to bottom, so the first location block is chosen.
Still in this example, it is different story if we have request URI like /video/mycars.mp4
, it only matches the second location block, so the second location block is chosen.
Thats it! Hopefully you understand how Nginx decide which location block will handle the request fro these explanation. Happy learning.