Por que o Apache está forçando explicitamente o redirecionamento com um URL absoluto?

2

Contexto

Com a seguinte regra:

# Redirect root url to /tvs
RewriteRule ^/$ /tvs [R=301,L]

Eu tenho um redirecionamento absoluto como:

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Fri, 24 Mar 2017 16:42:23 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 312
Location: http://www.tvsvizzera.it/tvs
Vary: Accept-Encoding
X-Node: pcache02
X-Cached: MISS
Proxy-Connection: Keep-Alive
Connection: Keep-Alive

e no rewrite.log eu tenho o seguinte

10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (2) init rewrite engine with requested uri /
10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (2) rewrite '/' -> '/tvs'
10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (2) explicitly forcing redirect with http://www.tvsvizzera.it/
tvs
10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (1) escaping http://www.tvsvizzera.it/tvs for redirect
10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (1) redirect to http://www.tvsvizzera.it/tvs [REDIRECT/301]

Por que o apache explicitamente força o redirecionamento a ser absoluto?

Problema

O servidor está por trás de um proxy reverso que faz o descarregamento de SSL. Portanto, se o redirecionamento permanecesse relativo, a mesma regra funcionaria para o protocolo HTTP / HTTPS. Mas este não é o caso e ao solicitar com https, um é redirecionado para http.

Eu sei que posso mudar a regra para algo parecido com isto

RewriteRule ^/$ %{ENV:REQUEST_SCHEME}://%{HTTP_HOST}/tvs [R=permanent,L]

Mas eu queria entender esse comportamento.

Obrigado por qualquer explicação.

    
por Julien 24.03.2017 / 18:13

1 resposta

4

Todos os redirecionamentos externos ( R flag) resultam em mod_rewrite requerendo um URL absoluto. Quando você não incluir explicitamente o esquema e o nome do host na RewriteRule substituição , o Apache usará o protocolo, o nome do servidor e a porta atuais. O Apache (ou estritamente falando, mod_rewrite) não envia um URL relativo de volta no cabeçalho de resposta Location: HTTP esperando que o user-agent resolva o URL.

(Não foi até junho de 2014 ( RFC 7231 ) que relativo URLs no cabeçalho Location: tornaram-se oficialmente parte do padrão Então, particularmente se você ainda estiver no Apache 2.2, então é difícil argumentar que o Apache está fazendo algo errado aqui.

Se o Apache está enviando de volta uma URL HTTP (ao contrário de HTTPS), então parece que o Apache está retornando a resposta via HTTP, não HTTPS.

Sim, você pode "corrigir" manualmente o URL usando o mod_rewrite. No entanto, a variável REQUEST_SCHEME do servidor provavelmente terá o mesmo "problema". Se você estiver atrás de um proxy, talvez seja necessário verificar o cabeçalho X-Forwarded-Proto (ou similar) se ele é "http" ou "https".

Além de (condicionalmente) forçar o HTTPS na própria diretiva, você também pode forçar HTTPS na configuração do servidor com a (s) diretiva (s) ServerName (e UseCanonicalName ). No entanto, presumo que isso não é desejável e você precisa ser flexível?

Você também pode editar o cabeçalho Location: , antes de enviá-lo de volta ao cliente. Usando mod_headers você pode forçar uma URL relativa removendo manualmente o esquema + hostname, como sugerido em esta resposta do StackOverflow :

Header edit Location "^https?://[a-zA-Z0-9.-]+" ""

Referência adicional:

por 24.03.2017 / 18:59