Я схожу с ума из-за тайм-аута, возникающего при фрагментарных запросах с 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-запрос (с использованием жадности, показанной здесь, но я также пробовал 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 => 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
Подводить итоги..
Я установил несколько переменных тайм-аута, но ни одна из них, которые я установил, не смогла избавить меня от этого безумия. Кто-нибудь может показать мне свет?
Задача ещё не решена.
Других решений пока нет …