Я работаю над веб-приложением Java, размещенным на сервере Tomcat. Мне нужно настроить перенаправление с www на не-www и с http на https. Мне нужны следующие три URL:
перенаправить на
Для этого я использую UrlRewriteFilter версии 4.0.3 от tuckey.org. Вот мой файл urlrewrite.xml:
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite>
<rule>
<name>Redirect www to non-www and http to https</name>
<condition type = "request-url" operator = "equal">(^http://example.com|^http://www.example.com|^https://www.example.com)</condition>
<from>^(.*)$</from>
<to type = "permanent-redirect" last = "true">https://example.com$1</to>
</rule>
</urlrewrite>
Перенаправления работают, но веб-сайт не загружается, а в браузере отображается сообщение:
This page isn’t working
example.com redirected you too many times.
Я использовал средство проверки перенаправления и обнаружил, что после первоначального перенаправления на https://example.com/ следует еще одно перенаправление на https://example.com/, а затем еще одно и так далее - URL-адрес перенаправляется на себя. Я не понимаю, что порождает этот бесконечный цикл. Любая помощь будет оценена по достоинству!
Обновление: у меня пока нет решения. Если я удалю первый URL из элемента условия, два других перенаправления будут работать, и все будет в порядке, но вопрос в том, как настроить перенаправление из http://example.com.
Я попробовал другой подход - настроить перенаправление на https в файле web.xml, вставив следующий код:
<security-constraint>
<web-resource-collection>
<web-resource-name>all</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
Результат тот же - https://example.com перенаправляет на себя в бесконечном цикле. Единственная разница в этом случае заключается в том, что перенаправления имеют код состояния 302. Есть идеи о том, что вызывает эту проблему и как ее решить?
Обновление: вот результат выполнения команды curl при использовании UrlRewriteFilter:
Результаты запуска: curl http://example.com
HTTP/1.1 301 Moved Permanently
Server: nginx admin
Date: Fri, 04 May 2018 13:24:16 GMT
Content-Type: text/plain
Content-Length: 0
Connection: keep-alive
Location: https://example.com/
X-Cache: HIT from Backend
Результаты запуска: curl https://example.com/
HTTP/1.1 301 Moved Permanently
Date: Fri, 04 May 2018 11:58:51 GMT
Server: Apache-Coyote/1.1
Location: https://example.com/
Content-Length: 0
Content-Type: text/plain
@Jokkeri Да, я уже пробовал <condition type = "scheme" operator = "equal">^http$</condition> и <condition type = "scheme" operator = "notequal">^https$</condition>. Это тоже не работает.
Не уверен, что побег будет иметь значение, но попробуйте что-нибудь вроде этого: ^(http://example.com(.*)|http://www.example.com(.*)|https://www.example.com(.*))
Посмотрим, поможет ли эта ветка stackoverflow.com/questions/44953464/…
@ Rick77 Судя по вашим примерам curl, у вас запущен nginx. Это правильно? Определить схему может быть сложнее, потому что nginx подключается к Tomcat через простой HTTP - см. этот ответ. Это объясняет, почему удаление первого URL-адреса из вашего условия работает нормально (для example.com больше нет правила). Посмотрите на другой ответ тот же вопрос, который может дать вам подсказку, как применить настраиваемый заголовок, который вы могли бы использовать для определения схемы. Или вы можете обработать перенаправление в nginx.
@FranzFellner Спасибо за ваш комментарий, это очень полезно. В моем случае заголовок x-forwarded-proto не установлен, и у меня нет доступа к nginx на производственном сервере. Поэтому мне придется попросить хостинг-провайдера выполнить настройку.




Я бы упростил правило, как показано ниже
<rule>
<name>Ensure HTTPS</name>
<condition type = "scheme" operator = "notequal" next = "or">https</condition>
<condition name = "host" operator = "notequal">www.example.com</condition>
<from>^/(.*)$</from>
<to type = "redirect">https://example.com/$1</to>
</rule>
Также убедитесь, что сертификат действителен для example.com, а также указан в потоке ниже.
UrlRewriteFilter: перенаправление www и https
Правило выглядит лучше написанным таким образом, но это не решает проблемы. Сертификат действителен как для example.com, так и для www.example.com.
Можете ли вы добавить к своему вопросу вывод curl -v https://example.com/? Также подключаетесь напрямую к серверу или к любому другому веб-серверу между ними?
Мои знания о curl могут быть немного устаревшими, но я подумал, что вам нужно выполнить curl -L url, чтобы следовать перенаправлениям.
Кроме того, вы уверены, что проблема не в вашем клиенте?
У меня не установлен curl, и я использую онлайн-инструмент для его запуска. Так что проблема не в моем клиенте. Если я запускаю curl –L http://example.com, я получаю сообщение об ошибке (я думаю, из-за бесконечного цикла перенаправления).
Кажется, ответ от https://example.com всегда имеет заголовки ниже:
Location: https.example.com
response Code: 301
Действия и перенаправление - это поведение браузера. Возможно, вам потребуется найти способ удалить эти заголовки. Надеюсь, это поможет в какой-то степени.
Можете ли вы установить условие на (псевдо): (ifNotStartsWith (https) | ^ example.com) Не уверен в синтаксисе (регулярное выражение?) Здесь, но в любом случае, если URL-адрес не HTTPS, вы всегда хотели бы перенаправить, верно?