Apache2 mod_proxy 包装 HTTP 标头而不是转发它

Apache2 mod_proxy 包装 HTTP 标头而不是转发它

通过 apache 代理访问 oracle apex 服务器时,我偶尔会收到以下 HTTP 包作为服务器的响应:

Connection:Keep-Alive
Date:Fri, 20 Jan 2017 16:00:24 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.6 () PHP/5.4.16
Transfer-Encoding:chunked

0
HTTP/1.1 200 OK
Server: Oracle XML DB/Oracle Database
Content-Type: text/html; charset=utf-8
Content-Length: 33388

ACTUAL HTML PAGE FROM APEX

我不知道这个 0 是从哪里来的。不过看起来代理将从 APEX 获得的完整 HTTP 响应(包括 HTTP 标头)作为 HTTP 主体包装到另一个 HTTP 包中:

<Apache HTTP PACKAGE>
    <Apache HTTP HEADER>
        Connection:Keep-Alive
        Date:Fri, 20 Jan 2017 16:00:24 GMT
        Keep-Alive:timeout=5, max=100
        Server:Apache/2.4.6 () PHP/5.4.16
        Transfer-Encoding:chunked

    </Apache HTTP HEADER>
    <Apache HTTP BODY>
        0
        <APEX HTTP PACKAGE>
                HTTP/1.1 200 OK
                Server: Oracle XML DB/Oracle Database
                Content-Type: text/html; charset=utf-8
                Content-Length: 33388

                ACTUAL HTML PAGE FROM APEX
        </APEX HTTP PACKAGE>
    </Apache HTTP BODY>
</Apache HTTP PACKAGE>

相反,代理应该只是将 HTTP 包转发给客户端。这样客户端接收 HTTP 包时就好像它来自 APEX 一样,而不知道它是由代理转发的。这在 30 次中有 29 次按预期工作,但有时它的行为如上所述。这是代理中的错误吗?您能建议一种可能的解决方法吗?

答案1

这不是换行,这是由于transfer-encoding: chunked标题造成的。请参阅https://en.wikipedia.org/wiki/Chunked_transfer_encoding

0 是最后一个块的信号。从上面的页面:

每个块都以它嵌入的数据的八位字节数开头,以 ASCII 中的十六进制数表示,后跟可选参数(块扩展)和终止 CRLF 序列,然后是块数据。块以 CRLF 结尾。

终止块是常规块,但其长度为零。它后面是尾部,尾部由一系列(可能为空的)实体标头字段组成。通常,此类标头字段将在消息的标头中发送;但是,在处理整个消息实体后确定它们可能更有效率。在这种情况下,在尾部中发送这些标头很有用。

尝试SetEnv proxy-nokeepalive 1在你的 Apache mod_proxy 配置中。或者尝试

SetEnv proxy-sendcl 1

SetEnv proxy-sendchunked 0

http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#request-bodies以获取解释。

相关内容