nginx rewrite not working - returning 404 - nginx

I'm trying to rewrite :
http://example/test/ -> http://example/new/
http://example/test/check -> http://example/new/check
location ~/test/(.*)$ {
rewrite ^/new/$1?$args permanent;
}
What am I doing wrong?

Your rewrite statement is incorrect. See this document for more.
To use rewrite to capture the latter part of the URI, try:
rewrite ^/test/(.*)$ /new/$1 permanent;
Alternatively, to use location to capture the latter part of the URI, try:
location ~ ^/test/(.*)$ {
return 301 /new/$1?$args;
}

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

How to group different rewrite rules in nginx?

I would like to have a lighter code for one of my NGINX configurations. I need to write the following four lines in only one (if possible!):
location /en/contact {
rewrite ^/.* https://$server_name/contact permanent;
}
location /en/quality {
rewrite ^/.* https://$server_name/quality permanent;
location /de/contact {
rewrite ^/.* https://$server_name/contact permanent;
}
location /de/quality {
rewrite ^/.* https://$server_name/quality permanent;
}
Thanks!
Using minimal typing, you could use a rewrite statement outside of any location block:
rewrite ^/(en|de)/(contact|quality) https://$server_name/$2 permanent;
If the scheme and server name does not change, the second parameter can be replaced with just /$2. See this document for more.
Alternatively, you could use a regular expression location block:
location ~ ^/(en|de)/(contact|quality) {
return 301 https://$server_name/$2;
}
Same as above, regarding the scheme and server name. Note that the evaluation order for regular expression location blocks is significant - the first rule that matches wins. See this document for more.

How to write this nginx rewrite rule

I have a nginx rewrite rule like this
location ~* /question\-(.*)\.html$ {
rewrite "^/question-([0-9]+).html$" "/question/$1.html";
rewrite "^/question-([0-9]+).html$" /question.php?id=$1&lm=&pn= break;
}
This rule mean is:
if URI is /question-123456.html so rewrite to /question/123456.html
/question/123456.html is static file, and via question.php to create.
So when I visit http://example.com/question-123456.html HTTP rewrite to http://example.com/question/123456.html if not exist, I want to execute next rewrite rewrite "^/question-([0-9]+).html$" /question.php?id=$1&lm=&pn= break;
Other than return 404 to user.
I would write it this way:
location ~ /question-(.*)\.html$ {
try_files /question/$1.html /question.php?id=$1;
}

If Is Evil - Nginx

I'm using Nginx 1.6.2. I read that if () is evil and it's not good using it so I need a bit help, because I can't do what I want without using if(). I will post the rules I have with if and would ask if somebody could help me and tell me how to not use if () and use something else and get the same result.
# REDIRECT NON-WWW TO WWW.
if ($http_host != "www.site.eu") {
rewrite ^ http://www.site.eu$request_uri permanent;
}
# REMOVE INDEX FILES FROM URL FOR SEO PURPOSE.
if ($request_uri ~ "/index.php") {
rewrite ^ /$1 permanent;
}
# REMOVE ANY MULTIPLE SLASHES IN THE URL.
if ($request_uri ~* "\/\/") {
rewrite ^/(.*) $scheme://$host/$1 permanent;
}
First rule should be replaced with separate server blocks
server {
listen 80 default_server;
return 301 http://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
# normal config
}
Other ifs usually are not necessary. Just don't generate links with index.php and you will not need to strip it.
In the official wiki introduction it says that there are some cases which are ok. Have a look at this quote:
The only 100% safe things which may be done inside if in location
context are:
return ...; rewrite ... last;
At the end of the introduction there is an example which also features a rewrite command. So your code looks ok, too.
EDIT: You should also have a look at how the if works.
You can replace this block
# REMOVE INDEX FILES FROM URL FOR SEO PURPOSE.
if ($request_uri ~ "/index.php") {
rewrite ^ /$1 permanent;
}
with this
location ~ ^/index.php/(.*[^/])$ { return 301 $scheme://$host/$1/$is_args$args; }
location ~ ^/index.php/(.*)/$ { return 301 $scheme://$host/$1/$is_args$args; }
I also don't think you need to worry about the last rule for double // because nginx by default automatically takes care of that before it even gets to the point of matching location blocks

how do I rewrite a URL in nginx to an updated location?

I have the following URLs:
1) http://example.com/downloads/
2) http://example.com/downloads/widgets
3) http://example.com/downloads/gadgets
These URLs need to be redirected rewritten to the following:
1) http://example.com/products/
2 & 3 & etc) http://example.com/products/thingies
I'm currently trying the following nginx code:
location ~* ^/downloads/ {
rewrite ^/downloads/$ /products break;
rewrite ^/downloads/(.*)$ /products/thingies break;
}
It's almost working, however my site's document root is /var/www/example.com/public. So after processing the rewrite rules, nginx tries to literally serve /var/www/example.com/public/products/, whereas I want it to just rewrite to http://example.com/products/ (which then proxies to PHP and so on).
Where am I failing? Is there a different, better way to accomplish this?
Thank you for any help.
-- UPDATE --
I got it to work by using the following rules:
rewrite ^/downloads/?$ $scheme://$host/tools last;
location ~* ^/downloads/ {
rewrite ^/downloads/?$ $scheme://$host/products last;
rewrite ^/downloads/(.*)$ $scheme://$host/products/thingies last;
}
IS this the proper way of doing it in nginx? I haven't seen this rewrite rule format anywhere while researching this. It somehow seems odd.
Your update redirects, not rewrites.
Here is how I would do:
location /downloads/ {
rewrite ^ /products/thingies;
}
location = /downloads/ {
rewrite ^ /products/;
}
# uncomment if you need '/downloads' (without trailing slash) act as '/downloads/'
#location = /downloads {
# rewrite ^ /products/;
#}
The correct syntax appears to be:
location ~* ^/downloads/ {
rewrite ^/downloads/?$ /products permanent;
rewrite ^/downloads/(.*)$ /products/thingies permanent;
}

Resources