Apache mod_proxy_html с заголовком PHP (Location:); не перенаправляет

Я погуглил эту проблему и ничего не нашел, так что, надеюсь, вы, ребята, сможете помочь.

Цель
Настроить обратный прокси-сервер (используя mod_proxy Apache), чтобы обеспечить доступ к внутреннему приложению PHP через Интернет используя mod_proxy_html для перезаписи URL-адресов в моем приложении.

Описание проблемы
Рассмотрим лендинг.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", он должен вернуть меня на страницу лендинг.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. Однако я не хочу взламывать все вызовы header("Location:..."), чтобы это работало. Я не возражаю против изменения всех вызовов header("Location:..."), предполагая, что я меняю исправление проблемы, а не взлом.

Наконец, я провел анализ пакетов на обратном прокси-сервере и обнаружил, что заголовок ("Расположение:...") отправляет сообщение HTTP/1.1 302 Not Found обратному прокси-серверу, но не передает его через в браузер, запрашивающий redirect.php. Когда я пробую одно из «решений» выше, 302 затем передается с обратного прокси-сервера на компьютер, запрашивающий redirect.php. Насколько я понимаю, заголовок Location должен перейти в браузер, а затем браузер должен запросить новое местоположение, переданное обратно. Так что это терпит неудачу, потому что 302 не доходит до браузера...

К вашему сведению, я пытался просмотреть журналы ошибок, чтобы увидеть, не происходит ли где-то сбой mod_proxy_html, но я ничего не вижу, хотя я открыт для конкретных предложений относительно ведения журнала, поскольку я не уверен на 100%. Настраиваю регистрацию правильно.

Извините, что так длинно, просто пытаюсь быть как можно более конкретным. Заранее спасибо!


person tjbourke    schedule 26.02.2013    source источник


Ответы (1)


Я понял проблему. Мне нужно было явно передать кодировку в заголовке Content-Type, чтобы это работало. Это было достигнуто путем добавления:

AddDefaultCharset utf-8

в мой конфигурационный файл Apache. Это глобально исправило все вызовы header("Location:...") без добавления header("Content-Type:") или header("Content-Type:text/html;charset=utf-8") к каждому один из них.

Короче говоря, я говорю о том, что ProxyHTMLLinks mod_proxy_html приводит к тому, что 302 Found не перенаправляется с обратного прокси-сервера клиенту, если а) применяется тип содержимого text/html (и, следовательно, ProxyHTMLLinks), б) кодировка не установлен и c) на вашей странице нет переданного содержимого.

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

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

person tjbourke    schedule 27.02.2013