Nginx config rewrite rule combination - .htaccess

So I have these 2 rules for url rewrites.
location ~ /details {
rewrite ^/details/(.*)/(.*)/(.*)/(.*)_(.*).html$ /site/$4.$5.html permanent;
rewrite ^/details/(.*)/(.*)/(.*)/(.*)_(.*)_(.*).html$ /site/$4.$5.$6.html permanent;
}
But for some reason the first one on its own works just fine but the second one will not pick up.
Is there a way I could combine these 2 rules into 1?
Thanks for any suggestions.

Try switching the order:
location ~ /details {
rewrite ^/details/(.*)/(.*)/(.*)/(.*)_(.*)_(.*).html$ /site/$4.$5.$6.html permanent;
rewrite ^/details/(.*)/(.*)/(.*)/(.*)_(.*).html$ /site/$4.$5.html permanent;
}
Because (.*) matches everything, it'll gobble up everything including _ characters, so your first regex matches everything the second one does and thus the second rule never gets reached.

Related

Nginx mapping with regex does not accept query string [duplicate]

I have this NGINX configuration:
root /var/www/web;
index index.php;
server_name domain.com;
access_log off;
error_log on;
location / {
rewrite ^/(.*)$ /index.php?tag=$1&page=1 last;
}
Now, I want to redirect url something like
"domain.com/index.php?tag=1&section=2&type=3" to "domain.com/tag/section/type"
how can I do that, where should I put the code? please help,
Thankyou
I already tried:
location / {
rewrite ^/index\.php?tag=(.*)&section=(.*)&type=(.*)$ /$1/$2/$3 permanent;
rewrite ^/(.*)$ /index.php?tag=$1&page=1 last;
}
but it didnt work..
The rewrite and location directives use a normalized URI which does not include the query string.
To test the query string, you will need to consult the $request_uri or $args variable using an if statement and/or map directive.
The advantage of using $request_uri is that it contains the original request and will help to avoid a redirection loop.
If you only have one redirection to perform, the map solution is probably overfill.
Try:
if ($request_uri ~ ^/index\.php\?tag=(.*)&section=(.*)&type=(.*)$) {
return 301 /$1/$2/$3;
}
location / {
...
}
See this caution on the use of if.

nginx regex redirect gives extra slash

I plan to convert this address:
www.somewebsite.com/news/22915
To this address:
www.somewebsite.com/news/22915.html
And this is how I do it in my nginx configuration:
rewrite ^/news/(\d+)$ /news/$1\.html redirect;
But somehow, nginx will rewrite my address to:
www.somewebsite.com/news/22915/.html
Had no idea why / will go into the variable automatically, since (\d+) should only be matching pure numbers, need help.
Use rewrite ^/news/(\d+)$ /news/$1.html redirect;
The second part of the rewrite syntax is not a regex. So you should not try to escape the dot character.

mod_rewrite for a 301 redirect. Not redirecting to proper location

I'm trying to use a RewriteRule (using ISAPI, NOT on an Apache server) to 301 redirect a url such as:
http://www.mydomain.com/news/story-title/
to
http://www.mydomain.com/news/detail/story-title/
What I've gotten so far is:
RewriteRule ^news/(?!detail)/?$ news/detail/$1/ [L,R=301]
which successfully ignores urls that already have the "detail" in them (in some of my first attempts I ended up with a loop and a url like "/news/detail/detail/detail..."), but visiting /news/story-title/ gives me a 404 so it's not redirecting to the proper location.
Change your rewrite rule to
RewriteRule ^news/(?!detail)([^/]+)/?$ news/detail/$1/ [L,R=301]
EDIT : (How it works?)
/(?!detail) is a negative lookahead but it's also non-capturing i.e. it matches / but not what comes after it; just makes sure that it isn't "detail". So, I added a capturing group ([^/]+) to capure those characters (one or more + of anything that's not a/) optionally ending with a /.
Hence, the $1 now gets replaced with the matched directory name.

Redirecting with htaccess using similar rules

I'm using .htaccess to rewrite my URLs and so far it's almost working as it should...
The problem I'm having is that mysite.com/author and mysite.com/author/submit/1 are both redirecting to the same page (mysite.com/author.)
These are the rewrite rules that I'm currently using:
RewriteRule ^author /zabjournal/pages/author/active_submissions.php [L]
RewriteRule ^author/submit/1 /zabjournal/pages/author/submit_step1.php [L]
How do I get the second rule to work?
This is because you have put the rules in the wrong order.
The first rule validates and executes because author is the first string in both URLs.
/author
/author/submit/1
/author/blah
/author/blah/blah/blah/blah/blah
The URLs above will all match the first rule, so, therefore, it will be executed.
The [L] (which stands for last) at the end of a rule means that it won't process other rules if that rule is executed.
But, if you change the order of your rewrite rules it will first check to see if the URL matches /author/submit/1 and, if it does, it will execute that rewrite and then stop; but if it doesn't, it will continue to the next rule, which, in your example, would be /author.

Remove parameters within nginx rewrite

I'm rewriting URLs in nginx after a relaunch. In the old site I had query parameters in the URL to filter stuff e.g.
http://www.example.com/mypage.php?type=4
The new page doesn't have these kind of parameters. I want to remove them and rewrite the URLs to the main page, so that I get:
http://www.example.com/mypage/
My rewrite rule in nginx is:
location ^~ /mypage.php {
rewrite ^/mypage.php$ http://www.example.com/mypage permanent;
}
But with this rule the parameter is still appended. I thought the $ would stop nginx from processing further values... any ideas? All other questions deal with how to add parameters - I just want to remove mine :)
Had a similar problem, after a lot of searching the answer presented itself in the rewrite docs.
If you specify a ? at the end of a rewrite then Nginx will drop the original $args (arguments)
So for your example, this would do the trick:
location ^~ /mypage.php {
rewrite ^/mypage.php$ http://www.example.com/mypage? permanent;
}
To drop a parameter from a URL, in this case coupon=xxx:
if ($query_string ~ "^(.*)coupon=(.*)$") {
rewrite ^(.*)$ $uri? permanent;
}
Note that this will drop all parameters if the
statement matches. $uri is the original request without parameters.
Try setting the $args variable to empty inside the location.
set $args '';
If you want to remove a specified parameter from url,
# in location directive:
if ($request_uri ~ "([^\?]*)\?(.*)unwanted=([^&]*)&?(.*)") {
set $original_path $1;
set $args1 $2;
set $unwanted $3;
set $args2 $4;
set $args "";
rewrite ^ "${original_path}?${args1}${args2}" permanent;
}
then visit your_site.com/a=1&unwanted=2&c=3
step1. server gives an 302 response, indicating the url is match.
step2. client re-send a request with the new url ( with the parameter removed)
If we append a ? to the end of the destination it will prevent the query from being appended to the destination. :)
Example
Source
Args
Destination
Keep the arg appended
rewrite ^/mypage.php$
arg=something
https://example.com/new-page/
Do not preserve the arg
rewrite ^/mypage.php$
arg=something
https://example.com/new-page/?

Resources