possible bug in PHP API 1.0.8
Ryan Gilfether
ryan@gilfether.com
Tue, 12 Aug 2003 19:25:17 -0400
This is a multi-part message in MIME format.
--------------020001090705080800040401
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Attached is a patch that fixes the problem found by Justin. His solution
fixed the problem.
Thanks,
Ryan
Brad Fitzpatrick wrote:
> Justin,
>
> Thanks! The PHP client is known to be buggy (discovered last week), and
> Ryan said he's working on it. Perhaps this is the only fix needed....
>
> Ryan?
>
> - Brad
>
>
> On Tue, 12 Aug 2003, Justin Matlock wrote:
>
>
>>Sorry for the extra-long email -- I just wanted to explain my thinking here,
>>and go into excessive detail so someone can prove me wrong. :)
>>
>>I'm using the latest CVS snapshot of memcached, and the 1.0.8 PHP API, and
>>the latest PHP 4.3.3 CVS tree, under Linux 2.4.21, Apache 2.0.47. It was
>>all working great on my devel box, but when I moved it over to production, I
>>started getting a ton of "_load_items(): Bytes read is greater than
>>requested data size." errors. But the thing is: the development box and
>>production box are using the exact same memcached server. They run the same
>>OS, the same PHP version, the same *everything*. They're even the same
>>hardware (one serial number apart). The *only* difference is the production
>>box is on the same subnet as the memcached server -- the development one is
>>on a different one. Of course, I start doing a lot more testing on the
>>development box, and I notice I was getting them over there too, just not as
>>many.
>>
>>So I modified the script to give me more information (patch follows):
>>
>>=================
>>1063,1064c1063,1064
>>< $this->_debug("_load_items(): Bytes
>>read is greater than requested data size.");
>><
>>---
>>
>>> $this->_debug("_load_items(): Bytes
>>
>>read ($bytes_read) is greater than requested data size ($len).");
>>
>>> $this->_debug("_load_items(): I
>>
>>received \"".urlencode($buf)."\"");
>>=================
>>
>>Here's what I'm getting in my logs (I modified the debug handler to use my
>>custom logging routines) -- add 7 for the "\r\nEND\r\n". So we're getting
>>back 2 characters instead of 1:
>>
>>(Data is "0")
>>[03Aug12 154857] (INFO) #/profile/# <10.1.0.11> (u:1) _load_items(): Bytes
>>read (9) is greater than requested data size (1).
>>[03Aug12 154857] (INFO) #/profile/# <10.1.0.11> (u:1) _load_items(): I
>>received "%0A2%0D%0AEND%0D%0A"
>>
>>(Data is "-1")
>>[03Aug12 154926] (INFO) #/profile/# <10.1.0.11> (u:1) _load_items(): Bytes
>>read (10) is greater than requested data size (2).
>>[03Aug12 154926] (INFO) #/profile/# <10.1.0.11> (u:1) _load_items(): I
>>received "%0A-1%0D%0AEND%0D%0A"
>>
>>(Data is a whole lot more than "0" :) ):
>>[03Aug12 154926] (INFO) #/profile/# <10.1.0.11> (u:1) _load_items(): Bytes
>>read (165) is greater than requested data size (157).
>>[03Aug12 154926] (INFO) #/profile/# <10.1.0.11> (u:1) _load_items(): I
>>received "%0Aa%3A1%3A%7Bi%3A0%3Ba%3A5%3A%7Bs%3A7%3A%(for clarity, I cut off
>>the end)
>>
>>The thing that sucks is I can't replicate this reliably. I can hit reload
>>over and over, and it will only happen 1 out of every 10 or so times, on
>>random data coming back. It's not just numerics, not text...
>>
>>I sniffed the connection, and here's one that barfed coming back from the
>>server:
>>
>>VALUE profile_1_7028277b0e9405414ea71de0bdde789f_rank 0 2\r\n-1\r\nEND\r\n
>>
>>Looks okay to me; it follows the protocol, and there are two characters in
>>the response. Memcached isn't the culprit. So on to the API...
>>
>>The problem appears to be with this line:
>>$line = substr($line, strpos($line, "\r\n")+1, strlen($line));
>>
>>I added some more logging lines before and after it to see what the 'pre'
>>and 'post' parsing results were.
>>
>>By only doing +1, you're just stripping off the \r. It's always letting a
>>\n through, even though it should be stripping it off. The strange thing to
>>me is sometimes it only lets a \n through, but sometimes it lets
>>"\n0\r\nEND\r\n" through (this is when it breaks). I'm still trying to
>>track down why this is happening...
>>
>>In summary; I changed that +1 to a +2, and it always strips off the
>>remaining \n. From there, it works great. I just pushed about 300 pages,
>>and all came back without errors...
>>
>>Final patch:
>>==============
>>999c999
>>< $line = substr($line, strpos($line,
>>"\r\n")+1, strlen($line));
>>---
>>
>>> $line = substr($line, strpos($line,
>>
>>"\r\n")+2, strlen($line));
>>===============
>>
>>"It works for me". :)
>>
>>Justin
>>
>>----- Original Message -----
>>From: "Ryan Gilfether" <ryan@gilfether.com>
>>To: <memcached@lists.danga.com>
>>Sent: Monday, August 11, 2003 12:37 AM
>>Subject: Re: PHP API 1.0.7
>>
>>
>>
>>>yes, you're right, I didnt notice that a newline got included at the end
>>>of the file. I'll be sure to remove it in future releases. Thanks for
>>>pointing it out.
>>>
>>>Ryan
>>>
>>>Lisa Marie Seelye wrote:
>>>
>>>>On Sat, 2003-08-09 at 13:08, Ryan Gilfether wrote:
>>>>
>>>>
>>>>>A new version of the PHP API has been completed, verson 1.0.7.
>>>>>I've had some requests for adding PHPDocs style comments to the API.
>>>>>Along with that 3 new function have been added
>>>>>error() - returns an error code for the last error genterated
>>>>>error_string() - returns a string with a description of the error
>>>>>error_clear() - clears the last error
>>>>>
>>>>>Ryan
>>>>
>>>>
>>>>Not to be incredibly anal, but the .php file should not have any
>>>>newlines after the closing ?> tag -- this tends to mess with headers
>>>>should it be included after headers have been sent. :(
>>>>
>>>>
>>>
>>>--
>>>Ryan Gilfether
>>>Software Engineer
>>>http://www.gilfether.com
>>>
>>>
>>
>>
>
>
--
Ryan Gilfether
Software Engineer
http://www.gilfether.com
--------------020001090705080800040401
Content-Type: text/plain;
name="php-memcached-1.0.8.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="php-memcached-1.0.8.diff"
--- devel/html/memcached/MemCachedClient.inc.php 2003-08-12 19:17:06.000000000 -0400
+++ MemCachedClient.inc.php 2003-08-11 00:27:44.000000000 -0400
@@ -602,7 +602,7 @@
}
// connect to the server, if it fails, add it to the host_dead below
- $sock = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);
+ $sock = socket_create (AF_INET, SOCK_STREAM, getprotobyname("TCP"));
// we need surpress the error message if a connection fails
if(!@socket_connect($sock, $conn[0], $conn[1]))
@@ -996,7 +996,7 @@
$bytes_read = 0;
// get the left over data after the header is read
- $line = substr($line, strpos($line, "\r\n")+2, strlen($line));
+ $line = substr($line, strpos($line, "\r\n")+1, strlen($line));
}
else
{
--------------020001090705080800040401--