Apache mod_proxy_html с PHP-заголовком ("Местоположение:..."); не перенаправляет
Я вырвал дерьмо из этой проблемы и ничего не придумал, так что, надеюсь, вы, ребята, сможете помочь.
Цель
Сконфигурируйте обратный прокси-сервер (используя Apache mod_proxy), чтобы разрешить доступ к внутреннему PHP-приложению через Интернет, используя mod_proxy_html для перезаписи URL-адресов в моем приложении.
описание проблемы
Рассмотрим файл collection.php только с этим кодом:
<a href="redirect.php">redirect.php</a>
и redirect.php только с:
<?php
header("Location:http://internal.example.com/landing.php");
?>
с этим фрагментом из моего httpd.conf
UseCanonicalName On
LoadFile /usr/lib64/libxml2.so
LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule xml2enc_module modules/mod_xml2enc.so
<VirtualHost *:80>
ServerName example.com
<Proxy *>
Order deny,allow
Allow from all
AllowOverride None
</Proxy>
ProxyPass / http://internal.example.com/
ProxyPassReverse / http://internal.example.com/
ProxyHTMLLinks a href #Commenting out this line fixes the problem, but I need it for rewriting
ProxyHTMLEnable On
RequestHeader unset Accept-Encoding
</VirtualHost>
Когда я захожу на http://example.com/landing.php и нажимаю "redirect.php", я должен вернуться на страницу landing.php. Вместо этого я получаю "Это соединение было сброшено" в Firefox или "Данные не получены" в Chrome. (К вашему сведению, http://internal.example.com/redirect.php перенаправляет правильно.)
Вопрос:
Почему перенаправление не проходит через обратный прокси-сервер, и как я могу это исправить?
Советы
Я обнаружил несколько вещей, которые могут быть полезны...
Я знаю, что если я закомментирую "ProxyHTMLLinks a href", это будет работать правильно. Но, очевидно, мне нужна эта функция переписывания.
Я также могу изменить страницу redirect.php на следующее, это работает правильно:
<?php
header("Location:http://internal.example.com/landing.php");
?>
random text
Я предполагаю, что этот текст каким-то образом что-то делает со страницей или заголовками HTTP, которые заставляют mod_proxy_html (или, более конкретно, ProxyHTMLLinks) работать иначе, чем без него.
Я также могу изменить страницу redirect.php на следующую, и она будет работать:
<?php
header("Location:http://internal.example.com/landing.php");
header("Content-Type:");
?>
Это работает, потому что ProxyHTMLLinks по умолчанию применяется только к текстовым / html-файлам Content-Type. Тем не менее, я не хочу взламывать все вызовы заголовка ("Location:..."), чтобы сделать эту работу. Я не против изменить все вызовы заголовка ("Location:..."), предполагая, что я изменяю, исправляя проблему, а не создавая взлом.
Наконец, я провёл некоторый анализ пакетов на обратном прокси-сервере и обнаружил, что заголовок ("Location:...") отправляет HTTP/1.1 302 Not Found обратному прокси-серверу, но не пропускает его через в браузер, запрашивающий redirect.php. Когда я пробую одно из "решений" выше, 302 затем передается с обратного прокси-сервера на компьютер, запрашивающий redirect.php. Насколько я понимаю, заголовок Location должен перейти в браузер, а затем браузер должен запросить новое местоположение, переданное обратно. Так что это терпит неудачу, потому что 302 не доходит до браузера...
К вашему сведению, я попытался просмотреть журналы ошибок, чтобы увидеть, не происходит ли где-нибудь ошибка mod_proxy_html, но я ничего не вижу, хотя я открыт для конкретных предложений относительно ведения журнала, так как я не уверен на 100%, если я устанавливаю регистрацию правильно.
Извините, это так долго, просто пытаюсь быть как можно более конкретным. Заранее спасибо!
1 ответ
Я понял проблему. Мне нужно было явно передать кодировку в заголовок Content-Type, чтобы это работало. Это было достигнуто путем добавления:
AddDefaultCharset utf-8
в мой файл конфигурации Apache. Это глобально исправило все вызовы заголовка ("Location:...") без необходимости добавлять заголовок ("Content-Type:") или заголовок ("Content-Type:text/html;charset=utf-8") к каждому один из них.
Короче говоря, то, что я говорю, что ProxyHTMLLinks в mod_proxy_html приводит к тому, что 302 Found не будет пересылаться с обратного прокси-сервера клиенту, если: a) тип содержимого - text/html (и, следовательно, ProxyHTMLLinks), b) кодировка не установлен и в) на вашей странице нет контента, который был передан обратно.
На мой взгляд, это нормальный сценарий. Страницы, которые обрабатывают входные данные формы, часто соответствуют всем трем критериям.
Возможно, по какой-то причине это предполагаемая функциональность, и что я делаю что-то еще неправильно, но я не вижу, что это будет. По крайней мере, здесь есть элегантная тренировка на случай, если кто-нибудь найдет ее полезной.