Nginx Rewrite Regex - nginx

I'm newbie on Nginx Regex and i want just to create a rewrite rule of a link
Example :
http://www.mywebsite.com/category/new --> http://www.mywebsite.com/category/new-new
AND
http://www.mywebsite.com/category/new/men --> http://www.mywebsite.com/category/new-new/men
I tried this
location ~ ^/category/new/?$ {
return 301 /category/new-new$is_args$args;
}
Thank you for help.

Your example does not establish a clear pattern, so, the best solution cannot be devised without knowing the full picture.
For example, if it's a list of random mappings between the source and a destination, then the best approach would be to use the map directive, see http://nginx.org/r/map.
Otherwise, if your intention is to rewrite any /category/new/ to /category/new-new/, then the following could be used:
location = /category/new {
return 302 /category/new-new;
}
location /category/new/
rewrite ^/category/new/(.*)$ /category/new-new/$1 redirect;
return 403;
}

Related

how to create an nginx rewrite to add / to url

I'm trying to create an nginx rewrite that will rewrite /pagename to /pagename/
I've tried using:
location ~ "^/test$" {
rewrite /test /test/ break;
}
but that doesn't seem to work...
any help would be appreciated.
The first parameter of a rewrite statement is a regular expression, and the flag you should use is probably permanent (see this document for details), for example:
location ~ "^/test$" {
rewrite ^(/test)$ $1/ permanent;
}
But you do not need to match the regular expression twice, once in the location and again in the rewrite, so a return would be more efficient, for example:
location ~ "^(/test)$" {
return 301 $1/$is_args$args;
}
Also, the location matches a single URI, to the = operator would be better than a regular expression (see this document for details). So the preferred solution is:
location = /test {
return 301 $uri/$is_args$args;
}
I ended up using return:
return 301 /test/;

Nginx location block with if but where is the else?

Need to redirect a url with variable to another domain name. The following code works when it matches but fails when it does not match.
For example it works when the request is https://old.example.com/test/place?id=2
Fails when the request is for https://old.example.com/test/place?id=1
Need https://old.example.com/test/place?id=1 to just pass through and only catch id=2.
What is missing in the configuration? What did I miss?
location = /test/place {
if ($request_uri ~ ^/test/place\?id=2) {
return 301 https://new.example.com/test/place?id=2;
}
}
Found the solution with the help from the nginx mailing list member, Patrick. Here is the link to the conversation.
The mailing list link to the solution
The final solution is as follows.
if ( $request_uri = "/test/place?id=2" ) {
rewrite ^ https://new.example.com${uri}?${args}? last;
}

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

Return with changing number in source url

When user visits:
/profile.php?mode=viewprofile&u=[NUMBER FROM 1 TO 4000]
I want nginx to return:
/memberlist.php?mode=viewprofile&u=[SAME NUMBER]
How can I do it? Thank you for help.
The problem is that you need to match /profile.php and mode=viewprofile which is not trivial nginx. There are a number of ways to achieve it.
You could replicate the location ~\.php$ block and add the conditional redirection there:
location = /profile.php {
if ($arg_mode = viewprofile) {
return 301 /memberlist.php?$args;
}
... # add location ~\.php$ stuff here
}
Alternatively, check the $request_uri (which contains the original URI including query string), early in the server block:
if ($request_uri ~ "^/profile\.php\?mode=viewprofile&") {
return 301 /memberlist.php?$args;
}
See this caution on the use of the if statement.

Rewrite Rule in Nginx to Block a Specific URL

I would like to block a specific URL from being access and return a 444 Error.
Example:
if ( $request_uri ~ https://subdomain.domain.com/abc/xyzdirector/login.do ) {
return 444;
}
Now this works fine, the issue is if I type the following URL in my browser and change ANY of the capitalization in the sub-directories, it does not work:
Example:
https://subdomain.domain.com/ABC/xyzdirector/login.d
https://subdomain.domain.com/abc/XYZdirector/login.d
https://subdomain.domain.com/abc/xyzdirecTOR/login.d
https://subdomain.domain.com/Abc/XyzDirector/login.d
When I do this, the url gets forwarded and servered.
How do I block this?
You want a case-insensitive regex location:
location ~* ^/abc/xyzdirector/login\.do$ {
return 444;
}
If you have any other regex locations in your config, make sure you put this one above any others that may match this url.

Resources