Со следующим правилом:
# 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]
Но я хотел понять это поведение.
Спасибо за любое объяснение.
Все внешние перенаправления (флаг 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.-]+" ""
Дополнительная ссылка: