Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx $request_uri has duplicated query parameter

Tags:

nginx

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?

like image 753
ming.kernel Avatar asked Jan 22 '15 04:01

ming.kernel


2 Answers

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

See Documentation Here.

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.

like image 65
Dayo Avatar answered Nov 12 '22 06:11

Dayo


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;
  }
}
like image 42
Aleksey Deryagin Avatar answered Nov 12 '22 08:11

Aleksey Deryagin