Replace string in query parameter in nginx - regex

Preset:
got a gallery script that is creating thumbnails like so:
GET /path/to/script/thumb.php?src=host.tld/path/to/file.jpg
Goal:
rewrite the hostname in src to a different name:
GET /path/to/script/thumb.php?src=newhost.tld/path/to/file.jpg
It's only the host that I need replaced, everything else should stay the same.
I've tried a couple of things but nothing produces the result that I want.
This is the code as it is now (not working):
location ~* thumb {
if ($args ~ "(src=http://host.tld:8080/)(.*)" ) {
set $params $2;
rewrite ^.*$ thumb.php?src=http://newhost.tld/$params? last;
}
}
also, host.tld could be just about anything so matching on host.tld literally is just a simplification for now.

Related

Regex to redirect two different URLs starting with the same string

Those are my two nginx rules :
rewrite ^(/v1/foobar)(.*)$ /final$2 permanent;
rewrite ^(/v1/foobar-tow)(.*)$ /final$2 permanent;
I expect that /v1/foobar-two/foo will use the second rule and then will redirect to /final/foo but I doesn't : since the URL starts with foobar, the first rule will be used and finally will redirect to final-two/foo : the concatenation of the first target and the difference between the first and second rule !
To solve the problem I've just inversed the rules, but I wonder if there is a better solution !
To sum up, this is what I'm looking for :
/v1/foobar -> /final
/v1/foobar/hello -> /final/hello
/v1/foobar-tow -> /final
/v1/foobar-tow/hola -> /final/hola
To avoid surprises with NGINX, and increase configuration scalability, you should, generally:
try to live without rewrite directive; as per NGINX author it simply appeared before location and in many cases you can now use location with capture groups in lieu of rewrite
design your regular expressions in the way that the order of matching is not important, if possible
use exact matching, where applicable
isolate regular expression locations under a prefixed one
Putting all things together:
location /v1/ {
location = /v1/foobar {
return 301 /final;
}
location ~ ^/v1/foobar/(\w+)$ {
return 301 /final/$1;
}
location = /v1/foobar-tow {
return 301 /final;
}
location ~ ^/v1/foobar-tow/(\w+)$ {
return 301 /final/$1;
}
}

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

What is the best way to handle Nginx rewrite with subdomains?

I need to parse out a subdomain and add it to end of the url, for example:
subdomain.mysite.com needs to rewrite to subdomain.mysite.com/subdomain
subdomain.mysite.com/login needs to rewrite to subdomain.mysite.com/subdomain/login
Trouble arises because I have a set of reserve words that I don't want to match, for example the various different environments.
dev-web.mywebsite.com should not map to mywebsite.com/dev-web
This is what I have so far... am struggling with the nginx syntax and regex in general.
if ($host ~ ^([^.]+)\.(.+)) {
set $subdomain $1;
}
if ($subdomain ~* ^(dev-web|uat-web)$) {
rewrite ^ $scheme://$host/$subdomain$request_uri permanent;
}
The various errors I get are too many redirects or it is just not redirecting at all.
ERR_TOO_MANY_REDIRECTS
subdomain.mysite.com/subdomain/subdomain/subdomain/subdomain...

nginx remove / rewrite GET Parameters for specific URL

I want to create a nginx localtion do to the following
Given URL:
example.com/foo/bar/123456?ItemID=123456&aid=0&bid=0
Task:
If both numbers are the same and aid and bid are zero, then rewreite the url to example.com/foo/bar/123456
My Try:
location ~ ^/foo/bar/(?<prid>\d+)\?ItemID=\1&aid=0&bid=0$ {
rewrite ^ /foo/bar/$prid? permanent;
}
But that doesn't work. ;)
Would be great if s.o. could give me a hint.
EDIT:
nginx seems not to match GET-Parameters by regex at all (in location line) so you have to use $args and check with if (which can be evil according to documentation).
This should work:
location ~ /foo/bar/(\d+) {
if ($arg_ItemID = $1) { set $check I; }
if ($arg_aid = 0) { set $check "${check}A"; }
if ($arg_bid = 0) { set $check "${check}B"; }
if ($check = IAB) {
rewrite ^ /foo/bar/$arg_ItemID? permanent;
} }
Explanation:
nginx doesn't include the parameters in the match for rewrite. You can access the parameters by name via $arg_name.
the set of if-statements is a work-around (described here), because nginx doesn't allow multiple conditions
the ? at the end of the replacement cuts off the arguments from the original request

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