bitlvl
ES

Probador de location de nginx

nginx elige un location con reglas fáciles de recordar mal, y la forma habitual de averiguarlo es desplegar y hacer curl. Pega en su lugar tu configuración y una URL: la traza muestra cada location considerado, por qué ganó o perdió, y qué pasa después.

Nada se envía a ningún sitio; la coincidencia se ejecuta en tu navegador.

Los resultados y mensajes de esta herramienta se muestran en inglés.

Cómo elige nginx un location

  1. El URI se normaliza primero: decodificación porcentual, barras repetidas fusionadas, . y .. resueltos. La cadena de consulta nunca forma parte de la coincidencia de location.
  2. Se comparan todos los locations de prefijo (sin modificador, =, ^~). Una coincidencia exacta = gana de inmediato. Si no, se recuerda el prefijo coincidente más largo.
  3. Si ese prefijo más largo tiene ^~, gana y se saltan las regex.
  4. Los locations regex (~ sensible a mayúsculas, ~* insensible) se prueban en el orden en que aparecen en el archivo. Gana la primera coincidencia, aunque antes haya coincidido un prefijo más largo.
  5. Si ninguna regex coincide, se usa el prefijo más largo recordado.
  6. Dentro del location ganador, el mismo procedimiento se repite para los locations anidados.

Dos consecuencias sorprenden más: un simple location /images/ pierde frente a location ~ \.png$ para /images/a.png, porque las regex se comprueban después de los prefijos; y location /api coincide también con /apiary, porque los prefijos son prefijos de cadena, no segmentos de ruta. Usa /api/ o ^~ cuando eso es lo que quieres decir.

proxy_pass y la barra final

Si proxy_pass tiene una parte de URI (cualquier cosa después del host, aunque sea solo /), nginx sustituye la parte del URI de la petición que coincidió con el prefijo del location por ella. location /api/ { proxy_pass http://app/; } convierte /api/users en /users. Sin parte de URI, el URI de la petición pasa sin cambios. Las barras desparejadas (/api frente a /api/, o http://app frente a http://app/) producen //users o users — el probador imprime el URI upstream exacto para que lo veas. En un location regex no se permite una parte de URI a menos que un rewrite haya cambiado antes el URI.

root frente a alias

root añade el URI entero al directorio: root /srv; location /static/ sirve /srv/static/x.css. alias sustituye el prefijo del location: alias /srv/assets/; location /static/ sirve /srv/assets/x.css. Con alias, las barras finales del location y del alias deben coincidir, y en un location regex el alias debe usar capturas.

Flags de rewrite

FlagEfecto
lastdejar de procesar rewrites, volver a empezar la coincidencia de location con el nuevo URI (máx. 10 veces, luego 500)
breakdejar los rewrites, quedarse en el location actual con el nuevo URI
redirectenviar un 302 al cliente
permanentenviar un 301 al cliente
(ninguno)continuar con el siguiente rewrite; a nivel server el resultado se compara después con los locations

try_files

Cada argumento se comprueba como archivo (o directorio, con barra final) relativo a root/alias; se sirve el primero que existe. El último argumento es la alternativa y no se comprueba: es una redirección interna a un URI (que pasa otra vez por la coincidencia de location), un location con nombre @name o un código de estado del estilo =404. El probador no puede ver tu sistema de archivos, así que lista las rutas que se comprobarían.

Herencia de add_header

add_header se hereda del nivel server solo cuando el location no tiene ningún add_header propio. Un solo add_header Cache-Control en un location elimina silenciosamente las cabeceras de seguridad fijadas a nivel server. La traza lo señala.

Preguntas

¿Admite toda la sintaxis de configuración de nginx?

El analizador maneja la sintaxis real: bloques anidados, comentarios, cadenas entrecomilladas, argumentos regex; las directivas include se listan pero no se siguen (pega también el archivo incluido). Las variables distintas de $uri, $request_uri, $args y las capturas regex se dejan como texto, y los bloques «if» se muestran pero no se evalúan.

¿Por qué mi regex se comporta distinto en nginx?

nginx usa PCRE; esta página usa expresiones regulares de JavaScript. Coinciden en casi todo lo que se usa en bloques location, pero los cuantificadores posesivos, la recursión y algunas formas de lookbehind difieren. La traza indica cuándo una regex no pudo compilarse.

¿Puede probar qué bloque server responde para un Host?

Sí. Pega varios bloques server y rellena el campo Host. La selección sigue a nginx: nombre exacto, comodín más largo que empieza por *, comodín más largo que termina por *, primera regex que coincide, luego default_server, luego el primer server de ese puerto.

¿Cómo lo pruebo en el servidor real?

nginx -T imprime la configuración completa fusionada (todos los include resueltos), que puedes pegar aquí. Para una comprobación en vivo, curl -sI -H "Host: example.com" http://127.0.0.1/ruta y lee la respuesta; añade temporalmente add_header X-Debug-Location "$uri" si necesitas ver qué bloque respondió.