O regex de localização do Nginx não funciona com o passe de proxy

43

Estou tentando fazer com que essas duas diretivas de local funcionem no Nginx, mas estou recebendo alguns erros ao inicializar o Nginx.

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

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

Este é o erro que estou recebendo:

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

Parece familiar para alguém? O que estou perdendo aqui?

Niels
fonte

Respostas:

48

Uma pequena adição à ótima resposta de Xaviar :

Se você não conhece muito bem o nginx, há uma diferença importante entre adicionar a barra ao final da proxy_passdiretiva.

O seguinte não funciona:

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

mas este faz:

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

A diferença está /no final da proxy_passdiretiva.

95%
fonte
1
Esse rastreio /corrigiu meu problema de configuração, era difícil de entender, obrigado!
yorch
Estava me deixando louco, obrigado por apontar isso!
Cyrrill
21

Ele informa que o URI na diretiva de proxy pass não pode ser usado em um local de regex. Isso ocorre porque o nginx não pode substituir a parte do URI que corresponde ao regex no locationbloco pelo que foi passado na proxy_passdiretiva de maneira genérica.

Simplesmente imagine que sua regex de localização é /foo/(.*)/bare você especifica que o proxy_pass http://server/testnginx precisaria mapear sua regex de localização para outra em um nível superior, porque você não deseja terminar com /foo/test/bar/somethingmas /test/something. Portanto, isso não é possível nativamente.

Portanto, para esta parte, o seguinte deve 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;
    }

}

No entanto, não será possível reescrever os redirecionamentos para corresponder ao padrão de URI do bloco de localização, porque ele reescreve o URI atual que está sendo processado, tornando impossível alterar o Locationcabeçalho com base na solicitação inicial antes de reescrever.

Xavier Lucas
fonte
2
mover o caminho para uma regra de reescrita funcionou para mim. obrigado.
sonjz 8/09/2015