nginx regexp and openresty - nginx

My nginx should match these requests:
/id/12345
/id/12345/qualifier
and /qualifier should be optional.
i want to use in a small lua openresty script the two matched groups (12345, qualifier) with ngx.var[]
i am trying with this location, but is not working for me.
how i can say that / and qualifier are optional?
location ~ ^/id/(\d+)(/?)(\w+?)$ {

^/id/(\d+)(?:/(\w+))?$
(?:) is a non-capturing group.

Related

NGINX - Setting a variable with regex replace

I'm looking to improve nginx caching by removing irrelevant query parameters (that could come from web crawlers or similar) from the request. I have come across an unwieldy solution on the internet:
set $c_uri $args; # e.g. "param1=true&param4=false"
# remove unwanted parameters one by one
if ($c_uri ~ (.*)(?:&|^)pd=[^&]*(.*)) { set $c_uri $1$2 ; }
if ($c_uri ~ (.*)(?:&|^)mid=[^&]*(.*)) { set $c_uri $1$2 ; }
if ($c_uri ~ (.*)(?:&|^)ml=[^&]*(.*)) { set $c_uri $1$2 ; }
if ($c_uri ~ (.*)(?:&|^)contact_eid=[^&]*(.*)) { set $c_uri $1$2 ; }
...
set $c_uri $scheme://$host$uri$c_uri;
...
location / {
# set $c_uri as cache_key
proxy_cache_key $c_uri;
...
}
It works, but it's not very concise, takes a lot of steps and from what I learned, if is evil.
I know there are maps, which can do basic regex things but they don't work in this scenario (because there can be any number of parameters in any order that I need to remove).
I also found this substitution module which can do regex replace but it's only made for specific operations and not for setting a variable.
So I have two questions:
Does anyone know whether there is some tooling to set a variable by doing a regex replace operation?
Is using if in this case really that bad? It's not inside a location context and I don't know whether many consecutive regexes are actually worse than one large regex replace.
I would be very thankful if someone with more nginx know-how could weigh in here and help me out. Thanks :)

Nginx : how to regrex on Nginx url wildcard?

I want to configure regular expression on location
example: /order-service/js/app.js or /order-service/js/xxxx/xxxxxx/app.js like this,
So order-service will be set proxy_pass://order-service/js/xxxx/xxxxxx/app.js
that means I will get 2 variables, one is order-service, and another is /js/xxxx/xxxx/app.js, so how can I write the URL wildcard?
location ~ ^/(order-service)(/js/.*) {}
or more specific:
location ~ ^/(order-service)(/js.*/app.js) {}

nginx wildcard subdomains to different roots

i want to support all level subdomains to "domain.com" for my configuration. That's possible with:
server_name "~^(?<sub>.+)\.domain\.com$";
My root looks like this:
set $subDirectory subdomains/$sub/;
set $root /var/www/domain.com/$subDirectory/www/;
root $root;
Example:
"abc.domain.com" will be /var/www/domain.com/subdomains/abc/www/
Now i want to support all level subdomains. For every sub i want to set in root between domain.com/HERE/www/ subdomains/$sub/. How can i do it?
"abc.domain.com" will be /var/www/domain.com/subdomains/abc/www/
"test.abc.domain.com" should be /var/www/domain.com/subdomains/abc/subdomains/test/www/
"hello.test.abc.domain.com" should be /var/www/domain.com/subdomains/abc/subdomains/test/subdomains/hello/www/
Currently "$sub" is for the last example hello.test.abc;.
Could i copy "$sub" to "$subRoot" and can replace all the points (.) on $subRoot with "/subdomains/"?
$subRoot looks then like "hello/subdomains/test/subdomains/abc"

nginx rewrite rules http://example.org/img?src=A to A?

My url format :
http://example.org/img?src=http://a.com/logo.png
I want nginx to rewrite this request to http://example.org/logo.png
(not url redriect)
how to do this?
The src argument is available as the $arg_src variable, however, you will need to use an if block to extract the part that you need. See this caution on using if.
For example (and you will need to adapt the regex to your specific needs):
location = /img {
if ($arg_src ~ \w(?<src>/\w.*)$) {
rewrite ^ $src last;
}
}
See nginx documentation here and a useful resource for regular expressions here.

nginx url rewrite with proxy pass example?

I need to know how do i do a proxy pass in nginx for certain url pattern only
i have written following but i am not sure whether its working as i wanted. What i wanted is
1. if the url matches '/member-chat' it needs to be redirected the proxy pass
2. anything else needs to be re-written as below
is what have written is correct ?
location ^/member-chat {
proxy_pass http://lxx.com:5280/http-bind;
}
location !/member-chat {
rewrite ^/files/([^/]+)/([^/]+)$ /_files/$1/$2;
rewrite ^/plugins/([^.]+) http://www.lxx.com:9090/plugins/$1;
}
if i do this as below
location / {
rewrite ^/files/([^/]+)/([^/]+)$ /_files/$1/$2;
rewrite ^/plugins/([^.]+) http://www.lxx.com:9090/plugins/$1;
}
i get a error
nginx: [emerg] duplicate location "/" in /var/www/vhosts/system/lxx.com
/conf/vhost_nginx.conf:4
nginx: configuration file /etc/nginx/nginx.conf test failed
Several issues:
Your location #1 location ^/member-chat is wrong
because ^ to match the beginning of the path only works with regular expression matching (location ~ or location ~* for case-sensitive/-insensitive expression matching).
Either do location /member-chat which will also match locations like /member-chatABCDE or /member-chat/xyz
or use location = /member-chat to only match /member-chat.
You can also use regular expressions like location ~ ^/member-chat (prefix-match) or location ~* ^/member-chat$ (exact match), but avoiding regular expressions in favor of prefix or even better exact matches is recommended
(regular expressions have much worse performance and are compared at the very last in the matching process).
Location #2 is just plain wrong because there is nothing like a not operator for location matching.
nginx will process locations in a certain order, e.g. it will start with exact matches (=), then check for prefix-matches (no modifier) and afterwards check for regular expressions (~ or ~*).
However, if a regular expression match is found, it will be favored over the prefix-match.
Conclusion
location = /member-chat {
# exact match
# proxy stuff for chat goes here
}
location /files {
# match files
}
location /plugin {
# match plugin
}
I really recommend you to read the nginx docs to prevent you from asking one question after another.
E.g. location matching is a complex topic but so far well covered by the docs already.

Resources