How can I get a param using regex in a nginx server block? - regex

I'm trying to get a param(h=1500 for example) via regex in a server block in an nginx server but it's not working. My last try was this:
location ~ "^/app/events/(?<eventid>\d+)/(?<image>.+)?h=(?<height>\d+)$" { ...... }
Here you can check and it works: https://regex101.com/r/kP9eY9/1
But in my server block file it does't.
If I try something like this, it works:
location ~ "^/app/events/(?<eventid>\d+)/(?<image>.+)/(?<height>\d+)$" { ...... }
Instead a param like "h=300", I just use a "/300" and I can get the value in my server block file.
I'm not a expert using regex so I can't see if there is something wrong. I need your help guys! Thank you!

From the documentation:
locations of all types test only a URI part of request line without
arguments
which means the ? and anything that follows it.

As #Richard mentioned, you can't use request arguments in locations regexps.
If you need to work with request arguments in your nginx config you might use $arg_ and/or $args syntax:
http://nginx.org/en/docs/http/ngx_http_core_module.html#var_arg_
http://nginx.org/en/docs/http/ngx_http_core_module.html#var_args
I.e
location / {
if ($arg_param = 'someval') {
# some code here
}
}

Related

Nginx regular expression on map

Not an expert on regexs,
working on a nginx project, and we are looking for a way to map the first two (2) directories levels of a uri
map $uri $my_uri {
~^(?<base_uri>.*)/[^/]+$ $base_uri;
default $uri;
}
So far this code return the base_uri without the domain/server or any filenames
But I need this original request :
http://example.com/level1/level2/file.ext
http://example.com/level1/level2/level3/file.ext
http://example.com/level1/level2/level3/level4/[...more levels...]/file.ext
to return only the first 2 levels, regex should return
/level1/level2
Please note:
sub-folders (lavel1, lavel2) will be dynamic folder names, not static.
nginx's $url variable does not include protocol/server/port from the original request. so regex is performed against /level1/level2/level3/[...]/file.ext
any help will be appreciated.

fastcgi_cache_key exclude some args in request uri

My fastcgi_cache_key is:
fastcgi_cache_key "$host$request_method$request_uri";
My $request_uri has timestamp and signature in it:
/abc/xyz?product_id=10529125896&shop_id=17224077&shop=abc.com&path_prefix=%2Fa%2Fcomment&timestamp=1503044416&signature=882102c51c7b7bd4c5d8521a6565fc70c27b908547316f1123eb4af13b19f2da
So, the cache always MISS (because it has different timestamp and signature). My question is:
I want to create new var and use that var for fastcgi_cache_key. That var will has something like this:
myvar
/abc/xyz?product_id=10529125896&shop_id=17224077&shop=abc.com
fastcgi_cache_key will like this:
fastcgi_cache_key "$host$request_method$myvar";
How can I do that ? Thanks so much.
There are two ways to do it.
if ($request_uri ~ "([^\?]*)\?(.*)timestamp=([^&]*)&?(.*)") {
set $args $2$4;
}
fastcgi_cache_key "$host$request_method$args";
This will remove the timestamp. You can either modify the pattern to ignore one more field or you can use it twice to remove the field from $args.
Next option is to use openresty or Nginx with lua which allows you to execute Lua script in your code. if conditions are not considered good. But then having lua increases your software requirement

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;
...
}

Nginx url rewrite fine tuning

I'm having trouble fine tuning a regex for Nginx url rewrite rules, What I am trying to do is take the first two pieces of the url and convert them to variables (nothing too fancy, and should be simple).
e.g. I type in http://www.webserver.com/piece1/piece2 and get http://www.webserver.com/rewtest.php??val1=piece1&val2=piece2
So far I have:
location / {
rewrite ^/(.*)/(.*)/? /rewtest.php?val1=$1&val2=$2 last;
return 404;}
}
which does seem to work. The problem is if the user types http://www.webserver.com/piece1/piece2/ it gives val 1 as piece1/piece2 (as 1 variable, not 2).
Also if the user were to type http://www.webserver.com/piece1/ I currently get piece1 in var 1, which is great. BUT if the user types http://www.webserver.com/piece1 it gives me an error and I'd like to get the same (var 1=piece1).
Any help greatly appreciated as I am new to regexs!
Seems as if / is also recognized by "."...try:
location / {
rewrite ^/([^/]+)/([^/]+)/? /rewtest.php?val1=$1&val2=$2 last;
return 404;}
}

Setting content dispose based on url / nginx

Having nginx serving static files with url like http://foobar.tld/<random_dir>/<file_md5sum_as_filename> and I would like if I specify at the end of url ?f="filename.filetype" - nginx parse that query string at the end (if is specified) and prepares new content dispose matching specified arguments and without any dynamic backend that's like impossible.
or instance http://foobar.tld/<random_dir>/<file_md5sum_as_filename>?f="foobar.pdf"
Can something like this be done with nginx/lua module? Does any one have any useful example or has done anything similar?
Pure Nginx configuration
location / {
if ($arg_f) {
add_header Content-Disposition "attachment; filename=$arg_f";
}
}
This is indeed possible with nginx-lua; in particular, the header_filter_by_lua directive.
Something like the following ought to do the trick:
location / {
header_filter_by_lua '
local args = ngx.req.get_uri_args()
if not args.f then return end
ngx.header["Content-Disposition"] = "attachment; filename=" .. args.f
';
}