2011-12-08 14 views
17

Estoy tratando de optimizar mis directivas de "ubicación" y no puedo encontrar una buena forma de determinar si se intenta siquiera una coincidencia de ubicación específica. Usar echo dentro del bloque de ubicación no ayuda aquí.¿Cómo controlar el orden de coincidencia de la directiva 'Ubicación' de NGINX?

The NGINX ngx_http_core_module documentation es algo confuso.

Para usar expresiones regulares, debe utilizar un prefijo:

  1. ~ Para el caso sensibles a juego

  2. ~* Para el caso insensible a juego

¿Cómo se realiza el encuentro:

  1. Directivas con el prefijo = que coinciden exactamente con la consulta. Si se encuentra, la búsqueda se detiene.

  2. Todas las demás directivas con cadenas convencionales. Si esta coincidencia usó el prefijo ^~, la búsqueda se detiene.

  3. Expresiones regulares, en el orden en que se definen en el archivo de configuración.

  4. Si # 3 arrojó una coincidencia, se utiliza ese resultado. De lo contrario, se usa la coincidencia de # 2.

número 2 aquí dice "cuerdas convencionales", pero luego dice que se puede utilizar con el ^~ prefijo. ¿No implica ~ un RegExp? Si no, ¿cómo determina qué es un no es un RegExp?

concreto, quiero lo siguiente:

  1. Servir nada fuera de literal /assets directamente. STOP SEARCH.

  2. Sirve cualquier cosa que coincida con RegExp \.php$|/$ a través de la BÚSQUEDA DE PARADA CGI rápida.

  3. sirven de todo lo demás directamente a través literal /

De esta manera, no hay más que un intento de / la altura de archivos no dinámicos servido desde fuera de los activos.

que tengo:

location ^~ /assets {}  # search-terminating literal? or regex? 
location ~ \.php$|/$ {} 
location/{}    # is this match always attempted? 

Desde el documento, parece que el orden real sería la formación 1-3-2, siempre corriendo el literal / partido. Sí, esta optimización no hará ninguna diferencia para el rendimiento real, pero solo quiero aclarar alguna ambigüedad.

Respuesta

7

Desde el wiki:

location =/{ 
    # matches the query/only. 
    [ configuration A ] 
} 
location/{ 
    # matches any query, since all queries begin with /, but regular 
    # expressions and any longer conventional blocks will be 
    # matched first. 
    [ configuration B ] 
} 

Por lo tanto, esta será igualada primera: location ~ \.php$ {}

A pesar de que los activos se sirven de location/{}

Dentro del bloque php también desea proteger contra cargas maliciosas antes de pasar a fastcgi:

if ($uri ~* "^/uploads/") { 
    return 404; 
} 

Como puede ver, nginx funciona de una manera un poco diferente de lo que cabría esperar.

+0

todavía no estoy claro por qué la expresión regular se correspondería primero. concedido que no hay directivas "=". El siguiente paso es "Todas las directivas restantes con cadenas convencionales". '/' es una cadena convencional y debe coincidir antes de cualquier expresión regular. todo el strings-then-regex es una optimización implícita de la mano que nginx parece hacer aquí, lo que hace que sea imposible determinar el verdadero orden de la evaluación. Creo que apache/iptables, etc. lo hacen bien al procesar predeciblemente en el mismo orden definido como un bloque if/else-if/else. sin ninguna regla implícita "más/menos" específica. – leeoniya

+0

Correcto, esto definitivamente es un poco confuso sobre nginx, especialmente el 'if' de nginx, que debería usarse solo para reescribir/devolver. Creo que están trabajando para simplificar esto. Para su situación, funcionará así: 1. php regex check con una parada si es una coincidencia 2./para cualquier contenido estático. – m33lky

+0

usted es incorrecto sobre la orden. El objetivo de tener la regla/assets como una cadena primero es evitar la sobrecarga de ejecutar la expresión regular php en cada solicitud. de hecho, QUIERO servir algo como assets/docs/example.php sin pasarlo por FCGI. Actualmente estoy ejecutando esta configuración y la expresión regular NO atrapa por ejemplo.php. está ordenado como^~/assets, /, ~ \ .php $ |/$ – leeoniya

Cuestiones relacionadas