Too much content was extracted from the stream (* instead of * bytes) Zend\Http\Headers Object while trying Data Streaming with Zend\Http\Client

I was having fun with Zend\Http\Client and wanted to try Data Streaming for downloading larger files. But there was a strange problem – downloads were aborted and an exception was thrown with the message:

Too much content was extracted from the stream
(976 instead of 687 bytes) Zend\Http\Headers Object

I did mostly everything as described in the documentation, so in general:

$client->setStream();
$response = $client->send();

but every time a few seconds after $client->send():

PHP Fatal error:  
Uncaught exception 'Zend\Http\Exception\OutOfRangeException'
with message 'Too much content was extracted from the stream
(976 instead of 687 bytes)' in ...

First I thought, that’s maybe something related to compression (Accept-encoding) and tried to play with it, but nothing has changed. Than I came to the brilliant idea to check my HTTP clients initialization options, and there was the problem. I was initializing the client with the following options:

$options = array(
    'maxredirects'    => 2,
    'strictredirects' => false,
    'useragent'       => 'Mozilla/5.0 (X11; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0',
    'timeout'         => 30,
    'httpversion'     => '1.1',
    'adapter'         => 'Zend\Http\Client\Adapter\Curl',
    'curloptions'     => array(
        CURLOPT_SSL_VERIFYPEER => false
    ),
    'keepalive'       => false,
    'storeresponse'   => true,
    'encodecookies'   => true,
    'outputstream'    => false,
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    'rfc3986strict'   => false,
);

so I checked the docs for HTTP Client Configuration Options again and changed outputstream to true and that solved the problem :-)

Because all this happened in a class that is reusing a single HTTP client for different requests, and this client is initially configured with outputstream set to false (and I want to have it this way), I tried to modify my code in this concrete method:

$client->setOptions(array('outputstream' => true));
$client->setStream();
$response = $client->send();

or

$client->setStream();
$client->setOptions(array('outputstream' => true));
$response = $client->send();

so it can “switch” streaming on for the already instantiated HTTP client, but this didn’t help.

So probably the only way is to instantiate another HTTP client with outputstream set initially to true and use it for streaming. That’s the way I’ve figured out, maybe there’s a better solution. Let’s see ;)

Leave a Reply