When working with nginx, in addition to returning static files, we can also build a flexible routing system, suitable for efficient Hosting environments.
Prefix Match is a term that describes partial URI matching. To clarify Prefix Match, let's refer to the following examples.
First, we will learn about a new context called location. Follow the example below:
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location /demo {
return 200 "Hello";
}
}
}
In the above example:
And if we run the test command below
curl -i http://nglearns.test/demo
Result:
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 15:59:07 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
# Hello
Here we can easily retrieve the content "Hello".
We will try calling a different URL like this
curl -i http://nglearns.test/demoA
Result
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 15:59:07 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
# Hello
In this case, because nginx understands that only a URI matching "demo" can access the application.
Exact Match is a term used to describe a complete URI match. Please refer to the example below.
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location = /demo {
return 200 "Hello";
}
}
}
Adding an = sign before the URI will help nginx understand and only allow access to exactly matching URIs.
Let's check the case of matching URI
curl -I http://nglearns.test/demo
Result
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:15:04 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
In this case, we have successfully requested and received a status of 200
Let's try with a case that does not match the URI
curl -I http://nglearns.test/demoA
Result
# HTTP/1.1 404 Not Found
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:14:29 GMT
# Content-Type: text/html
# Content-Length: 162
# Connection: keep-alive
In this case, we could not access because the request did not match the specified URI.
Regex Match is a term that describes matching URIs according to a predefined template. Follow the example below
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location ~ /demo[0-9] {
return 200 "Hello";
}
}
}
In this case, we use the ~ symbol to tell nginx that URI matching will be determined by the template /demo[0-9].
Let's experiment with the following example
curl -I http://nglearns.test/demo
Result
# HTTP/1.1 404 Not Found
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:14:29 GMT
# Content-Type: text/html
# Content-Length: 162
# Connection: keep-alive
In this case, the request returns a 400 error because the URI does not match the template, as we need a number from 0 to 9 after the demo URI
Try testing with a different case
curl -I http://nglearns.test/demo8
Result
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:15:04 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
In this case, the URI matched the template and the request was successful.
Try testing with a URL that has uppercase letters
curl -I http://nglearns.test/demo8
Result
# HTTP/1.1 404 Not Found
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:14:29 GMT
# Content-Type: text/html
# Content-Length: 162
# Connection: keep-alive
In the above case, the request fails because Regex Match always works on a Case Sensitive basis, so the request will fail when it does not comply with uppercase and lowercase letters.
To fix this, we will configure as follows
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location ~* /demo[0-9] {
return 200 "Hello";
}
}
}
By adding the * symbol after the ~ symbol, we will help nginx understand that in this case we will not apply Case Sensitive.
Let's check again with the following example
curl -I http://nglearns.test/demo8
Result
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:15:04 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
Nginx prioritizes Regext Match over Prefix Match.
Refer to the example with the following config:
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location /Demo8 {
return 200 "prefix matched.\n";
}
location ~* /demo[0-9] {
return 200 "regex matched.\n";
}
}
}
We will test with the following code
curl -i http://nglearns.test/Demo8
Result
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Thu, 22 Apr 2021 08:08:18 GMT
# Content-Type: text/plain
# Content-Length: 15
# Connection: keep-alive
# regex matched.
In the example above, although we want to access the Prefix branch URL, the result returned is the Regex branch.
To change the priority, refer to the following example
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location ^~ /Agatha8 {
return 200 "prefix matched.\n";
}
location ~* /agatha[0-9] {
return 200 "regex matched.\n";
}
}
}
By adding the ^ symbol to the Prefix branch, we will set the priority of the Prefix higher.
Please test the following command
curl -i http://nglearns.test/Demo8
Result
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Thu, 22 Apr 2021 08:13:24 GMT
# Content-Type: text/plain
# Content-Length: 16
# Connection: keep-alive
# prefix matched.
In the above case, Prefix successfully received the request after prioritizing.
Here is a list of priority permissions for each type of request.
MATCH | MODIFIER |
---|---|
Exact | = |
Preferential Prefix | ^~ |
Regex | ~ or ~* |
Prefix | none |