Директива Nginx map не соответствует правилам

Директива Nginx map не соответствует правилам

У меня есть такой файл конфигурации nginx:

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

Директива map вообще не работает, а просто по умолчанию принимает то, что определено в ней по умолчанию.

Например:

$ 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следовало бы установить $new_uriкак http://lol.comи $ret_codeкак 302, но если посмотреть на X-заголовки, то они просто принимают значения по умолчанию, указанные в сопоставлении.

Неделю назад я заставил работать эту же конфигурацию nginx, и с тех пор никаких изменений не было. У меня включены автоматические обновления безопасности Ubuntu, но не думаю, что nginx вообще обновлялся. Запускается v1.10.0. Не могу точно сказать, почему это перестало работать.

Редактировать: Только что проверил эту же конфигурацию на другом VPS, той же версии nginx, и там все работает правильно. Как мне теперь это исправить?

решение1

Я разобрался с проблемой. У меня было несколько таких файлов конфигурации для каждого домена, и поскольку map определен в контексте http, последний перезаписывал значение переменных. Я исправил это, добавив суффикс к имени переменной в каждом файле конфигурации, чтобы переменные были уникальными:

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 — это идентификатор этого конкретного домена в моей системе.

решение2

Я столкнулся с той же проблемой в Nginx 1.12.2 — директива map не соответствовала ни одному из шаблонов, даже самым простым и тривиальным, таким как /, и всегда использовала значение по умолчанию.

Проблема была вызвана использованием переменной $uriв отображении. Некоторые конфигурации Nginx неявно изменяли $uriисходное значение, добавляя /index.phpпрефикс, что приводило к несоответствию шаблона. Такое поведение $uriявляется намеренным и точное различие между$request_uriи $uriпеременные.

Исправление заключалось в замене переменной URI в конфигурации Nginx:

map $uri $result_var {
    # ...
}

со следующим:

map $request_uri $result_var {
    # ...
}

Связанный контент