About priority of nginx location / {} and location = {} - nginx

When I study about the nginx location configuration, I have some questions.Here is my example.
the files structure is like this:
test1/index.html
test2/index.html
and the nginx.conf location part is like below:
location = / {
root test1;
index index.html;
# deny all;
}
location / {
root test2;
index index.html;
}
the question is , when i issue curl -v http://host/, I get the page of test2/index.html , but when I get rid of the # in the location = / {} part,
the result will be 403 forbidden. can anyone explain why ? when both the location = same_uri {A} and location same_uri {B} are in the configuration file,which configuration will match[A or B]? Thank you very much.
http://nginx.org/en/docs/http/ngx_http_core_module.html#location

When you request the URI /, nginx will process two requests.
The first request (for the URI /) is processed by the location = / block, because that has highest precedence. The function of that block is to change the request to /index.html and restart the search for a matching location block.
The second request (for the URI /index.html) is processed by the location / block, because that matches any URI that does not match a more specific location.
So the final response comes from the second location block, but both blocks are involved in evaluating access.
See this document for location syntax and this document on the index directive.

Related

How to match nginx location with keyWord in the middle of URI

Can location directive resolve the incoming requests not at the beginning, but anywhere in the middle of the URI.
for example i have to match location based on environment.
location /uat/ {.....}
location /sit/ {.....}
The request coming in would be /abc/customer/uat/ide
How to make a match when the environment name is not in the beginning of the URI.
Thanks in advance.
You can have something like this
server {
listen ...;
server_name _;
location ~* .*/sit/.*$ {
...
}
location ~* .*/uat/.* {
...
}
}
Breakdown of regex ~* .*/uat/.*:
~* -> Makes the matching case insensitive
.* -> Any character any number of times
/uat/ -> Match /uat/
.* -> Any character any number of times

nginx regex location

we need to serve the static content through nginx. below is our location directive:
location ~ /app$ {
root /srv/deployments/app/build/;
index index.html;
}
now we are expecting any thing like /app/login,/app/signup will be served by this location directive. but when we try to access /app/login we 404 error. and in addition to above location directive if we define below location directive, then it work.
location ~ /app/login$ {
root /srv/deployments/app/build/;
index index.html;
}
as there can be multiple routes, how can we define a location directive with regex so that any which match /app/.* should served by single location.
Please check if this link helps.
It suggests (specific to that question)
location ~ ^/sitename/[0-9a-z]+/index.php$ {
fastcgi_pass phpcgi;
}
where:
^ -> Start of string
[0-9a-z]+ -> matches all the characters in this range
index.php$ -> end of string with index.php

nginx server: how to remove first directory from URL

Can anybody please help me to remove first directory name from URL?
My Image location is _data/hotel/3/15377/hotel_image.jpg
But Image path gets changed due to relative URL in code and it become to something like this.
example.com/france/_data/hotel/3/15377/hotel_image.jpg
example.com/usa/_data/hotel/3/15377/hotel_image.jpg
example.com/india/_data/hotel/3/15377/hotel_image.jpg
is their any possibilities to remove dynamic country name from above URL
If you want to rewrite only this particular URL, you can use this location block in your config:
location ~ /[a-z]+/_data/hotel/3/15377/hotel_image.jpg {
try_files /_data/hotel/3/15377/hotel_image.jpg;
}
If you want to rewrite all URLs which lead to /<country>/_data/..., you can use:
location ~ /[a-z]+/_data/(.+) {
try_files /_data/$1;
}
or for stricter URL checking:
location ~ /(?:france|usa|india)/_data/(.+) {
try_files /_data/$1;
}
#Ivan Shatsky's answer is great for files but also if we want to redirect a general url is better if you use the rewrite directive.
Depending where you define the rewrite directive you have two ways to implement it:
A. In the server context
server {
...
rewrite ^/[a-z]+/_data/(.+)$ /_data/$1 last;
...
}
B. In the location context
location ~ /[a-z]+/_data/(.+) {
rewrite ^/[a-z]+/_data/(.+)$ /_data/$1 break;
proxy_pass http://backend;
}
Teo, why did you change the flag to break?* Because, if this directive is put inside of a location context, the last flag might make nginx to run 10 cycles and return the 500 error.
Note:
Remember not add / at the end of the proxy_pass directive. This example wont work:
...
proxy_pass http://backend/;
...

How to set the proxy_pass to get the desired address?

I have been struggling with setting up Nginx for our use case.
When I set up Nginx with the following config:
location /dep-core {
proxy_pass http://node-server:7070/;
}
and call the server with following endpoint:
<END-POINT>/dep-core/api/login
the call is redirected to
<ADDRESS-AFTER-RESOLUTION>//api/login
with two leading //s.
and when I remove the trailing / in proxy_pass after 7070:
location /dep-core {
proxy_pass http://node-server:7070;
}
the call is redirected to
<ADDRESS-AFTER-RESOLUTION>/dep-core/api/login
with leading /dep-core appended.
I want my call to redirect my call to:
<ADDRESS-AFTER-RESOLUTION>/api/login
What would be the standard way to achieve this??
For correct translation from /dep-core/foo to /foo, the location directive requires a trailing /.
For example:
location /dep-core/ {
proxy_pass http://node-server:7070/;
}
See this document for details.
To translate /dep-core to /, you can use a rewrite...break with a clever regular expression in the second block of your question. But a simple solution is to add an exact match location for that single edge case.
For example:
location = /dep-core {
rewrite ^ $uri/ last;
}
location /dep-core/ {
proxy_pass http://node-server:7070/;
}

How can I serve a particular file for root url in Nginx?

I need to serve file from my filesystem for GET / request. I tried the following:
location = / {
index page2257160.html;
root /var/www/site/;
}
The rest of requests are proxied to backend:
location / {
proxy_pass http://localhost:1234;
}
But when I do the request, instead of serving the file from filesystem, nginx asks backend about /page2257160.html, backend returns 404, nginx sends this 404 back to client.
How can I fix this?
The index directive performs an internal redirect, so you will need a second location to match the rewritten URI. For example:
root /var/www/site/;
location = / {
index page2257160.html;
}
location = /page2257160.html {
}
See this document for details.
You can achieve the same thing with one location block and a try_files directive. For example:
location = / {
root /var/www/site/;
try_files /page2257160.html =404;
}
See this document for more.

Resources