Назад | Перейти на главную страницу

mod_proxy неправильное поведение перенаправления

В chrome эта конфигурация вызывает бесконечный цикл перенаправления, и в любом другом браузере я пробовал запросить https://www.example.com/servlet/foo приводит к перенаправлению на https://www.example.com/foo/ вместо того https://www.example.com/servlet/foo/ однако это происходит только тогда, когда я не включаю завершающий / в конце URL-адреса запроса (т.е. http://www.flightboard.net/servlet/foo/ работает нормально).

<VirtualHost *:80>
    # ...

    RewriteEngine On

    RewriteCond %{HTTPS} off
    RewriteCond %{REQUEST_URI} ^/servlet(/.*)?$
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    # ...

    ProxyPass /servlet/ ajp://localhost:8009/
    ProxyPassReverse /servlet/ ajp://localhost:8009/
</VirtualHost>

Виртуальный хост на порту 443 не имеет правил перезаписи, которые могли бы вызвать проблему, контексты tomcat, на которые ссылаются, не отправляют никаких перенаправлений, и если я изменю директивы ProxyPass и ProxyPassReverse на:

    ProxyPass / ajp://localhost:8009/
    ProxyPassReverse / ajp://localhost:8009/

все работает нормально (за исключением того факта, что все с www.example.com передается на прокси-сервер, что мне не подходит). Я почти уверен, что это проблема с тем, как у меня настроены настройки прокси, потому что я регистрировал весь вывод перезаписи, исходящий из apache, и все было правильно.

Переход с mod_proxy_ajp на mod_proxy_http, похоже, решает эту проблему.

ProxyPass /servlet/ http://localhost:8080/
ProxyPassReverse /servlet/ http://localhost:8080/

К сожалению, это имеет побочный эффект, заключающийся в том, что IP-адрес удаленного соединения не передается. Другой альтернативой является добавление правила перезаписи для сопоставления URL-адреса с отсутствующей косой чертой в конце:

RewriteCond %{REQUEST_URI} ^/servlet/[^/]+$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}/ [R=301,L]

Я не уверен, что это ваша проблема, но ProxyPassReverse не работает с адресом ajp :. ProxyPassReverse вызывает перезапись заголовков Location:, если они совпадают. Заголовки, сгенерированные перенаправлением, имеют http: URL, а не ajp:

Вы должны уметь использовать:

ProxyPass /servlet/ ajp://localhost:8009/
ProxyPassReverse /servlet/ http://hostname/

т.е. используйте ajp: для прокси-сервера для tomcat, но используйте http: для сопоставления и перезаписи заголовков перенаправления. Возвращенные заголовки также, вероятно, имеют реальное имя хоста сервера вместо localhost. (хотя localhost работает для ProxyPass). Вы можете проверить возвращенные заголовки с помощью 'curl -I', чтобы увидеть, что вам нужно сопоставить.

См. Этот ответ в stackoverflow по некоторым ссылкам.

(Этому вопросу уже пару месяцев, но я столкнулся с той же проблемой, и мне было трудно искать ответ.)