Время от времени помогаю знакомым старта́перам в части, относящейся к вебу. В процессе обнаруживаю странное: есть сайты, которыми не сильно можно порулить, даже если и хочется: хостинг-провайдер предоставляет лишь возможность править апачный конфигурационный файл .htaccess
. Всё бы ничего, но между файлами и посетителем сайта не только Apache — там ещё и Nginx, чья конфигурация вообще недоступна.
Сейчас в 2023 году редко какой сайт не использует HTTPS (этот — один из них, но сейчас не о нём речь). Если сайт сделан на какой-нибудь CMS, там вполне может существовать возможность указать в настройках основной адрес сайта и включить перенаправление на него — так можно перенаправляться на использование HTTPS и в WordPress, и в Open Journal Systems.
Но что делать, если сайт — статичный? Вроде бы, можно обойтись средствами самого́ Апача, а точнее, его модуля mod_rewrite — напишем в .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
Этот код включает механизм перенаправлений, проверяет, используется ли HTTPS и если нет — перенаправляет посетителя. Только в нашем случае условие RewriteCond
всегда истинно, что вызывает циклические перенаправления. Причина — Apache в конкретном случае работает всегда по HTTP, поэтому значение переменной HTTPS
— всегда off
. С другими переменными аналогично — например, SERVER_PORT
всегда равен 80.
В случае, когда есть доступ к настройкам Nginx, проблем нет — всё настраивается там. Но если нет, приходится искать другие переменные, которые однозначно покажут, как именно посетитель обращается к сайту. Nginx, передавая запрос Апачу, добавляет в него поля, чьи имена начинаются с X-Forwarded
— среди них есть и X-Forwarded-Proto
, где хранится запрашиваемый посетителем протокол — http
или https
. В итоге работоспособным оказался такой код:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
Может возникнуть вопрос — нельзя ли в условии вместо !https
написать более короткое http
? Оказалось, что нет — сама по себе строка без знака равенства не проверяется на совпадение, а сопоставляется с образцом, то есть, происходит pattern matching. А такому условию удовлетворяли бы оба рассмотренных значения и условие всегда оказывалось бы истинным, что снова бы вызвало циклические перенаправления.
Вы должны авторизоваться чтобы опубликовать комментарий.