NGINX: map y try_files no funcionan

Oct 08 2020

estoy usando nginx para detectar la compatibilidad con webp en el navegador:

# Check if client is capable of handling webp
map $http_accept $webp_suffix {
       default "";
       "~*webp" ".webp";
}

este código funciona bien y asigna .webp a $ webp_suffix cuando el cliente soporta image / webp

luego, unas líneas más tarde, estoy usando esta variable en la siguiente configuración:

        location ~ ^/imgs/([0-9]*)/(.*?)(\..+)$ {
                add_header X-webp $webp_suffix; try_files /imgs/$1$webp_suffix /imgs/$1$3 =404;
        }

y SIEMPRE da como resultado e404 incluso si ambos archivos existen. El encabezado X-webp está configurado en ".webp", por lo que el mapa funciona bien.

Lo que es más extraño, si cambio el orden de los argumentos try_files de:

try_files /imgs/$1$webp_suffix /imgs/$1$3 =404;

a

try_files /imgs/$1$3 /imgs/$1$webp_suffix =404;

luego funcionó y envió el archivo / imgs / $ 1 $ 3 al navegador. Como es posible ? ¿Me estoy perdiendo algo en esta lógica?

EDIT1: Complete nginx.conf para reproducir:

events {
    use           epoll;
    worker_connections  128;
}

http {

    # Check if client is capable of handling webp
    map $http_accept $webp_suffix { default ""; "~*webp" ".webp"; } server { listen *:8888; server_name test; root /srv; location ~ ^/imgs/([0-9]*)/(.*?)(\..+)$ {
                    add_header X-webp $webp_suffix; try_files /imgs/$1$webp_suffix /imgs/$1$3 =404;
            }

    }
}

EDIT2: ¿Qué es aún más extraño? Si cambio:

try_files /imgs/$1$webp_suffix /imgs/$1$3 =404;

a:

try_files /imgs/$1.webp /imgs/$1$3 =404;

entonces try_files funciona como se esperaba (pero no estamos verificando el soporte webp en el cliente ahora, simplemente asumiendo que lo admite). Por favor recuerde que:

add_header X-webp $webp_suffix;

en la misma ubicación da como resultado un encabezado agregado: X-webp .webp

entonces por qué / imgs / $ 1$webp_suffix does not work and /imgs/$1.webp funciona?

Lo que he probado:

  1. $ webp_suffix = ".webp" (probado y funciona)
  2. try_files / imgs / $ 1$webp_suffix /imgs/$1 $ 3 = 404 - NO funciona y devuelve 404
  3. try_files /imgs/$1.webp / imgs /$1$3 = 404 - funciona y devuelve el archivo webp
  4. try_files / imgs /$1$3 / imgs /$1$webp_suffix = 404 - funciona y devuelve el archivo jpg

que no tiene ningún sentido

EDIT3:

Para la prueba que estoy abriendo: http: // test: 8888 / imgs / 10 / anything.jpg

Los archivos /srv/imgs/10.jpg y /srv/imgs/10.webp existen.

Respuestas

7 RichardSmith Oct 08 2020 at 00:50

La try_filesdeclaración utiliza capturas numéricas de la expresión regular en la locationdeclaración. El problema con las capturas numéricas es que se sobrescriben cada vez que se evalúa una expresión regular. El mapcontiene una expresión regular que se evalúa entre el locationy las try_filesdeclaraciones.

La solución es utilizar capturas con nombre:

Por ejemplo:

location ~ ^/imgs/(?<prefix>[0-9]*)/(.*?)(?<suffix>\..+)$ { add_header X-webp $webp_suffix;
    try_files /imgs/$prefix$webp_suffix /imgs/$prefix$suffix =404;
}