ZF-6218: Invalid chunk size in Zend_Http_Client_Adapter_Socket problem with strlen


In some cases Zend_Http_Client_Adapter_Socket fails to correctly read chunked answer from server. I figured out this on one server with PHP 5.2.5 (as I can remember). The problem was with strlen function - it returns not actual bytes in string and makes problem with reading chunk. I suggest to use ftell function instead of relying on strlen.

Here is my patch for Zend/Http/Client/Adapter/Socket.php (Zend Framework 1.7.8).

<                     $left_to_read = $chunksize;
<                     while ($left_to_read > 0) {
<                         $line = @fread($this->socket, $left_to_read);
>                     $read_to = ftell($this->socket) + $chunksize;
>                     while ($read_to > ftell($this->socket)) {
>                         $line = @fread($this->socket, $read_to - ftell($this->socket));
<                             $left_to_read -= strlen($line);

P.S. I know that PHP is binary safe but I can't explain error with strlen function (or fread?) on that server (it's not mine and with suhosin patch), but this patch works for me fine.


This is because mbstring.func_overload is in use, and the website contains multibyte characters. I cannot use Zend_Http_Client against any Chinese website, eg.

Working on another patch...

Hmm needs a fix in ->getBody() of the response object too...

Patch to fix chunked encoding

To be more accurate, this happens when: - mbstring is loaded - mbstring.func_overload & 2 - mbstring.internal_encoding is a multibyte-encoding

This is pretty hard to reproduce for those who don't have that setup - but I've added some unit tests that catch this (given the right php.ini configuration) and will look into solving this. This is actually a bigger problem, and affects several other places in Zend_Http and Zend_Uri. It was solved for Zend_OpenId by implementing a dedicated strlen() wrapper (see Zend_OpenId::strlen())

Resolved in rev. 17041 along with another related issue in Http_Client.

BTW thanks for the ftell() idea - that worked well although I reduced the number of calls. I used mb_internal_encoding everywhere else, just to avoid the consecutive if() calls.

I set fix version . I find at SVN r17118 in 1.9 branch.