Reputation: 3645
I found that nginx's $request_uri duplicate the query parameters.
To goal I want to achieve is to redirect any request of naked domain to www domain. Here is a sample configuration.
server {
listen 8080;
server_name localhost;
location / {
if ($http_host !~* "^www\.") {
rewrite (.*) http://www.$http_host$request_uri permanent;
}
}
}
The result I got is this:
curl -I http://127.0.0.1:8080/pp/\?a\=b
HTTP/1.1 301 Moved Permanently
Server: nginx/1.6.2
Date: Thu, 22 Jan 2015 04:07:39 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: http://www.127.0.0.1:8080/pp/?a=b?a=b
The query parameter is duplicated in the result; am I missing something here?
Upvotes: 10
Views: 8181
Reputation: 2675
if is evil (not always, but) so why not try return 301:
server {
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
server {
server_name www.example.com;
root /var/www;
location / {
index index.html;
}
}
Upvotes: 3
Reputation: 12775
The replication of the query parameters you see is an expected behaviour of Nginx. To change this, you need to add a trailing ?
to the rewrite as in:
server {
listen 8080;
server_name localhost;
location / {
if ($http_host !~* "^www\.") {
rewrite (.*) http://www.$http_host$request_uri? permanent;
}
}
}
If a replacement string includes the new request arguments, the previous request arguments are appended after them. If this is undesired, putting a question mark at the end of a replacement string avoids having them appended, for example:
rewrite ^/users/(.*)$ /show?user=$1? last;
However, the configuration given by Aleksey Deryagin is the better and more efficient option for your desired type of redirection because every request will be evaluated by if
block in your original configuration whether needed or not.
Upvotes: 15