nginx - how to combine redirects? - nginx

In my nginx.conf file, I have something like this:
...
location ^~ /path1/ {
root /usr/local/html;
index path1.html;
}
location ^~ /path2/ {
root /usr/local/html;
index path2.html;
}
...
Is it possible to combine the two "redirects" into one by using wildcards, rewrites or something else?
If so, how can I do it?

Have you had a look at the nginx wiki? What you are after is the HttpRewriteModule
An example from said wiki that is pretty damn close to what you are after:
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}

Related

NGINX rewrite args without an IF?

I would like to rewrite legacy links using a query parameter type of URL to a new style of URL.
Ex.
example.com/page?id=1 -> example.com/page/1
example.com/otherpage?id=1 -> example.com/otherpage/1
Currently I have the following configuration using the evil if.
if ($args ~* "id=(.*)") {
set $w1 $1;
rewrite .* $scheme://$host/page/$w1? permanent;
}
Note: I am using CloudFront, and relying on the host header above.
If the above is in a server block, with no other location block - would this qualify as a non-evil use of if in NGINX config? Also, the above only supported /page/. Any better ideas for making that portion work for otherpage and other pages?
I have seen a few other ideas discussing using a map, but I'm not quite sure how to bring it all together? I was thinking something along the lines of:
map $args_id ?? {
default ?
??
}
...
server {
...
???
}
UPDATE:
Based on the Answer from #Ivan, this was my final solution:
server {
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;
# Handle legacy requests
if ($args ~* "id=(.*)") {
set $w1 $1;
rewrite ^ $scheme://$host$uri/$w1? permanent;
}
}
Your if construction isn't evil. You can use something like
rewrite ^ $scheme://$host$uri/$w1? permanent;
for any page. More complex example if you want to process both example.com/page?id=1 and example.com/page/?id=1:
map $uri $maybe_slash {
~/$ "";
default "/";
}
...
server {
...
rewrite ^ $scheme://$host$uri$maybe_slash$w1? permanent;
...
}

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

nginx proxy_pass url with GET params conditionally

I have a url http://foo.com/banana and I have another url http://foo.com/banana?a=1&b=2
I like that all /banana routes are handled by my local nginx, but I'd like any banana routes with GET params to be proxied to http://bar.com
so:
http://foo.com/banana -> http://foo.com/banana
http://foo.com/banana?a=1 -> (proxy) -> http://bar.com/banana?a=1
I should note this is not for production. I'm trying to redirect api calls to redirect to another server during development.
I've tried to do an 'if args' block but I can't do a proxy_pass in an if block.
I thought about doing a rewrite of:
http://foo.com/banana?a=1 -> http://foo.com/proxy?a=1
location /proxy {
proxy_pass http://bar.com;
}
But I don't have the right logic for above because bar.com is expecting the /banana route.
Any ideas?
Since this is not for production, you could stick with your original "if" solution. You only need to escape from the "if" block to be able to proxy_pass, which can be easily done with the traditional trick:
location /banana {
error_page 418 = #good_old_fallback;
if ($args) {
return 418;
}
}
location #good_old_fallback {
proxy_pass http://bar.com;
}
Your idea of using another location will also work, so if you prefer it better, you can go with something like this:
location /banana {
if ($args) {
rewrite ^/banana(.*)$ /proxy$1 last;
}
}
location /proxy {
internal;
rewrite ^/proxy(.*)$ /banana$1 break;
proxy_pass http://bar.com;
}

Rewrite nginx cut last location

I would like to rewrite the following URL http://example.net/bar/foo to http://example.net/bar.
Do you know how to do this ?
Use this :
location /bar {
rewrite ^/bar/(.*)/[^/]+$ /bar/$1;
}

nginx url rewrite rule

I have URL like this
http://domain/PROD_SHEP_PDF_Downloader/DownloadPdf?favorId=10100018565295&lang=ru
I want to rewrite this part PROD_SHEP_PDF_Downloader to this SHEP_PDF_Downloader so the result will be
http://domain/SHEP_PDF_Downloader/DownloadPdf?favorId=10100018565295&lang=ru
This rule doesn't work
location /PROD_SHEP_PDF_Downloader/ {
rewrite ^/PROD_SHEP_PDF_Downloader/(.*) SHEP_PDF_Downloader/$1 break;
proxy_pass http://localhost:85;
}
Docs say that if you just want to change the URI prefix, you can use this:
location /name/ {
proxy_pass http://127.0.0.1/remote/;
}

Resources