ZF-2098: Problem with Content-Length value using raw POST data with mbstring extension

Issue Type: Bug Created: 2007-10-24T15:36:53.000+0000 Last Updated: 2009-11-17T20:52:37.000+0000 Status: Resolved Fix version(s): - 1.9.0 (31/Jul/09)

Reporter: Brian DeShong (bdeshong) Assignee: Shahar Evron (shahar) Tags: - Zend_Http_Client

Related issues: - ZF-6218



When using Zend_Http_Client to POST raw data, the strlen() function is called to determine the value for the Content-length header. However, when using the mbstring extension and overriding the string functions (mbstring.func_overload = 4), the strlen() call (which is overridden using mb_strlen()) must be made with the second argument of "ASCII". With string functions overridden by mbstring, the byte count of the raw POST data is less than its actual size as multibyte characters will be counted a single character.

The patch below corrects the problem by performing an ini_get() and checking the value to see if the bit for string function overriding is set. If it is, the Content-length will be set accordingly by calling $this->setHeaders('content-length', strlen($this->raw_post_data, 'ASCII'));.

This patch was generated against trunk as of 10/24/2007.

<pre class="highlight">
--- library/Zend/Http/Client.php    (revision 6682)
+++ library/Zend/Http/Client.php    (working copy)
@@ -913,7 +913,15 @@

         // If we have raw_post_data set, just use it as the body.
         if (isset($this->raw_post_data)) {
-            $this->setHeaders('Content-length', strlen($this->raw_post_data));
+            // If user is not overriding string functions with mbstring, the
+            // call to strlen() with the data is sufficient.  Otherwise,
+            // ensure that we have the ASCII byte count for the POST data.
+            if (!ini_get('mbstring.func_overload') & 4) {
+                $this->setHeaders('content-length', strlen($this->raw_post_data));
+            } else {
+                $this->setHeaders('content-length', strlen($this->raw_post_data, 'ASCII'));
+             }
             return $this->raw_post_data;


Posted by Wil Sinclair (wil) on 2008-03-25T20:37:21.000+0000

Please categorize/fix as needed.

Posted by Benjamin Eberlei (beberlei) on 2008-11-15T10:02:50.000+0000

First: the bitmask is 2 for str functions not 4.

Second, I cannot reproduce this issue, either with a setting in php.ini oder with ini_set. my testcase looks as following:

This is added into Zend_Http_Client_TestAdapterTest.

<pre class="highlight">    /**
     * Tests that overriding strlen with mb_strlen via php.ini option is recognized.
     * @group ZF-2098
    public function testStrlenFunctionOverrideByMbstringIsRecognized()
        $client = new Zend_Http_Client('<a href=""></a>', array('adapter' => $this->adapter));
        $string = "asdföäü€";

        $previousSetting = ini_get("mbstring.func_overload");

        ini_set("mbstring.func_overload", 0);

        echo $client->getLastRequest();

        ini_set("mbstring.func_overload", 2);

        echo $client->getLastRequest();

any additional feedback or a fixed testsuite?

Posted by Brian DeShong (bdeshong) on 2008-11-15T14:56:44.000+0000

A thread was started on the forums about this bug about a year ago:…

I'm looking to try and reproduce it again. The particular use case I was running into was when POSTing the raw contents of a binary file to a virus scanning HTTP service.

In that case, if the file was, say, 500 bytes, the Content-Length header was being set to less than 500 bytes because certain multi-byte characters were being counted as 1 byte instead of 2.

I'm taking a look into this now to try to reproduce.

Posted by Brian DeShong (bdeshong) on 2008-11-15T15:28:37.000+0000

I was able to reproduce this using an older version of Zend Framework and 1.6.2 on a RHEL4 machine.

My file is 19,620 bytes on disk. $string is the value of file_get_contents() for the file on disk. In this case, I've got mbstring.func_overload set to 6.

print "ASCII strlen = " . strlen($string) . "\n"; print "mb strlen = " . mb_strlen($string) . "\n"; print "mb strlen ASCII = " . mb_strlen($string, 'ASCII') . "\n";


ASCII strlen = 13389 mb strlen = 13389 mb strlen ASCII = 19620

...which means that Content-Length is being set to 13,389 bytes in the HTTP request:

POST / HTTP/1.1 Host: localhost Connection: close Accept-encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded User-Agent: Zend_Http_Client Content-Length: 13389

This is using PHP 5.2.2. Note that I was NOT able to reproduce this on my Mac running Leopard and PHP 5.2.6, which is surprising.

Hope this helps! Sorry, though, it's been quite some time since I've looked into this issue.

Posted by Shahar Evron (shahar) on 2008-11-17T10:15:41.000+0000

I was able to reproduce and create some tests for this, and it seem to depend on the current locale. I will try to share some tests and perhaps some fix code later this week.

Posted by Shahar Evron (shahar) on 2009-07-24T11:24:38.000+0000

Surprisingly, I actually fixed this in rev. 17041.

Posted by Satoru Yoshida (satoruyoshida) on 2009-11-17T20:52:37.000+0000

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

Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.