通过 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以获取解释。