Nginx Remove Trailing Question Mark - nginx

I'm trying to make a rewrite rule in Nginx to remove trialing question mark (?) from urls but i can't get it right. I've done that for trailing slashes like this:
#redirect all trailing slash URL's to the respective non trailing slash
rewrite ^/(.*)/$ /$1 permanent;
so I figured the same would work just replacing the slash with the question mark:
rewrite ^/(.*)?$ /$1 permanent;
but that didn't work, but it occurred to me that the question mark has some significance in the regex so i tried escaping it:
rewrite ^/(.*)\?$ /$1 permanent;
but that didn't work either, I tried also removing the first slash:
rewrite ^(.*)\?$ $1 permanent;
but that was also a bust, and yes i did restart the server in between tests.
Here's what I am trying to do:
www.mysite.com? should redirect to wwww.mysite.com
www.mysite.com/some/path? should redirect to wwww.mysite.com/some/path
www.mysite.com?some=vars should remain unchanged.
www.mysite.com/some/path?some=vars should remain unchanged.
so basically only removing the question mark if there is no query string.
How can i accomplish that?
I've checked other answers but they seem to want to remove the query string entirely, I only want to remove in the case that there is only a question mark and no parameters.

The ? marks the start of the query string and is not part of the normalized URI used by the rewrite or location directives. So you cannot remove it using a rewrite statement.
You will need to look at the original request which is in the $request_uri variable.
For example:
if ($request_uri ~ ^(.*)\?$) { return 301 $1; }
See this caution on the use of if.

Related

Rewrite URLs with different domains and similar paths

I need to redirect all URLs formatted as http://www.example.org/dir/subdir/ to http://subdomain.example.org/subdir/. For example, http://www.example.org/dir/subdir/page would redirect to http://subdomain.example.org/subdir/page.
I tried rewrite ^(/dir/subdir.*) http://subdomain.example.org$1 permanent;, but this keeps the /dir/ part, which I want to omit.
Your rewrite rule is capturing the /dir/ part too.
Try this:
location /dir/subdir {
rewrite ^/dir(.*)$ http://subdomain.example.org$1 permanent;
}

Nginx remove trailing slash but not if query string is present

I'm trying to create a rewrite rule in Nginx to remove trailing slashes.
My rule so far is:
rewrite ^/(.*)/$ /$1;
I want to remove trailing slashes for all URL:s except those that has a query string directly after a trailing slash, how do you do that? I mean URLs that look like https://www.domain.tld/page/?query=xxx
When using rewrite, the query string is appended automatically
From http://wiki.nginx.org/HttpRewriteModule:
If in the line of replacement arguments are indicated, then the rest of the request arguments are appended to them. To avoid having them appended, place a question mark as the last character:
Just an FYI if you are using rewrite for a redirect it is not recommended but no one is going to stop you.
This rule removes trailing slash from url on both cases and worked fine for me; you can customize the the if logic by the way
location ~ (.*)/$ {
if ($query_string) {
return 301 $scheme://$host$1?$query_string;
}
return 301 $scheme://$host$1;
}

Different rewrite rule redirect same url

rewrite ^/old-url /new-url permanent;
rewrite ^/old-url/old-url-sub /new-url/new-url-sub permanent;
2 urls are (/old-url and old-url/old-url-sub) redirected to same url (/new-url)
What is the problem ?
The problem is that the regular expression ^/old-url matches /old-url and /old-url/old-url-sub and /old-url/anything-else.
So the first rewrite statement is invoked for both URIs.
If you want a regular expression to match the entire string only, you need to use an anchor at the front and the back of the pattern. As you know, the ^ anchors the front of the pattern, whereas $ anchors the back of the pattern.
Try:
rewrite ^/old-url$ /new-url permanent;
If you were trying to redirect /old-url/xxx to /new-url/xxx where xxx is anything, you would use a single rewrite statement with a capture:
rewrite ^/old-url(/.*)?$ /new-url$1 permanent;
See this useful resource on regular expressions.

Nginx rewrite anything after specific keyword

I want to rewrite all requests after "whois" keyword in url to whois.php in nginx but can't find suitable rules.
e.g. rewrite domain.com/whois.php/TEST.COM to whois.php?domain=TEST.COM.
There are a number of options available to you. One solution is:
location ~* ^/whois.php/ {
rewrite ^(/whois.php)/(.*)$ $1?domain=$2 last;
}
Place the location block above other regex locations that might match, as regex locations are executed on the basis of the first one that matches.
See this and this for more.

nginx rewrite rule exclude numbers

Need some help with Nginx write rule such that:
All urls of type:-
/1.1.1/xyz/abc/z.js
/2.2.2/xyz/def/c.css
are re-directed to
/xyz/abc/z.js
/xyz/def/c.css
Want to exclude the numeric part which comes at the beginning of URL.
location ~ ^/[0-9\.]+(/.*) {
try_files $1 $1/;
}
this will work
rewrite ^/(d+).(d+).(d+)/(.+)$ /$1;

Resources