Почему Apache явно принудительно перенаправляет с абсолютным URL?

Контекст

Со следующим правилом:

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

У меня есть абсолютное перенаправление вроде:

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

, а в журнале rewrite.log есть следующее

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]

Почему apache явно принудительно устанавливает абсолютное перенаправление?

Проблема

Сервер находится за обратным прокси, выполняющим разгрузку SSL. Таким образом, если перенаправление останется относительным, то же правило будет работать для обоих протоколов HTTP / HTTPS. Но это не тот случай, и при запросе с https происходит перенаправление на http.

Я знаю, что могу изменить правило, чтобы оно было примерно таким

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

Но я хотел понять это поведение.

Спасибо за любое объяснение.

2
задан 24 March 2017 в 19:13
1 ответ

Все внешние перенаправления (флаг R ) приводят к тому, что mod_rewrite требует абсолютного URL. Если вы явно не включили схему и имя хоста в подстановку RewriteRule , то Apache будет использовать текущий протокол, имя сервера и порт. Apache (или, строго говоря, mod_rewrite) не отправляет относительный URL-адрес обратно в HTTP-заголовке ответа Location: в надежде, что пользовательский агент разрешит URL-адрес.

(Так было до июня 2014 г. ( RFC 7231 ), что относительные URL-адреса в заголовке Location: официально стали частью стандарта. Поэтому, особенно если вы все еще используете Apache 2.2, тогда трудно утверждать, что Apache здесь делает что-то не так.)

Если Apache отправляет обратно URL-адрес HTTP (в отличие от HTTPS), то может показаться, что Apache отправляет ответ обратно через HTTP, а не через HTTPS.

Да, вы можете вручную «исправить» URL с помощью mod_rewrite. Однако серверная переменная REQUEST_SCHEME , вероятно, имеет ту же «проблему».Если вы находитесь за прокси-сервером, вам может потребоваться проверить заголовок X-Forwarded-Proto (или аналогичный) на предмет «http» или «https».

А также (условно) принудительное использование HTTPS в самой директиве, вы также можете принудительно использовать HTTPS в конфигурации сервера с помощью директивы ServerName UseCanonicalName ). Однако я предполагаю, что это нежелательно и вам нужно проявлять гибкость?

Вы также можете отредактировать заголовок Location: , прежде чем он будет отправлен обратно клиенту. Используя mod_headers, вы можете принудительно указать относительный URL-адрес, вручную удалив схему + имя хоста, как предлагается в в этом ответе StackOverflow :

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

Дополнительная ссылка:

4
ответ дан 3 December 2019 в 09:58

Теги

Похожие вопросы