Edit report at http://bugs.php.net/bug.php?id=51775&edit=1

 ID:               51775
 Updated by:       dmi...@php.net
 Reported by:      vic at zymsys dot com
 Summary:          Chunked response parsing error
-Status:           Assigned
+Status:           Feedback
 Type:             Bug
 Package:          SOAP related
 Operating System: CentOS 4.8
 PHP Version:      5.3SVN-2010-05-09 (snap)
 Assigned To:      dmitry

 New Comment:

I can't reproduce the issue. Anyway php_stream_gets() must make its work
proper and ext/soap doesn't have to care about its mistakes. Especially
because '\n' may be a valid character in data stream.


Previous Comments:
------------------------------------------------------------------------
[2010-05-09 06:07:09] vic at zymsys dot com

Description:
------------
I was getting an error from a SoapClient call:  "Error Fetching http
body, No Content-Length, connection closed or chunked data".  Thing was
I couldn't see any problem with the HTTP response.



I tracked the problem down to the get_http_body function in
ext/soap/php_http.c, where it reads the chunk size using
php_stream_gets().  That's returning the chunk size plus the CR (0d) but
leaving the LF (0a) unread.  Then the unread LF gets read with HTTP
chunk, and the attempt to read the next chunk size starts with the last
character of the HTTP chunk, since it's behind one thanks to the unread
LF.



Here's a chunk of the response that throws it off, with the chunk size
(000001bc) in the middle, surrounded by CR/LF pairs.



00000850  3b 20 63 68 61 72 73 65  74 3d 22 75 74 66 2d 38  |;
charset="utf-8|

00000860  22 0d 0a 0d 0a 30 30 30  30 30 31 62 63 0d 0a 3c 
|"....000001bc..<|

00000870  65 6e 76 3a 45 6e 76 65  6c 6f 70 65 20 78 6d 6c 
|env:Envelope xml|



I added a little code under the line that adjusts the http buffer
allocation, and above the loop that reads the chunk, and this solved the
problem for me:



ch = php_stream_getc(stream); /* php_stream_gets may stop after CR and
leave LF in the buffer.  If so, we need to eat it. */

if (ch != '\n') {

    // Nope, it wasn't a LF.  Put it at the start of the current buffer,
and advance one character.

    http_buf[http_buf_size] = ch;

    len_size++;

    http_buf_size++;

}



This reads the next character, and if it is an LF it eats it, and if it
isn't it adds it to the http buffer.



I wanted to run this by someone more experienced hacking on the php
source before going any further to make sure the bug is legit, and the
fix looks at all sane.



------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=51775&edit=1

Reply via email to