J'essaie de convertir un proxy inverse en utilisant une configuration Apache mod_rewrite intéressante pour utiliser Nginx à la place (en raison de problèmes externes, nous passons d'Apache à Nginx, et la plupart des choses fonctionnent bien sauf cette partie).
Ma configuration d'origine était de lire un cookie HTTP (défini par une application) et, en fonction de sa valeur, de diriger le proxy inverse vers différents backends. Il est allé quelque chose comme ça:
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]
J'essaie d'obtenir la même chose en utilisant Nginx, et ma configuration initiale était quelque chose comme ça (où "proxy_override" est le nom du 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;
}
Mais ce n'était pas le cas. J'ai essayé de voir si Nginx peut lire mon cookie en écrivant le proxy principal pour rediriger vers quelque chose basé sur ${cookie_proxy_override}
et je peux voir qu'il lit bien le contenu, mais les if
s semblent toujours échouer.
Mon prochain essai, selon la réponse de Rikih, était le suivant:
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;
}
Et maintenant, je peux voir que le if
bloc est activé, mais au lieu de mandater la demande (comme je le pensais), il renvoie une redirection 302 vers l'URL spécifiée - ce qui n'est pas ce que j'essaie de faire: j'ai besoin du serveur pour relayer de manière transparente la demande aux backends et diriger la réponse vers le client d'origine.
Qu'est-ce que je fais mal?
if
) et je l'ai implémentée. Il y a un problème cependant - Nginx (au moins ma version: 1.0.0) n'aime pas les captures numérotéesmap
, j'ai donc dû utiliser à la~^(?P<name>[\w-]+) $name;
place. J'ai modifié votre réponse en conséquence.Finalement, ma solution se résume à ceci:
Le test est effectué dans la
server
portée de chaque demande (avant que la redirection réelle ne soit résolue) et est juste utilisé pour définir une variable - il s'agit apparemment d'une utilisation prise en charge du module de «réécriture» de Nginx. Il teste également l'intégralité$http_cookie
comme l'a suggéré @Rikih, mais inclut le nom du cookie pour m'assurer que je ne correspond pas aux éléments aléatoires que les gens pourraient me lancer.Ensuite, dans la
location
portée où je veux faire la redirection, j'utilise le nom de variable qui contient la configuration en amont par défaut ou a été remplacé par le cookie.la source
avez-vous essayé $ http_cookie? http://wiki.nginx.org/HttpRewriteModule
if ($ http_cookie ~ * "proxy-target-A") {foo; }
la source
rewrite
cela ne fait pas de réécriture de proxy mais renvoie à la place une redirection vers le client, et je ne peux pas utiliser proxy_pass dans leif
bloc. J'ai mis à jour la question en conséquence.J'ai un échantillon que j'utilise pour détecter l'en-tête de demande basé sur udid et cela fonctionne, vous aurez peut-être une idée.
la source
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
commande, donc je ne sais pas comment cela peut fonctionner pour vous compte tenu de la discussion sur le forum ci-dessus.