我有一个XML-over-HTTP服务长期以来一直运行良好,我被要求提供一些示例PHP代码来连接它。我已经编写了代码并且连接等等,除此之外 在完成之前它正在等待保持活动超时(5s)。
当我使用基于Java的客户端连接时,我可以看到Tomcat(通过httpd)正在使用分块编码:
DEBUG: Request properties:
DEBUG: Accept-Charset: UTF-8, ISO-8859-1, *
DEBUG: Cache-Control: private, no-cache, no-store, no-transform
DEBUG: Accept: application/xml, text/xml, text/plain
DEBUG: User-Agent: My Awesome Java Client
DEBUG: Pragma: no-cache
DEBUG: Accept-Encoding: gzip, deflate
DEBUG: Content-Type: application/xml
DEBUG: Received first response packet after 219ms
DEBUG: Dumping HTTP response headers
DEBUG: Transfer-Encoding: chunked
DEBUG: Keep-Alive: timeout=5, max=100
DEBUG: null: HTTP/1.1 200 OK
DEBUG: Server: Apache/2.2.22 (Debian)
DEBUG: Connection: Keep-Alive
DEBUG: Date: Fri, 03 Feb 2017 15:33:13 GMT
DEBUG: Content-Type: application/xml;charset=UTF-8
DEBUG: Read response in 7ms
当我使用PHP客户端时,这是我在响应头中得到的内容:
array(6) {
[0]=>
string(15) "HTTP/1.1 200 OK"
[1]=>
string(35) "Date: Fri, 03 Feb 2017 15:37:01 GMT"
[2]=>
string(30) "Server: Apache/2.2.22 (Debian)"
[3]=>
string(30) "Keep-Alive: timeout=5, max=100"
[4]=>
string(22) "Connection: Keep-Alive"
[5]=>
string(43) "Content-Type: application/xml;charset=UTF-8"
}
请注意,没有任何Transfer-Encoding: chunked
响应标头。
我可以确认PHP客户端正在发出HTTP / 1.1请求(和 你可以看到响应正在使用HTTP / 1.1)但是分块编码 似乎没有在使用,这里。
我相信我从PHP客户端发送相同的请求标头。 这是服务器看到的内容:
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] ========== Request from x.y.113.203
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] host: example.com
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] content-length: 135
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] content-type: application/xml
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] user-agent: My Awesome PHP Client
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] accept: application/xml, text/xml, text/plain
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] Accept-Charset: UTF-8, ISO-8859-1, *
2017-02-03 10:44:59,288 [catalina-exec-2] TRACE MyServlet- [1d] Accept-Encoding: gzip, deflate
2017-02-03 10:44:59,288 [catalina-exec-2] TRACE MyServlet- [1d] Cache-Control: private, no-cache, no-store, no-transform
2017-02-03 10:44:59,288 [catalina-exec-2] TRACE MyServlet- [1d] pragma: no-cache
2017-02-03 10:44:59,288 [catalina-exec-2] TRACE MyServlet- [1d] connection: keep-alive
来自Java客户端的相同内容:
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] ========== Request from x.y.113.203
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] user-agent: My Awesome Java Client
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] content-type: application/xml
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] accept: application/xml, text/xml, text/plain
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] Accept-Encoding: gzip, deflate
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] Accept-Charset: UTF-8, ISO-8859-1, *
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] Cache-Control: private, no-cache, no-store, no-transform
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] pragma: no-cache
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] host:
example.com
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] connection: keep-alive
2017-02-03 10:46:33,685 [catalina-exec-3] TRACE MyServlet- [1e] content-length: 135
我正在使用相同的“呼叫”有效负载,响应应该相同 为两个客户。
如果我将Connection: close
添加到PHP客户端的标题中
呼叫在没有5秒延迟的情况下立即完成。
PHP被记录为支持分块编码,但服务器没有 看起来它甚至试图使用分块编码,因为响应 标题没有说什么。 PHP代码如下所示:
$options = array(
'http' => array(
'header' => array('Content-Type: application/xml',
'User-Agent: My Awesome PHP Client',
'Accept: application/xml, text/xml, text/plain',
'Accept-Charset: UTF-8, ISO-8859-1, *',
'Accept-Encoding: gzip, deflate',
'Cache-Control: private, no-cache, no-store, no-transform',
'Pragma: no-cache',
// NOTE: Connection: close makes multiple calls less efficient, but file_get_contents seems to stall otherwise
// 'Connection: close'
'Connection: keep-alive',
),
'follow_location' => 0, // Don't follow redirects
'protocol_version' => '1.1',
'ignore_errors' => TRUE, // Does not dump ugly errors to stderr
'timeout' => 0.01, // TODO: adjustable
'method' => 'POST',
'content' => $message,
),
'ssl' => array(
'disable_compression' => TRUE,
'ciphers' => '!aNULL:!eNULL:!EXPORT:!DSS:!DES:!3DES:!SSLv2:!RC4:!MD5:ECDHE:ECDH',
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
var_dump($http_response_header);
关于可能发生的事情的任何想法?我相信如果使用chunked-encoding,当响应实际完成时,客户端不会停止等待更多信息。
请注意,响应必须是分块或超时,因为响应的动态和流式特性不能预先计算并在HTTP响应头中发送content-length
。