Wyrażenie regularne lokalizacji Nginx nie działa z przepustką proxy

43

Próbuję przywrócić działanie tych 2 dyrektyw lokalizacji w Nginx, ale otrzymuję błędy podczas uruchamiania Nginx.

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

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

To jest błąd, który otrzymuję:

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

Czy to brzmi znajomo? Czego tu brakuje?

Niels
źródło

Odpowiedzi:

48

Mały dodatek do świetnej odpowiedzi Xaviar :

Jeśli nie znasz się tak dobrze na nginx, istnieje ważna różnica między dodaniem ukośnika na końcu proxy_passdyrektywy.

Następujące nie działa:

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

ale ten robi:

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

Różnica polega /na końcu proxy_passdyrektywy.

2 użytkowników 95%
źródło
1
To, że wleczenie /naprawiło mój problem z konfiguracją, było trudne do złapania, dzięki!
luty
Doprowadzał mnie do szału, dzięki za zwrócenie na to uwagi!
cyrrill
20

Mówi ci, że URI w dyrektywie proxy proxy nie może być używany w lokalizacji wyrażenia regularnego. Wynika to z faktu, że nginx nie może zastąpić części identyfikatora URI pasującego do wyrażenia regularnego w locationbloku tym, który został przekazany w proxy_passdyrektywie w sposób ogólny.

Po prostu wyobraź sobie, że twoja regex lokalizacji jest /foo/(.*)/bar, a ty określasz proxy_pass http://server/test, że nginx musiałby mapować regex lokalizacji na inną na wyższym poziomie, ponieważ nie chcesz kończyć, /foo/test/bar/somethingale z /test/something. Więc nie jest to możliwe natywnie.

W przypadku tej części korzystanie z następujących elementów powinno działać:

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;
    }

}

Jednak przekierowanie przekierowań w celu dopasowania do wzorca URI bloku lokalizacji nie będzie możliwe, ponieważ przepisuje bieżący przetwarzany URI, uniemożliwiając zmianę Locationnagłówka na podstawie początkowego żądania przed przepisaniem.

Xavier Lucas
źródło
2
przejście ścieżki do reguły przepisywania działało dla mnie. dzięki.
sonjz