Я спросил только так, чтобы я мог ответить на вопрос, главным образом потому, что я нигде не мог найти решение.
Справочная информация:
То, как Network Solutions управляет своими системами общего хостинга, вы фактически не подключаетесь к серверу, вы подключаетесь к прокси-серверу (это имеет смысл). Когда вы выполняете перенаправление https, как:
RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://[domain_redacted]/$1 [R=301,L]
Вы фактически перенаправляете страницу на HTTPS. Однако вы выполняете транзакцию HTTPS с прокси-сервером, а не с хост-сервером. Прокси-сервер преобразует ваше HTTPS-соединение с ним в HTTP через порт 80. При попытке обнаружить это с помощью .htaccess сервер не видит HTTPS, потому что соединение между вашим хост-сервером и прокси-сервером всегда будет HTTP на порту 80. PHP извлекает переменную HTTPS из Apache, он будет иметь тот же результат, что и обнаружение HTTP через .htaccess.
Поэтому, если я не ошибаюсь, невозможно выполнить перенаправление с самоотсылкой HTTP на HTTPS при использовании общего хостинга от Network Solutions. Запрос должен как-то измениться (либо путем изменения URI, либо строки запроса), чтобы сервер мог обнаружить это изменение. Это, конечно, полностью подделка (например, независимо от того, как вы измените URI / строку запроса, можно просто ввести его в браузере как http, и сервер никогда не узнает), сводя на нет весь смысл HTTPS.
Я попытался проверить, ссылается ли% {HTTP_REFERER} на себя, но он не использует mod_rewrite.
Единственный обходной путь, который я могу найти, - это обнаружение на стороне клиента с помощью javascript. Это имеет свои подводные камни (NoScript и т. Д.). Но я не могу найти другое решение проблемы. Следующий код будет приблизительно перенаправлять 301.
if(document.URL.match(/^https/i) == null) {
var NetworkSolutionsSucks = document.createElement('meta');
with (NetworkSolutionsSucks) {
httpEquiv = 'refresh';
content = '0;url=' + document.URL.replace(/^http/i,'https');
}
document.head.appendChild(NetworkSolutionsSucks);
var msg = document.createElement('div');
with (msg) {
innerHTML = 'This page requires a secure connection, you are being redirected.<br><br>';
innerHTML += 'If the page does not load, please click <a href="' + document.URL.replace(/^http/i,'https') + '">Here</a>';
}
var newBody = document.createElement('body');
newBody.appendChild(msg);
document.replaceChild(newBody, document.body);
}
Включите приведенный выше скрипт в заголовок любого документа, для которого вы хотите использовать HTTPS (форсирование HTTP оставлено в качестве упражнения для читателя - это более простой скрипт, не требующий ручного перенаправления при некотором сбое). Вы должны использовать тег noscript с этим (очевидно); Вы можете использовать следующее:
<noscript id="networkSolutionsHTTPSRedirect">This site requires javascript in order to operate properly. Please enable javascript and refresh this page.</noscript>
<style type="text/css">#networkSolutionsHTTPSRedirect{position: fixed; height: 100%; width: 100%; top: 0; left: 0; z-index: 500;}</style>
<script type="text/javascript">
<!--
document.getElementById("networkSolutionsHTTPSRedirect").style.visibility = "hidden";
document.getElementById("networkSolutionsHTTPSRedirect").style.display = "none";
-->
</script>
РЕДАКТИРОВАТЬ: я нашел способ сделать это на стороне сервера:
Вы можете попытаться принудительно заставить HTTPS весь сайт, если на каждой странице вы делаете следующее:
<?php
if((!isset($_ENV['HTTP_REFERER']) || preg_match('/^http[s]{0,1}:\/\/' . $_ENV['SERVER_NAME'] . '/i',$_ENV['HTTP_REFERER']) == 0) && !isset($_ENV[HTTP_X_HTTPS_REDIRECT])) {
header('X-HTTPS-REDIRECT: true\n');
header('Location:' . preg_replace('/^http/','https', $_ENV['SCRIPT_URI']));
}
?>
Это должно привести к перенаправлению на все запросы, для которых не установлен HTTP_REFERER на вашем сайте и которые не содержат пользовательский заголовок X-HTTPS-REDIRECT, который вы вводите. Это на самом деле не обнаруживает HTTPS, но выполняет разумную факсимильную связь (по крайней мере, на стороне сервера).
Конечно, вы можете изменить регулярное выражение так, чтобы только HTTPS должен был быть только для определенных сайтов, сопоставив REFERER с той частью вашего домена, которую вы хотите защитить, и затем отмените тест для принудительного использования HTTP.