nginx location block not directing to location directory when using regex - regex

I have a location block that works when I am not using a regex.
location ^~ /mapdata/ {
alias /data/map/coordinates/;
}
When i visit http://localhost/mapdata/2002/g.txt I am getting the data from the file.
When I alter the location and use a regex. I can not read the file, the location block is correct. But the url gets an extra slash added on to the end http://localhost/mapdata/2002/g.txt changes to http://localhost/mapdata/2002/g.txt/
location ~ "^/mapdata/([\d]{4})/.*.txt$" {
alias /data/map/coordinates/;
}

alias inside a regular expression location requires the full path to the file to be captured. See the documentation for details.
For example:
location ~ "^/mapdata/([\d]{4}/.*\.txt)$" {
alias /data/map/coordinates/$1;
}

Related

Nginx regex to match single path

Suppose I have these paths:
/
/something # this path is variable (any characters except /)
/api/v1/something
What is the best nginx config to capture this requirement? The following is not working for m:
server {
listen 8080;
location ~^/(?:.*)$ {
...
}
location / {
...
}
location /api/v1/something {
...
}
}
Your regular expression matches everything which means it always wins! See the documentation to understand how Nginx chooses which location block to process a request.
You do not need to use a regular expression location.
First define location blocks for the single URIs using the = operator:
location = / { ... }
location = /api/v1/foo { ... }
Then use the default location to catch anything else:
location / { ... }
The above location blocks can appear in any order. Only regular expressions are sensitive to evaluation order.

How to extract the name of a request file only from a request?

How to extract only the name of file from a request?
I have URLs like these:
my_domain.com/dir1/image1.png
my_domain.com/dir1/image143.jpg
my_domain.com/dir1/image167658.gif
# [etc, images]
And these sections:
location / {
# [..........]
}
~ ^/dir1/.(jpg|png|gif) {
set $my_file_name $1;
# [...........]
}
1st issue: it won't trigger the 2nd section when I'm requesting one of the URLs mentioned above
If I change it to be:
/dir1 {
set $my_file_name $uri;
# [...........]
}
It'll trigger it, yes. However, in this case $my_file_name will contain the whole URL, whereas I need only the name of a file/image. For instance, image143.jpg
Question:
How should I change the section with /dir1 such that 1) it'll match the URLs from above and similar ones, and 2) I'll be able to extract a requested file or image name from a URL?
You need to use a regular expression with a capture.
For example:
location ~ ^/dir1/(?<filename>.*\.(jpg|png|gif))$ {
# do something with the $filename variable
}
See this document for details.

nginx location regex rule not working

We are trying to create a location rule on nginx side, but its not working as expected. Below is the location rule
location ~* ".*\.legalcontent\.html\?path=\/legal\/.*" {
return 200 'regex rule'; //Using this temporarily to confirm if rule is triggering
}
Incoming URL is below, want to capture (.legalcontent.html?path=/legal/)
https://www.mycompany.com/myapp/myproduct/mysubpage.legalcontent.html?path=/legal/somepage
Tested regex separately on regex tool, seems to be good
But its not working, tried simple context roots to check if everything else is good.
# Following simple rules works fine, but we want location to kick-in
# only for specific condition
location /myapp {
return 200 'myapp rule';
}
location /myapp/myproduct {
return 200 'myapp myproduct rule';
}
Is there a way to handle location rule for this kind of input URL
The location will only check the path of the request. To check the arguments you must create a conditional with the $args variable.
location ~* ".*\.legalcontent\.html$" {
if ($args ~* "^path=\/legal\/.*") {
return 200 'regex rule';
}
}

supporting deep-linking with location regex and try_files, can't redirect to foo/local/ to foo/index.html

I have a number of drop in GUIs that all under the general TTP subdomain and all allow deep-linking. Specifically the URL /TTP/app/site/ should load GUI named app with site's statistics. with /ttp/app loading the same GUI with the default site.
This should work by redirecting both /ttp/app and /ttp/app/site/ requests to the /usr/share/html/ttp/app/index.html page, that page will parse the remaining url and figure out which backed to hit if site is provided.
Currently I have something like this in my conf file (I'm utilizing the nested location for other things not included here):
location /ttp {
root /usr/share/nginx/html/ttp/;
location ~ ^/foo/ {
try_files $uri $uri/ /foo/index.html;
}
location ~ ^/bar/ {
try_files $uri $uri/ /bar/index.html;
}
... (one for each app)
}
This works, but is redundant. I'm trying to consolidate this with a regex which will cover all apps with a single location. I've tried a few variants, original having issue with greedy regex grabbing all /app/site/ instead of just /app/. My best attempt with non-greedy regex being
location /ttp {
index index.html
root /usr/share/nginx/html/ttp/
location ~ ^/((?U).*)/ {
try_files $uri /$1/index.html;
}
}
this give me an error about rewrite or internal redirection cycle while internally redirecting ti "/ttp/index.html" Which seems to imply it's not greedy enough and is completely ignoring app with $1 being a null string.
Is there some clean way to do this, with regex or some directive I'm not aware of?
Your example is flawed - I presume you over simplified it and we are missing the part that removes the /ttp prefix after it enters the outer location block.
You have a URI structure /ttp/foo/xxx and you would like the default action to be /ttp/foo/index.html where foo is the name of an app.
You can use non-greedy regular expression, but you may find the [^/] character class easier to use for matching individual path elements in the URI.
If the final element of a try_files statement needs a rewrite, use a named location. See this document for more.
For example:
location /ttp {
root /usr/share/nginx/html;
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^(/ttp/[^/]+)/ $1/index.html last;
return 404;
}
Any URI of the form /ttp/foo/xxx that takes the default action, will re-enter the location /ttp block with the URI as /ttp/foo/index.html. The root parameter is prefixed to the URI to form the local path.

Nginx location match regex not working

I am unable to match location with below mentioned pattern, I want to set expires header to 24 hrs. but it is not working. It works if I just use below mentioned regex :
location ~* .*abc\.php.* {
expires 24h;
}
Below example does not work.
location ~* .*abc\.php.*xyz=detail.*login_something=.* {
expires 24h;
}
There is lot of content in between and after of "abc.php" & "xyz=detail" & "login_something=" so I have to use .* only.
Thanks in advance!
There are multiple ways to achieve what you are trying to do, but the simplest method is to apply your mega regex to a variable that contains the entire URI (including the query string). This would be $request_uri
The second problem is how to manipulate expires and again, rather than use multiple blocks and have to reimplement PHP directives in each one, just use the map directive as detailed in the expires documentation.
For example:
map $request_uri $expires {
default off;
~*abc\.php.*xyz=detail.*login_something= 24h;
}
server {
...
expires $expires;
...
}