3

Some map kill my URI, I do not get why:

map $http_cookie $redir_scheme {
    default http;
    ~some=value https; # here is the SSL cookie
}
server {
    listen       8888;
    server_name  redir.*;

    expires -1;
    add_header Last-Modified "";

    location / {
        rewrite ^/(.*)$ $redir_scheme://example.com/$1 redirect;
    }
}

Curl give a redirect without URI:

$ curl -giH 'Host: redir.somedomain.com' 'localhost:8888/some/path/with/meaningful/data' -H 'Cookie: some=value'
(...)
Location: https://example.com/
(...)

But when I change the configuration to:

map $http_cookie $redir_scheme {
    default http;
    some=value https; # here is the SSL cookie
}
server {
    listen       8888;
    server_name  redir.*;

    expires -1;
    add_header Last-Modified "";

    location / {
        rewrite ^/(.*)$ $redir_scheme://example.com/$1 redirect;
    }
}

Curl gives a redirect with a URI:

$ curl -giH 'Host: redir.somedomain.com' 'localhost:8888/some/path/with/meaningful/data' -H 'Cookie: some=value'
(...)
Location: https://example.com/some/path/with/meaningful/data
(...)

I guess the first solution was really dumb, but I can't see why. Do you have any light?

3

This happens because $1 comes from the last regular expression executed. As map{} is checked later than the regular expression in rewrite, the $1 comes from the regular expression specified in the map (and it's empty). There is a ticket 564 in nginx trac about this - while the behaviour is formally correct, it's clearly counter-intuitive and needs to be changed.

As a workaround you can use named captures instead:

rewrite ^/(?<rest>.*)$ $redir_scheme://example.com/$rest redirect;

Or, better yet, just use return with $request_uri instead:

return 302 $redir_scheme://example.com$request_uri;
1
  • wow, that's unexpected. Thanks a lot for this thorough explanation. – brisssou Dec 11 '14 at 21:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.