Estoy tratando de convertir un proxy inverso usando una configuración interesante de Apache mod_rewrite para usar Nginx en su lugar (debido a preocupaciones externas, nos estamos moviendo de Apache a Nginx, y casi todo funciona bien, excepto esta parte).
Mi configuración original era leer una cookie HTTP (establecida por alguna aplicación) y, dependiendo de su valor, dirigir el proxy inverso a diferentes backends. Fue algo como ésto:
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]
Estoy tratando de lograr lo mismo usando Nginx, y mi configuración inicial fue algo así (donde "proxy_override" es el nombre de la 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;
}
Pero no fue así. Traté de ver si Nginx puede leer mi cookie escribiendo el proxy primario para redirigir a algo basado ${cookie_proxy_override}
y puedo ver que lee bien el contenido, pero if
parece que los s siempre fallan.
Mi siguiente intento, de acuerdo con la respuesta de Rikih fue este:
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;
}
Y ahora puedo ver que el if
bloque se activa, pero en lugar de enviar la solicitud (como pensé que haría), devuelve una redirección 302 a la URL especificada, que no es lo que estoy tratando de hacer: necesito el servidor para retransmitir de forma transparente la solicitud a los servidores y canalizar la respuesta al cliente original.
¿Qué estoy haciendo mal?
if
entrar) y la implementé. Sin embargo, hay un problema: a Nginx (al menos mi versión: 1.0.0) no le gustan las capturas numeradasmap
, así que tuve que usarlas~^(?P<name>[\w-]+) $name;
. He editado tu respuesta en consecuencia.Finalmente, mi solución se reduce a esto:
La prueba se realiza en el
server
ámbito de cada solicitud (antes de que se resuelva la redirección real) y solo se usa para establecer una variable; aparentemente, este es un uso compatible del módulo Nginx "rewrite". También prueba todo$http_cookie
como sugirió @Rikih, pero incluye el nombre de la cookie para asegurarse de que no coincida con cosas aleatorias que la gente podría estar arrojándome.Luego, en el
location
ámbito donde quiero hacer la redirección, utilizo el nombre de la variable que contiene la configuración ascendente predeterminada o la cookie la sobrescribió.fuente
¿Has probado $ http_cookie? http://wiki.nginx.org/HttpRewriteModule
if ($ http_cookie ~ * "proxy-target-A") {foo; }
fuente
rewrite
realidad no hace una reescritura de proxy, sino que devuelve una redirección al cliente, y no puedo usar proxy_pass en elif
bloque. He actualizado la pregunta en consecuencia.Tengo una muestra que uso para detectar el encabezado de solicitud basado en udid y está funcionando, podría ser que tengas alguna idea.
fuente
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
comando, por lo que no estoy seguro de cómo puede funcionar para usted dado el debate del foro anterior.