La ubicación de Nginx regex no funciona con el pase de proxy

44

Estoy tratando de hacer que estas 2 directivas de ubicación funcionen en Nginx, pero recibo algunos errores al iniciar Nginx.

   location ~ ^/smx/(test|production) {
        proxy_pass   http://localhost:8181/cxf;
    }

    location ~ ^/es/(test|production) {
        proxy_pass   http://localhost:9200/;
    }

Este es el error que estoy recibiendo:

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

¿Le suena familiar a alguien? ¿Qué me estoy perdiendo aquí?

Niels
fuente

Respuestas:

49

Una pequeña adición a la gran respuesta de Xaviar :

Si no está tan familiarizado con nginx, hay una diferencia importante entre agregar la barra diagonal al final de la proxy_passdirectiva.

Lo siguiente no funciona:

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend/;

pero este sí:

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend;

La diferencia es /al final de la proxy_passdirectiva.

marca
fuente
1
Ese seguimiento /solucionó mi problema de configuración, era difícil de entender, ¡gracias!
Yorch
Me estaba volviendo loco, ¡gracias por señalarlo!
cyrrill
22

Le dice que el URI en la directiva de paso de proxy no se puede usar en una ubicación de expresiones regulares. Esto se debe a que nginx no puede reemplazar la parte del URI que coincide con la expresión regular en el locationbloque con la que se aprobó en la proxy_passdirectiva de forma genérica.

Simplemente imagine que su regex de ubicación es /foo/(.*)/bar, y usted especifica proxy_pass http://server/test, nginx tendría que asignar su regex de ubicación a otra en un nivel superior porque no desea terminar con /foo/test/bar/somethingpero con /test/something. Entonces eso no es posible de forma nativa.

Entonces, para esta parte, usar lo siguiente debería funcionar:

server {

   [ ... ]

    location ~ ^/smx/(test|production) {
        rewrite ^/smx/(?:test|production)/(.*)$ /cxf/$1 break;
        proxy_pass http://localhost:8181;
    }

    location ~ ^/es/(test|production) {
        rewrite ^/es/(?:test|production)/(.*)$ /$1 break;
        proxy_pass http://localhost:9200;
    }

}

Sin embargo, no será posible reescribir los redireccionamientos para que coincidan con el patrón de URI del bloque de ubicación porque reescribe el URI actual que se está procesando, lo que hace imposible cambiar el Locationencabezado en función de la solicitud inicial antes de volver a escribir.

Xavier Lucas
fuente
2
mover el camino hacia una regla de reescritura funcionó para mí. Gracias.
sonjz