Apache的mod_proxy_html与PHP标题(“位置:...”);不重定向

时间:2013-02-26 21:40:07

标签: php redirect http-headers reverse-proxy mod-proxy-html

我已经用谷歌搜索了这个问题的废话并没有提出任何建议,所以希望你们能帮忙。

目标
配置反向代理(使用Apache的mod_proxy)以通过Internet 使用mod_proxy_html在我的应用程序中重写URL来访问内部PHP应用程序。

问题描述
考虑只使用以下代码的landing.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仅适用于Content-Type text / html文件。但是,我不想破解所有对标题的调用(“Location:...”)来使其工作。我不介意更改所有对标题的调用(“位置:...”),假设我正在改变的是纠正问题,而不是创建黑客。

最后,我在反向代理服务器上做了一些数据包嗅探,发现标题(“Location:...”)向反向代理服务器发送了HTTP / 1.1 302 Not Found,但它没有将此传递给请求redirect.php的浏览器。当我尝试上面的一个“解决方案”时,302然后从反向代理服务器传递到请求redirect.php的计算机。 我的理解是Location头应该转到浏览器,然后浏览器应该请求传回的新位置。所以它失败了,因为302没有进入浏览器......

仅供参考,我已经尝试查看错误日志以查看mod_proxy_html是否在某处失败,但我没有看到任何内容,尽管我对日志记录的具体建议持开放态度,因为我不是100%确定我是否正确设置了记录。

对不起,这太长了,只是想尽可能具体。 提前谢谢!

1 个答案:

答案 0 :(得分:0)

我弄明白了这个问题。我需要在头文件Content-Type中显式传递charset才能工作。 这是通过添加:

来完成的
AddDefaultCharset utf-8

到我的Apache配置文件。这全局修复了对标题的所有调用(“Location:...”),而不必向每个标题添加标题(“Content-Type:”)或标题(“Content-Type:text / html; charset = utf-8”)其中之一。

简而言之,我所说的mod_proxy_html的ProxyHTMLLinks会导致302 Found无法从反向代理服务器转发到客户端,如果a)内容类型是text / html(因此也是ProxyHTMLLinks),b )没有设置charset,c)你的页面没有传回内容。

在我看来,这是正常情况。处理表单输入的页面通常符合所有三个标准。

由于某种原因,这可能是预期的功能,而且我正在做其他错误的事情,但我看不出那会是什么。至少在这里有一个优雅的锻炼,万一有人发现它有用。