Чтение заголовков прогресса запроса скручивания с помощью Guzzle - PullRequest
0 голосов
/ 22 октября 2018

При вызове curl с помощью php, я могу перехватить обратный вызов на CURLOPT_PROGRESSFUNCTION и прочитать заголовки во время выполнения запроса, используя curl_multi_getcontent($handle)

$handle = curl_init()
curl_setopt(CURLOPT_NOPROGRESS, false)
curl_setopt(CURLOPT_RETURNTRANSFER, true)
curl_setopt(CURLOPT_PROGRESSFUNCTION, function($handle) {
   $response = curl_multi_getcontent($handle);
   // some logic here
})
curl_exec($handle)

Как это сделать с помощью Guzzle?

Проблема в том, что я не могу использовать curl_multi_getcontent($handle) без установки CURLOPT_RETURNTRANSFER на true.

Но когда я установил CURLOPT_RETURNTRANSFER в конфигурацию curl curzzle, я смогу прочитать заголовки в функции выполнения $response = curl_multi_getcontent($handle); Однако поток ответов содержит пустое содержимое.

$request->getResponse()->getBody()->getContents(); // always outputs ""

Редактировать: У меня естьсделал это изменение https://github.com/guzzle/guzzle/pull/2173, чтобы я мог получить доступ к обратному обратному вызову дескриптора с настройками прогресса:

'progress' => function($handle) {
   $response = curl_multi_getcontent($handle);
   // some logic here
})

Это работает, пока CURLOPT_RETURNTRANSFER равно true.Однако, как я упоминал ранее, содержание ответа "" затем.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Я нашел решение или, скорее, объяснение, почему это происходит.

По умолчанию Guzzle устанавливает параметр CURLOPT_FILE, когда пользовательский приемник не определен (или CURLOPT_WRITEFUNCTION, когда приемник определен, но это не такдействительно важно на самом деле).

Однако установка CURLOPT_RETURNTRANSFER на true отменяет обе эти опции -> они больше не применяются.

После установки CURLOPT_RETURNTRANSFER:

:
  1. после считывания ответа можно прочитать PROGRESSFUNCTION с $response = curl_multi_getcontent($handle).Для этого необходима модификация Guzzle https://github.com/guzzle/guzzle/pull/2173
  2. Ответ возвращается, когда Guzzle вызывает curl_exec($handle) в качестве возвращаемого значения этого вызова.Но Guzzle не присваивает его какой-либо переменной, потому что ожидает, что ответ не будет возвращен туда, а через WRITEFUNCTION, который, однако, был нейтрализован установкой CURLOPT_RETURNTRANSFER.

Так что мое решение несамый чистый, но я не нахожу другого способа обойти это с Guzzle.Жадность просто не создана, чтобы справиться с этим.

Я раздвоил Жадность.Затем создал пользовательский класс Stream, который ведет себя как приемник по умолчанию ->, записывающий в php://temp.И когда мой пользовательский класс Stream установлен как приемник, я записываю результат curl_exec в поток:

$result = curl_exec($easy->handle);
$easy->sink->write($result);
0 голосов
/ 22 октября 2018

Существует опция запроса прогресса.

// Send a GET request to /get?foo=bar
$result = $client->request(
    'GET',
    '/',
    [
        'progress' => function(
            $downloadTotal,
            $downloadedBytes,
            $uploadTotal,
            $uploadedBytes
        ) {
            //do something
        },
    ]
);

http://docs.guzzlephp.org/en/stable/request-options.html#progress

...