La directiva de mapas de Nginx no coincide con las reglas

La directiva de mapas de Nginx no coincide con las reglas

Tengo este archivo de configuración de 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;
        }
    }
}

La directiva map no funciona en absoluto, simplemente adopta de forma predeterminada lo que esté definido de forma predeterminada.

Por ejemplo:

$ 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

/lolDebería haberse configurado $new_uricomo http://lol.comy $ret_codecomo 302, pero si observa los X-encabezados, solo toma los valores predeterminados especificados en el mapeo.

Hace una semana tuve funcionando esta misma configuración de nginx y no ha habido ningún cambio desde entonces. Tengo activadas las actualizaciones de seguridad automática de Ubuntu, pero no creo que nginx se haya actualizado. Correr v1.10.0. Realmente no puedo explicar por qué esto dejó de funcionar.

Editar: Acabo de probar esta misma configuración en un VPS diferente, la misma versión de nginx y funciona allí correctamente. ¿Cómo puedo solucionar esto ahora?

Respuesta1

Descubrí el problema. Tenía varios archivos de configuración de este tipo para cada dominio y, dado que el mapa está definido en el contexto http, el último sobrescribía el valor de las variables. Lo arreglé añadiendo el sufijo del nombre de la variable en cada archivo de configuración, para que las variables sean únicas:

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 es el ID de este dominio particular en mi sistema.

Respuesta2

He estado experimentando el mismo problema en Nginx 1.12.2: la directiva map no coincidía con ninguno de los patrones, ni siquiera los más simples y triviales como /, y siempre usaba el valor predeterminado.

Se descubrió que el problema se debía al uso de la $urivariable en el mapeo. Alguna configuración de Nginx estaba modificando implícitamente $urisu valor original anteponiendo /index.phpel prefijo, lo que provocó que el patrón no coincidiera. Tal comportamiento $uries por diseño y la distinción exacta entre$request_uriy $urivariables.

La solución fue reemplazar la variable URI en la configuración de Nginx:

map $uri $result_var {
    # ...
}

con lo siguiente:

map $request_uri $result_var {
    # ...
}

información relacionada