Chunked Requests上的PHP CURL错误18(隐藏超时变量)

时间:2017-09-29 00:19:36

标签: php scala curl guzzle chunked

由于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

总结..

我设置了一些超时变量,但我设置的没有一个能够摆脱这种疯狂。有谁能告诉我光明?

0 个答案:

没有答案