This is an old revision of the document!
Table of Contents
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.
- Coincidencia exacta =.
- coincidencia prefijo Ningun modificador y ^~.
- Expresión regular (sensible a mayúsculas y no sensible a mayúsculas).
Cuando se anidan locations en nginx, se debe tener muy 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). }
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