Esta é provavelmente a maneira mais eficiente de fazer o que você deseja, sem o uso de expressões regulares:
location = /en {
return 302 /en/;
}
location /en/ {
proxy_pass http://luscious/; # note the trailing slash here, it matters!
}
Eu tenho um aplicativo da web em execução em http://example.com/
e quero "montar" outro aplicativo em um servidor separado em http://example.com/en
. Servidores upstream e proxy_pass
parecem funcionar, mas por um problema:
upstream luscious {
server lixxxx.members.linode.com:9001;
}
server {
root /var/www/example.com/current/public/;
server_name example.com;
location /en {
proxy_pass http://luscious;
}
}
Ao abrir example.com/en
, meu aplicativo de envio de dados retorna 404 not found /en
. Isso faz sentido, pois o upstream não possui o caminho /en
.
A proxy_path
é a solução correta? Devo reescrever "upstream" para que ele ouça /en
, como caminho raiz? Ou existe uma diretiva que me permita reescrever o caminho passado para o upstream?
Gostaria de abordar uma nova resposta baseada em regex que está crescendo em popularidade.
location ~ ^/en(/?)(.*)$ { # OOPS!
proxy_pass http://luscious/$2$is_args$args; # OOPS!
}
A solução pode parecer mais fofa à primeira vista, mas está errada por vários motivos.
A regex acima corresponderia a uma solicitação uri de /enjoy
, redirecionando-a para /joy
upstream. Isso é realmente pretendido?
Uma solicitação para /en
não resultará em nenhum redirecionamento, atendendo diretamente a /
do upstream (quase como se uma solicitação para /en/
fosse feita, mas não totalmente). Se você usa URIs relativos dentro do upstream da sua página raiz (caso contrário, por que você não teria o prefixo /en/
ali dentro dos URIs do upstream?), src="style.css"
(que pode referenciar um url("menu.png")
específico do idioma, por exemplo), o navegador solicitará isso como /style.css
em vez de /en/style.css
. (Ou mesmo se você usar URIs absolutos em todos os lugares, e se alguém referenciar um recurso semi-opcional obscuro relativamente?) Ops, de repente o site pode não funcionar, mas apenas às vezes ou em casos extremos.
De acordo com meu aconselhamento anterior em outra pergunta já mencionada pela resposta do próprio OP , o uso de expressões regulares impede a diretiva proxy_redirect
de ter o valor padrão de default
, desviando-o para off
. Isso significa que, se o upstream responder com Location: http://127.0.0.1:8080/en/dir/
quando uma solicitação para /en/dir
for feita, é isso que o cliente verá, o que obviamente não funcionará corretamente. (O que seria especialmente irônico para uma solicitação de /en
que solicita o uso de regex, mas essa implementação específica, ao contrário, sofre de outro problema, como já mencionado acima.) Além disso, se você já estiver usando o upstream
directiva, então pode ficar ainda mais feio se você tentar usar um custom, especialmente se você tiver mais de um servidor upstream - como você tem um proxy_redirect
separado para cada um desses? Também é possível usar expressões regulares em proxy_redirect
, talvez até para corresponder a qualquer host, mas e se você decidir fornecer um redirecionamento de vários domínios no futuro?
Para tentar resolver alguns dos pontos acima com um único local baseado em regex, poderíamos fazer o seguinte (observe que em proxy_pass
também tivemos que descartar a referência a um servidor de uma diretiva baseada em upstream
, para tornar proxy_redirect
mais simples):
location ~ ^/en/?((?<=/).*)?$ {
location = /en { return 302 /en/; }
proxy_pass http://127.0.0.1:8080/$1$is_args$args;
proxy_redirect http://127.0.0.1:8080/ /en/;
}
Então, se você me perguntar, a solução original com os dois locais irmãos de nível superior ainda seria melhor idéia do que cavar-se em um buraco de coelho, indo a rota regex vez.
Então, encontrei a resposta no stackoverflow :
upstream luscious {
server lixxxx.members.linode.com:9001;
}
server {
root /var/www/example.com/current/public/;
server_name example.com;
location ~ ^/en(/?)(.*) {
proxy_pass http://luscious/$2;
}
}
Basicamente: passando um regex para o local e passando o backref ao longo do URL proxy_pass.