Próbuję przekonwertować zwrotny serwer proxy za pomocą ciekawej konfiguracji mod_rewrite Apache, aby zamiast tego używać Nginx (z powodu problemów zewnętrznych przechodzimy z Apache na Nginx, a większość wszystkiego działa dobrze oprócz tej części).
Moją pierwotną konfiguracją było odczytanie pliku cookie HTTP (ustawionego przez jakąś aplikację) i zależnie od jego wartości, skierować zwrotne proxy do różnych backendów. Poszło mniej więcej tak:
RewriteCond %{HTTP_COOKIE} proxy-target-A
RewriteRule ^/original-request/ http://backend-a/some-application [P,QSA]
RewriteCond %{HTTP_COOKIE} proxy-target-B
RewriteRule ^/original-request http://backend-b/another-application [P,QSA]
RewriteRule ^/original-request http://primary-backend/original-application [P,QSA]
Próbuję osiągnąć to samo za pomocą Nginx, a moja początkowa konfiguracja była mniej więcej taka (gdzie „proxy_override” to nazwa pliku cookie):
location /original-request {
if ($cookie_proxy_override = "proxy-target-A") {
rewrite . http://backend-a/some-application;
break;
}
if ($cookie_proxy_override = "proxy-target-B") {
rewrite . http://backend-b/another-application;
break;
}
proxy_pass http://primary-backend/original-application;
}
Ale tak nie było. Próbowałem sprawdzić, czy Nginx może odczytać mój plik cookie, pisząc główny serwer proxy, aby przekierować do czegoś opartego na, ${cookie_proxy_override}
i widzę, że dobrze czyta treść, ale if
wydaje się, że zawsze zawodzi.
Moja następna próba, zgodnie z odpowiedzią Rikih, była następująca:
location /original-request {
if ($http_cookie ~ "proxy-target-A") {
rewrite . http://backend-a/some-application;
break;
}
if ($http_cookie ~ "proxy-target-B") {
rewrite . http://backend-b/another-application;
break;
}
proxy_pass http://primary-backend/original-application;
}
A teraz widzę, że if
blok zostaje aktywowany, ale zamiast proxy żądania (tak jak myślałem, że tak zrobi), zwraca przekierowanie 302 do podanego adresu URL - co nie jest tym, co próbuję zrobić: potrzebuję serwera w celu transparentnego przekazania żądania do backendów i przesłania odpowiedzi do oryginalnego klienta.
Co ja robię źle?
if
) i zaimplementowałem ją. Jest jednak jeden problem - Nginx (przynajmniej moja wersja: 1.0.0) nie lubi przechwytywania numerowanegomap
, więc musiałem go użyć~^(?P<name>[\w-]+) $name;
. Odpowiednio zredagowałem twoją odpowiedź.W końcu moje rozwiązanie sprowadza się do tego:
Test jest wykonywany w
server
zakresie dla każdego żądania (przed rozwiązaniem rzeczywistego przekierowania) i jest po prostu używany do ustawienia zmiennej - jest to najwyraźniej obsługiwane użycie modułu „przepisywania” Nginx.$http_cookie
Testuje także całość, jak sugeruje @Rikih, ale zawiera nazwę pliku cookie, aby upewnić się, że nie pasuję do losowych rzeczy, które ludzie mogą mi rzucać.Następnie w
location
zakresie, w którym chcę dokonać przekierowania, używam nazwy zmiennej, która zawiera domyślną konfigurację wysyłania lub została zastąpiona przez plik cookie.źródło
próbowałeś $ http_cookie? http://wiki.nginx.org/HttpRewriteModule
if ($ http_cookie ~ * "proxy-target-A") {foo; }
źródło
rewrite
tak naprawdę nie przepisuje proxy, ale zamiast tego zwraca przekierowanie do klienta i nie mogę użyć proxy_pass wif
bloku. Odpowiednio zaktualizowałem pytanie.Mam próbkę, której używam do wykrywania nagłówka żądania na podstawie udid i działa, być może dostaniesz jakiś pomysł.
źródło
nginx: [emerg] "proxy_pass" may not have URI part in location given by regular expression, or inside named location, or inside the "if" statement, or inside the "limit_except" block in /etc/nginx/conf.d/proxy.conf:47
proxy_pass
poleceniu, więc nie jestem pewien, w jaki sposób może on działać w przypadku powyższej dyskusji na forum.