TransWikia.com

Nginx map directive not matching rules

Server Fault Asked by Ashfame on November 24, 2021

I have this nginx config file:

map $request_uri $new_uri {
    default DEFAULT;
    /shell http://shell.com;
    /lol http://lol.com;
}
map $request_uri $ret_code {
    default 301;
    /shell 301;
    /lol 302;
}

server {
    listen 80;
    server_name TestDomain.com www.TestDomain.com;

    location / {
        add_header X-request_uri $request_uri;
        add_header X-new_uri $new_uri;
        add_header X-return_code $ret_code;
        if ($new_uri = "DEFAULT") {
            return 301 https://ashfame.com$request_uri;
        }
        if ($ret_code = 301) {
            return 301 $new_uri;
        }
        if ($ret_code = 302) {
            return 302 $new_uri;
        }
    }
}

The map directive is not working at all, just defaulting to whatever its defined for default.

For example:

$ curl -I testdomain.com/lol
HTTP/1.1 301 Moved Permanently
Server: nginx/1.10.0 (Ubuntu)
Date: Sun, 22 Jan 2017 20:04:06 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://ashfame.com/lol
X-request_uri: /lol
X-new_uri: DEFAULT
X-return_code: 301

/lol should have set $new_uri as http://lol.com and $ret_code as 302, but if you look at the X- headers, its just taking the default values specified in the mapping.

A week back I got this same nginx config working, and there hasn’t been any change since then. I do have ubuntu’s auto security upgrades on, but don’t think nginx was even updated. Running v1.10.0. Can’t really point out why this stopped working.

Edit: Just tested this same config on a different VPS, same nginx version and it works over there correctly. How do I even fix this now?

2 Answers

I've been experiencing the same issue on Nginx 1.12.2 -- map directive would not match any of the patterns, even the simplest and most trivial ones like /, and always used the default value.

The issue tuned out to be caused by the use of the $uri variable in the mapping. Some Nginx configuration was implicitly modifying the $uri from its original value by prepending /index.php prefix which caused the pattern mismatch. Such behavior of $uri is by design and the exact distinction between $request_uri and $uri variables.

The fix was to replace the URI variable in the Nginx config:

map $uri $result_var {
    # ...
}

with the following:

map $request_uri $result_var {
    # ...
}

Answered by Sergii Shymko on November 24, 2021

I figured out the issue. I had multiples of such config files for each domain and since map is defined in http context the last one was overwriting the value of variables. I fixed it by suffixing the variable name in each config file, so that variables are unique:

map $request_uri $new_uri_5 {
    default DEFAULT;
    /shell http://shell.com;
    /lol http://lol.com;
}
map $request_uri $ret_code_5 {
    default 301;
    /shell 301;
    /lol 302;
}

server {
    listen 80;
    server_name TestDomain.com www.TestDomain.com testdomain.com www.testdomain.com;

    location / {
        add_header X-request_uri $request_uri;
        add_header X-new_uri $new_uri_5;
        add_header X-return_code $ret_code_5;

        if ($new_uri_5 = "DEFAULT") {
            return 301 https://ashfame.com$request_uri;
        }
        if ($ret_code_5 = 301) {
            return 301 $new_uri_5;
        }
        if ($ret_code_5 = 302) {
            return 302 $new_uri_5;
        }
    }
}

5 is the ID of this particular domain in my system.

Answered by Ashfame on November 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP