由于PHP 5.5版和curl版本7.51.0的分块请求发生超时,我一直在疯狂。 PHP正在从Scala Play Framework服务请求一组数据,该服务返回一个分块响应。
发生了什么:一旦PHP请求等待下一个块的60秒,它就会以CURL错误18终止。这个相同的端点适用于较小的请求,所以我知道这不是一般的连接问题。
使用此格式的请求通过命令行从PHP框测试端点可以正常工作:
curl -i -X POST -H 'Content-Type: application/json' -d '<Request Params>' <URL>
我的PHP请求(使用guzzle在这里显示,但我也尝试过raw curl exec)看起来像这样:
$client->request('POST', $route, [
// I thought this would work first
'timeout' => 120,
// Maybe some of these other timeouts will help...
'connect_timeout' => 120,
'read_timeout' => 120,
'json' => $body,
'headers' => [
// I found some random SOs that suggest setting headers..
'Connection' => 'close',
'Expect' => '',
'Transfer-Encoding' => 'chunked'
],
'stream' => true,
'curl' => [
// Beginning the descent into insanity
CURLOPT_CONNECTTIMEOUT => 120,
// I don't have a low speed limit set but maybe?
CURLOPT_LOW_SPEED_TIME => 120,
// Perhaps there's a guzzle bug that doesn't set timeout.. NOPE
CURLOPT_TIMEOUT => 120,
// Hey, this one works! We'll see in the curlinfo below
CURLINFO_HEADER_OUT => true,
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => '<logloc>',
// alright this isn't even a socket connection but sure
CURLOPT_FORBID_REUSE => true,
// SET ALL OF THE TIMEOUTS!!
CURLOPT_TCP_KEEPALIVE => 120,
CURLOPT_TCP_KEEPIDLE => 120,
CURLOPT_TCP_KEEPINTVL => 120
]
]);
以上都没有奏效。一些建议建议我将HTTP版本设置为1.0。这是一个不可接受的解决方案,因为从该端点返回的数据需要直接在响应中流式传输(因此stream =&gt; true)。原始卷曲(没有Guzzle)也会出现同样的问题。
除了上述请求设置外,我还设置了以下PHP设置:
set_time_limit(0); // also have set this to large numbers
ini_set("default_socket_timeout", 270); // Have also set this in the PHP.ini
失败回复的卷曲状态为
{
"url": "<URL>",
"content_type": "text/plain; charset=utf-8",
"http_code": 200,
"header_size": 144,
"request_size": 207,
"filetime": -1,
"ssl_verify_result": 0,
"redirect_count": 0,
"total_time": 60.20854, // WHY CRUEL WORLD??
"namelookup_time": 0.124769,
"connect_time": 0.125011,
"pretransfer_time": 0.132244,
"size_upload": 116,
"size_download": 51,
"speed_download": 0,
"speed_upload": 1,
"download_content_length": -1,
"upload_content_length": -1,
"starttransfer_time": 0.132248,
"redirect_time": 0,
"redirect_url": "",
"primary_ip": "<>",
"certinfo": [],
"primary_port": 443,
"local_ip": "<>",
"local_port": 39562,
"request_header": "POST <URL> HTTP/1.1 Host: <HOST> User-Agent: GuzzleHttp/6.2.1 curl/7.51.0 PHP/5.5.38 Content-Type: application/json Connection: close Transfer-Encoding: chunked "
}
然后抛出:
cURL error 18: transfer closed with outstanding read data remaining (see http://curl.haxx.se/libcurl/c/libcurl-errors.html
总结..
我设置了一些超时变量,但我设置的没有一个能够摆脱这种疯狂。有谁能告诉我光明?