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) кодировка не установлен и в) на вашей странице нет контента, который был передан обратно.

На мой взгляд, это нормальный сценарий. Страницы, которые обрабатывают входные данные формы, часто соответствуют всем трем критериям.

Возможно, по какой-то причине это предполагаемая функциональность, и что я делаю что-то еще неправильно, но я не вижу, что это будет. По крайней мере, здесь есть элегантная тренировка на случай, если кто-нибудь найдет ее полезной.

Другие вопросы по тегам