Estou tentando converter um proxy reverso usando uma configuração interessante do mod_rewrite do Apache para usar o Nginx (devido a preocupações externas, estamos passando do Apache para o Nginx, e quase tudo funciona bem, exceto esta parte).
Minha configuração original era ler um cookie HTTP (definido por algum aplicativo) e, dependendo do seu valor, direcionar o proxy reverso para diferentes back-ends. Aconteceu mais ou menos assim:
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]
Estou tentando conseguir o mesmo usando o Nginx, e minha configuração inicial era algo assim (onde "proxy_override" é o nome do 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;
}
Mas isso não aconteceu. Eu tentei ver se o Nginx pode ler meu cookie escrevendo o proxy primário para redirecionar para algo baseado ${cookie_proxy_override}
e posso ver que ele lê bem o conteúdo, mas os if
sempre parecem falhar.
Minha próxima tentativa, de acordo com a resposta de Rikih, foi esta:
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;
}
E agora posso ver que o if
bloco é ativado, mas, em vez de proxies a solicitação (como eu pensava que faria), ele retorna um redirecionamento 302 para o URL especificado - o que não é o que estou tentando fazer: preciso do servidor retransmitir de forma transparente a solicitação para os back-end e canalizar a resposta para o cliente original.
O que estou fazendo errado?
if
) e a implementei. Porém, há um problema: o Nginx (pelo menos minha versão: 1.0.0) não gosta de capturas numeradasmap
, então tive que usá-lo~^(?P<name>[\w-]+) $name;
. Editei sua resposta de acordo.Eventualmente, minha solução se resume a isso:
O teste é realizado no
server
escopo de cada solicitação (antes que o redirecionamento real seja resolvido) e é usado apenas para definir uma variável - esse é aparentemente um uso suportado do módulo "reescrita" do Nginx. Ele também testa todo o$http_cookie
conteúdo, como o @Rikih sugeriu, mas inclui o nome do cookie para garantir que eu não corresponda a coisas aleatórias que as pessoas possam estar jogando para mim.Em seguida, no
location
escopo em que desejo redirecionar, utilizo o nome da variável que contém a configuração upstream padrão ou foi substituída pelo cookie.fonte
você experimentou $ http_cookie? http://wiki.nginx.org/HttpRewriteModule
if ($ http_cookie ~ * "proxy-target-A") {foo; }
fonte
rewrite
, na verdade, ele não reescreve o proxy, mas retorna um redirecionamento para o cliente e não posso usar proxy_pass noif
bloco. Eu atualizei a pergunta de acordo.Eu tenho um exemplo que eu uso para detectar o cabeçalho da solicitação com base no udid e está funcionando, pode ser que você tenha uma idéia.
fonte
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, portanto, não tenho certeza de como ele pode funcionar para você, dada a discussão no fórum acima.