CURL — неполный ответ, если потокPhp

Кемеровские программисты php общаются здесь
Ответить
Anonymous
 CURL — неполный ответ, если поток

Сообщение Anonymous »

Я делаю запрос cURL, используя PHP-библиотеку GuzzleHttp, которая возвращает мне огромный список данных, которые я позже обрабатываю. Из-за размера и времени отклика я попытался оптимизировать свою сторону, включив опцию потоковой передачи. Поскольку я могу обрабатывать ответ частями, это экономит много памяти, и я могу обработать ответ до того, как сервер вернет все содержимое.
Есть одна проблема, с которой я столкнулся: ответ не является полным. Это как будто часть ответа (зависит, иногда больше половины, иногда только самые последние байты) вырезается и никогда мне не отправляется. Следует отметить, что правильный ответ, сжатый gzip, составляет около 15 МБ.
Мне не разрешено указывать конкретную конечную точку/хост, который я подсказываю, но в основном запрашивается и получается следующая информация:

Код: Выделить всё

GET  HTTP/1.1
Host: 
Accept-Encoding: zstd;q=1.0, br;q=0.9, gzip;q=0.8, deflate;q=0.7, *;q=0.1
TE: traileds, gzip;q=0.9, deflate;q=0.7, compress;q=0.7
Accept: application/json
User-Agent: GuzzleHttp/7
Authorization: 
Настройки Guzzle:

Код: Выделить всё

    [
'headers' => [
'Accept-Encoding' => 'zstd;q=1.0, br;q=0.9, gzip;q=0.8, deflate;q=0.7, *;q=0.1',
'TE' => 'trailers, gzip;q=0.8, deflate;q=0.7, compress;q=0.7',
'Accept' => 'application/json',
],
'timeout' => 60 * 45,
'connect_timeout' => 60 * 45,
'cookies' => false,
'stream' => true,
'allow_redirects' => true,
'http_errors' => true,
'version' => 1.1,
'debug' => true,
],
Отладка (поток включен):

Код: Выделить всё

 [CONNECT]
 [MIME_TYPE_IS] message: "application/json"
 [PROGRESS]
 [PROGRESS] bytes_transferred: "8192"
...
Отладочные сообщения о переданных байтах повторяются до самого конца, увеличивая количество переданных байтов.
Я обрабатываю ответ, используя что-то вроде

Код: Выделить всё

// Ensured that the response is valid
$buffer = '';

while (!$stream->eof()) {
$buffer.=$stream->read(8192);

// here, my handler is able to process the buffer and clear its data if processed. No special-relevant logic here.
}

// For debugging right now:
dump($stream->getMetadata());

// here my handler processes the rest of the buffer. Again, no relevant logic.
Каждый дамп показывал, что поток был правильно завершен - нет тайм-аута (который, как я думал, может произойти) и непрочитанный байт.
Тот же самый запрос со сжатием, та же версия протокола, заголовки.. НО без потока включенная опция Guzzle приводит к правильному телу ответа.
Что я пытался проверить:
  • проблема возникает на разных версиях PHP (Версия PHP не актуальна - 7.4; 8.2)
  • происходит в разных глобальных сетях (не похоже на конкретную сетевую проблему)
  • происходит на разных серверах PHP (не похоже на проблему конкретного устройства)
  • происходит в разных версиях Guzzle (7.8.2-7.10.0)
  • иногда тело ответа является полным (обычно не)
  • увеличение таймаутов (timeout, Connect_timeout, read_timeout) до безумных значений не помогает
  • отключение параметра потока или установка для него значения false (по умолчанию) всегда возвращает полный ответ
Пожалуйста, какие-либо предложения/советы, в чем может быть проблема, как ее решить? Я действительно вижу преимущества в производительности при использовании потока и хотел бы этим воспользоваться.

Подробнее здесь: https://stackoverflow.com/questions/798 ... -if-stream
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Php»