Ich versuche, einen Reverse-Proxy mit einem interessanten Apache mod_rewrite-Setup zu konvertieren, um stattdessen Nginx zu verwenden (aufgrund externer Bedenken wechseln wir von Apache zu Nginx, und fast alles funktioniert einwandfrei, außer diesem Teil).
Mein ursprüngliches Setup bestand darin, ein HTTP-Cookie (von einer Anwendung festgelegt) zu lesen und je nach Wert den Reverse-Proxy an verschiedene Backends zu leiten. Es ging ungefähr so:
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]
Ich versuche, dasselbe mit Nginx zu erreichen, und meine anfängliche Konfiguration war ungefähr so (wobei "proxy_override" der Name des Cookies ist):
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;
}
Aber es war nicht so. Ich habe versucht zu sehen, ob Nginx mein Cookie lesen kann, indem ich den primären Proxy schreibe, um zu etwas weiterzuleiten, das auf basiert, ${cookie_proxy_override}
und ich kann sehen, dass es den Inhalt gut liest, aber die if
s scheinen immer fehlzuschlagen.
Mein nächster Versuch laut Rikihs Antwort war folgender:
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;
}
Und jetzt kann ich sehen, dass der if
Block aktiviert wird, aber anstatt die Anfrage zu proxyieren (wie ich es mir vorgestellt hatte), wird eine 302-Umleitung an die angegebene URL zurückgegeben - was ich nicht versuche: Ich brauche den Server um die Anforderung transparent an die Backends weiterzuleiten und die Antwort an den ursprünglichen Client weiterzuleiten.
Was mache ich falsch?
if
) und sie implementiert habe. Es gibt jedoch ein Problem: Nginx (zumindest meine Version: 1.0.0) mag keine nummerierten Capturesmap
, daher musste ich~^(?P<name>[\w-]+) $name;
stattdessen verwenden. Ich habe Ihre Antwort entsprechend bearbeitet.Schließlich läuft meine Lösung darauf hinaus:
Der Test wird im
server
Bereich für jede Anforderung durchgeführt (bevor die eigentliche Umleitung aufgelöst wird) und wird nur zum Festlegen einer Variablen verwendet - dies ist anscheinend eine unterstützte Verwendung des Nginx-Moduls "Umschreiben". Es testet auch das$http_cookie
Ganze wie von @Rikih vorgeschlagen, enthält jedoch den Namen des Cookies, um sicherzustellen, dass ich nicht mit zufälligen Dingen übereinstimme, die Leute möglicherweise auf mich werfen.In dem
location
Bereich, in dem ich die Umleitung durchführen möchte, verwende ich dann den Variablennamen, der entweder die Standard-Upstream-Konfiguration enthält oder vom Cookie überschrieben wurde.quelle
Hast du $ http_cookie ausprobiert? http://wiki.nginx.org/HttpRewriteModule
if ($ http_cookie ~ * "proxy-target-A") {foo; }}
quelle
rewrite
kein Proxy-Rewrite durchgeführt wird, sondern eine Umleitung an den Client zurückgegeben wird, und ich kann proxy_pass imif
Block nicht verwenden . Ich habe die Frage entsprechend aktualisiert.Ich habe ein Beispiel, das ich verwende, um den Anforderungsheader basierend auf udid zu erkennen, und es funktioniert. Vielleicht bekommen Sie eine Idee.
quelle
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
Befehl zu verwenden, daher bin ich mir nicht sicher, wie er angesichts der obigen Forumsdiskussion für Sie funktionieren kann.