guia_rapida_de_location_y_modificadores_en_nginx

This is an old revision of the document!


Guía rápida de Nginx locations (Modificadores, prioridad y slash - proxy_pass)

Modificadores

= El bloque se considerará una coincidencia si la URI de la solicitud coincide exactamente con la ubicación indicada. Es lo primero que busca Nginx, no pueden repetirse y tienen prioridad sobre cualquier otra location, usen o no expresiones regulares. El orden de estas location NO importa.

location  = / {  # Solo se usa si coincide al 100%, en este caso "/" únicamente. }
location  = /img/ {  # Solo se usa si coincide al 100%, en este caso "/img/" únicamente. Si la query es /img/algo_más NO se usará. }
# Query GET /cp/abc
location ~ ^cp/abc{}
location ^~ /cp {}
location ^~ /cp/abc {}
location = /cp/abc {}  <--- location seleccionada.

^~ No permite expresiones regulares. Actúa como un prefijo, de haber varias location, la que encaje con el prefijo más largo es la location elegida. Por lo tanto NO es importante el orden de este tipo de expresiones regulares.

# Query GET /cp/abc
location ^~ /cp/{}
location ^~ /cp/ab {}
location ~ ^cp/abc{}   # NO será seleccionada porque es una regex y NO tiene prioridad frente al uso de prefijos (^~ o ningún modificador).
location ^~ /cp/abc {} <--- location seleccionada.

NOTA: Es el método recomendado frente a usar “ningún modificador” cuando no se usan expresiones regulares.

(ninguno): Actúa como un prefijo exactamente igual que “^~” y tiene su misma prioridad frente a regex. NO es importante el orden y la que coincida con el prefijo más largo será la elegida. NO tiene tampoco prioridad especial frente a “^~”, si hay dos location iguales, una sin modificador y otra con ^~, la primera será la utilizada.

# Query GET /cp/abc
location /cp/{}
location /cp/ab {}
location ~ ^cp/abc{} # NO será seleccionada porque es una regex y NO tiene prioridad frente al uso de prefijos (^~ o ningún modificador).
location /cp/abc {}  <--- Location seleccionada
location ^~/cp/abc {}

A partir de estos tres modificadores (=, ~^ y ninguno), los siguientes modificadores refieren a expresiones regulares, siendo el primero en encajar el seleccionado. Por lo tanto SI importa el orden usado al usar regex.

NOTA: Es preferible usar el método de prefijo ^~ ya que internamente tiene un mejor rendimiento.

~ (Modificador de expresión regular) La ubicación se interpretará como una coincidencia de expresión regular que distingue entre mayúsculas y minúsculas. SI importa el orden ya que el primero en coincidir será el usado.

location ~^/cp { # Distingue entre mayúsculas y minúsculas }

~* (Modificador de expresión regular) La ubicación se interpretará como una coincidencia de expresión regular que NO distingue entre mayúsculas y minúsculas. Al igual que el anterior modificador case sensitive, SI importa el orden ya que el primero en coincidir será el usado.

location ~* .(png|gif|ico|jpg|jpeg)$ { # Queries que terminen con png, gif, ico, jpg o jpeg. Al no ser que la query tenga un /img/ y exista un modificador de prefijo "location ^~ /img/" o "location /img/" }
location ~*^/cp { # cualquier cosa que empiece con /cp, /CP, /cP o /Cp }
location ~*/cp { # cualquier cosa que tenga /cp, /CP, /cP o /Cp en alguna parte de la URL, no necesariamente al principio. }

Modificadores en nested location

Recordemos la prioridad de los modificadores en Nginx.

  1. Coincidencia exacta =.
  2. coincidencia prefijo Ningún modificador y ^~.
  3. Expresión regular (sensible a mayúsculas y no sensible a mayúsculas).

Cuando se anidan locations en nginx, se debe tener en cuenta esa prioridad, si el location raíz es una regex, sus location anidadas deben tener también esa prioridad, es decir, ser expresiones regulares. Si se anidan coincidencias exactas o de prefijo, estas nunca serán elegidas.

# Query GET /cp/abc
location ~ /cp {
   ...
   location = /cp/abc {}  # Nunca será seleccionada
   location /cp/abc {}    # Nunca será seleccionada
   location ^~/cp/abc {}  # Nunca será seleccionada
   location ~/cp/abc {}   <----- Sí (Debido a que es una regex).
}

En cambio con los modificadores de coincidencia exacta o mediante prefijo se puede combinar como se quiera. Dentro del nested location se usa la prioridad normal anteriormente vista.

location /cp {
   ...
   location = /cp/abc {} # Query GET /cp/abc
   location ~/cp/abcd {} # Query GET /cp/abcd
   location /cp/abcd {}  # Nunca será seleccionada porque la anterior (regex) es usada. De ser "location ^~ /cp/abcd {}" SÍ tendría prioridad frente a la regex.
}

Location sin expresiones regulares y proxy_pass

Ejemplos de comportamiento para location de Nginx que no usan regex, es decir modificador “ninguno” o “^~”. El modificador “=” en esta sección no tiene sentido ya que no permite usarse de manera flexible.

location ^~/cp { proxy_pass  http://192.168.178.25; }
 
http://XXX/cp/aaa ----> http://192.168.178.25/cp/aaaa
http://XXX/cp -------->  http://192.168.178.25/cp
http://XXX/cp/ ------->  http://192.168.178.25/cp/
location ^~/cp { proxy_pass  http://192.168.178.25/;  }
 
http://XXX/cp/aaa ---> http://192.168.178.25//aaa
http://XXX/cp/ ------> http://192.168.178.25//
http://XXX/cp -------> http://192.168.178.25/
location ^~/cp/ { proxy_pass  http://192.168.178.25/;  }
 
http://XXX/cp/aaa ---> http://192.168.178.25/aaa
http://XXX/cp/ ------> http://192.168.178.25/
http://XXX/cp -------> http://XXX/cp/ ----> http://192.168.178.25/
location ^~/cp/ { proxy_pass  http://192.168.178.25; }
 
http://XXX/cp/aaa ---> http://192.168.178.25/cp/aaa
http://XXX/cp/ ------> http://192.168.178.25/cp
http://XXX/cp ------->  http://XXX/cp/ --> http://192.168.178.25/cp

Location con expresiones regulares y proxy_pass sin URL

location ~ /c(p|a)/ {  proxy_pass  http://192.168.178.25; }
 
http://XXX/cp/aaa ---> http://192.168.178.25/cp/aaa
http://XXX/cp/ ------> http://192.168.178.25/cp/
http://XXX/cp -------> NOT FOUND
#  Al no especificarse una URL (incluir al menos un slash) en proxypass, la variable $1 no tendrá ningún valor.
location ~ ^/c(p|a)/ {  proxy_pass  http://192.168.178.25; }
location ~ ^/cp/ {  proxy_pass  http://192.168.178.25$1; }
location ~ ^/cp/ {  proxy_pass  http://192.168.178.25; }
 
http://XXX/cp/aaa ---> http://192.168.178.25/cp/aaa
http://XXX/cp/ ------> http://192.168.178.25/cp/
http://XXX/cp -------> http://192.168.178.25/cp

Location con expresiones regulares y proxy_pass con URL

Si se usan URLs en el proxypass, deben usarse variables, $1, $2, $3,… Las cuales tendrán el valor resultante de cada regex para ser integradas en la URL del proxy_pass. Las variables pueden tener nombres personalizados. Si no se usan variables cuando se utilizan URLs (uso de slash) en proxy_pass, Nginx mostrará el siguiente error.

nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in

La obligación de usar variables, implica que para agrupar sus valores deben usarse paréntesis, veamos algunos ejemplos de uso de location con expresiones regulares y URLs en proxy_pass.

# No hay regex activa, por lo que $1 no contiene ningún valor.
location ~ ^/cp/ {  proxy_pass  http://192.168.178.25/$1; }
 
http://XXX/cp/bbbb ----> http://192.168.178.25/
http://XXX/ca/bbb ----> http://192.168.178.25/
 
location ~ ^/cp/ {  proxy_pass  http://192.168.178.25/$1/hola; }
 
http://XXX/cp/bbbb ----> http://192.168.178.25/hola
http://XXX/ca/bbb ----> http://192.168.178.25/hola
 
# La Expresión regular refiere a "p" o "a".
location ~ ^/c(p|a) {  proxy_pass  http://192.168.178.25/$1/$1; }
location ~ ^/c(p|a)/ {  proxy_pass  http://192.168.178.25/$1/$1; }
 
http://XXX/cp/bbbb ----> http://192.168.178.25/p/p 
http://XXX/ca/bbb ----> http://192.168.178.25/a/a
 
# La Expresión regular refiere a "/cp/" o "/ca/".
location ~ ^(/cp/|/ca/) {  proxy_pass  http://192.168.178.25/dir1/dir2$1; }
 
http://XXX/cp/AAA/BBB/CCC ---> http://192.168.178.25/dir1/dir2/cp/
http://XXX/ca/AAA/BBB/CCC ---> http://192.168.178.25/dir1/dir2/ca/
 
# La expresión regular refiere a cualquier location.
location ~ ^/(.*) {  proxy_pass  http://192.168.178.25/dir1/$1/dir2; }
 
http://XXX/cp/AA/BBB ---> http://192.168.178.25/dir1/cp/AA/BBB/dir2
http://XXX  ------------> http://192.168.178.25/dir1//dir2
http://XXX/ ------------> http://192.168.178.25/dir1//dir2

Varias regex y personalización de nombre de variables

# El valor obtenido con la primera regex se guarda en la variable "$width" y el segundo en "$height" para luego ser enviadas al host en la forma expuesta.
location ~/resize/(?<width>(\d+))/(?<height>(\d+)) { proxy_pass  http://192.168.178.25/?ancho=$width&alto=$height&blabla=null;}
 
http://XXX/resize/300/500/ ----> http://192.168.178.25/?ancho=300&alto=500&blabla=null
guia_rapida_de_location_y_modificadores_en_nginx.1620680673.txt.gz · Last modified: 2021/05/10 23:04 by busindre