Nginx rewrite rule for query string - nginx

I am looking for a Nginx rewrite rule to rewrite (handling relative paths) e.g.
domain.com/en/?var1=val1&var2=val2
to
domain.com/?var1=val1&var2=val2
Which is not simply removing the language code 'en' from the URL, because there are other pages like:
domain.com/en/page1
which should not be rewritten to
domain.com/page1
So only removing when there is a query string in the URL. I have already tried:
rewrite ^/en/?s=(.*) /$args

Related

nginx rewrite preserving CGI query params (with a hash anchor)

For my www.example.com nginx config, I have these rewrite rules:
rewrite ^/foo$ https://one.example.com/page#one permanent;
rewrite ^/foo(\?.*)$ https://two.example.com/page$1#two permanent;
rewrite ^/bar$ https://three.example.com/page#one permanent;
rewrite ^/bar\?(.*)$ https://four.example.com/page?$1#two permanent;
A request for http://www.example.com/foo correctly redirects to https://one.example.com/page#one.
A request for http://www.example.com/bar correctly redirects to https://three.example.com/page#one.
A request for http://www.example.com/foo?extra=yes incorrectly redirects to https://one.example.com/page#one?extra=yes (I expect it to go to https://two.example.com/page?extra=yes#two).
A request for http://www.example.com/bar?extra=yes incorrectly redirects to https://three.example.com/page#one?extra=yes (I expect it to go to https://four.example.com/page?extra=yes#two).
How can I redirect to a page copying CGI parameters and linking to a particular anchor in the destination page?
It appears that the rewrite directive does not handle the # fragment correctly when assembling the query string into the replacement string.
You can prevent rewrite from appending the query string by adding a trailing ? to the replacement string. So, you can construct the correct result using the built-in variables $is_args and $args.
For example:
rewrite ^/foo$ https://one.example.com/page$is_args$args#one? permanent;
See this document for details.
Note that the query string is not part of the normalised URI used to match rewrite and location statements, so your ^/foo(\?.*)$ regular expression will not work.

Rewrite Nginx URLs with Parameters (After a Question Mark)

I have URLS in this format:
/wiki/index.php?title=Widget
/wiki/index.php?title=Blue
/wiki/index.php?title=Red
/wiki/index.php?title=Etc
I want to be able to match any URL that has the pattern "/wiki/index.php?title=" or even just "/wiki/index.php" (but so it will pick up the above URLs with the "?") and then redirect them to simply /wiki/ (all pages that match the above pattern go to the single url /wiki/)
I used to have a Mediawiki install on the /wiki/ directory with a lot of pages in the format above. However now I am running a Wordpress install and it is using the /wiki/ directory. I don't need each rewritten URL to go to a different URL (I know that is difficult as my source URLs have parameters) but right now they all 404 and so I just want to direct to them /wiki/ at least.
Simple URL rewriting
The easiest case (rewrite all /wiki/index.php requests with any arguments) can be done by this config (inside your server block):
location = /wiki/index.php {
rewrite .* /wiki/?;
}
The '?' sign at the end of second rewrite parameter is a trick to completely remove any request arguments. Without it, request /wiki/index.php?title=Widget will be rewrited to /wiki/?title=Widget.
Rewriting only requests matching /wiki/index.php?title=... is a more complex, I don't know how to do it without if construction:
location = /wiki/index.php {
if ($request_uri ~ ^/wiki/index\.php\?title=) {
rewrite .* /wiki/?;
}
}
If you want to generate HTTP 301 or 302 redirect instead of simple URL rewriting, you can use redirect (for 301 temporary redirect) or permanent (for 302 permanent redirect) flag at the end of rewrite directive parameters (see documentation).
Rewriting URLs to individual pages
This task is not as difficult as it seems. For redirecting /wiki/index.php?title=Widget to /wiki/Widget, /wiki/index.php?title=Blue to /wiki/Blue etc. we can make use of map directive:
map $request_uri $uri_suffix {
~^/wiki/index\.php\?title=([^&]*) $1;
}
server {
...
location = /wiki/index.php {
rewrite .* /wiki/$uri_suffix?;
}
...
}
Please note that map directive must be declared outside your server configuration block!

How to rewrite path to url with semicolon in nginx?

I am using nginx as a reverse proxy, a Angular Universal application is serving in the background.
I am trying to rewrite an old URL pattern to a new one via nginx, namely
server {
rewrite ^/s/(.+)$ /search\;q=$1 permanent;`
...
}
such that something like /s/keywords gets redirected to /search;q=keywords
Unfortunately, the above nginx rule turns
/s/keywords into /search/;q=keywords (so a slash gets added after /search). Is there a chance to remove this slash so the result is /search;q=keywords?
(The application running behind nginx expects the url to be /search;q=keywords.)
You could add quotes to the replacement, for example:
rewrite ^/s/(.+)$ "/search;q=$1" permanent;

Write a url path parameter to a query string parameter in nginx

I'm trying to rewrite a place name from a url path into a query string on nginx.
I want ourdomain.com/hotels/london?some_key=value to become ourdomain.com?d=london&some_key=value
We were doing it with Apache -
RewriteRule ^hotels/([^/]+)/?\??(.*)$ ?d=$1&$2 [QSA]
And we're currently doing on haProxy (acting as a reverse proxy) -
reqrep ^([^\ :]*)\ /hotels/([^/\ \?]+)/?\??([^\ ]*)(.*)$ \1\ /?d=\2&\3\4
How do I do the same thing on nginx?
Try something like:
rewrite ^/hotels/([^/]+)/?$ /?d=$1 permanent;
The nginx URI always has a leading /. The ? and query string is not part of the normalised URI, but the rewrite directive appends any arguments automatically unless there is a trailing ?.
See this document for details.

Nginx: redirect regardless of the url structure

I recently moved a subdomain to my main domain but I also changed the url structure.
Previously I had pages like http://sub.domain.com/companies/my-company-id/year/2012/charts
When moving to the main domain, I removed all the complicated urls to juts get:
http://www.domain.com/companies/my-company
I currently have the following rule:
rewrite ^/companies/(.*)$ http://www.domain.com/companies/$1 permanent; but when someone go on a page like http://sub.domain.com/companies/my-company/2012/charts they get redirect to http://www,.domain.com/companies/my-company/2012/charts and get a 404.
I like to force a redirection to http://www,.domain.com/companies/my-company-id regardless of what's after the my-company-id
Currently the parameter $1 is having the entire URI after /companies, so you are getting redirected to the original path. You should only extract the company-id in $1.
Use this:
rewrite ^/companies/(.*)/(.*)$ http://www.domain.com/companies/$1 permanent;
Here the rest of the URI after company-id will be available in the parameter $2, which is not needed in the rewrite condition.

Resources