为什么基于PHP的HTTP请求无法允许分块编码?

时间:2017-02-07 18:16:41

标签: php http chunked-encoding

我有一个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

0 个答案:

没有答案