Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:42834 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 23775 invoked from network); 25 Jan 2009 21:44:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 25 Jan 2009 21:44:09 -0000 Authentication-Results: pb1.pair.com smtp.mail=giovanni@giacobbi.net; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=giovanni@giacobbi.net; sender-id=unknown Received-SPF: error (pb1.pair.com: domain giacobbi.net from 62.149.226.38 cause and error) X-PHP-List-Original-Sender: giovanni@giacobbi.net X-Host-Fingerprint: 62.149.226.38 host38-226-149-62.serverdedicati.aruba.it Linux 2.5 (sometimes 2.4) (4) Received: from [62.149.226.38] ([62.149.226.38:54038] helo=lowca.thgnet.it) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 8F/8B-55096-72DDC794 for ; Sun, 25 Jan 2009 16:44:08 -0500 Received: from lowca.thgnet.it (lowca [127.0.0.1]) by lowca.thgnet.it (8.12.11.20060308/8.12.11) with ESMTP id n0PLhq2O003576; Sun, 25 Jan 2009 22:43:52 +0100 Received: (from johnny@localhost) by lowca.thgnet.it (8.12.11.20060308/8.12.11/Submit) id n0PLhqtn003575; Sun, 25 Jan 2009 22:43:52 +0100 Date: Sun, 25 Jan 2009 22:43:52 +0100 To: internals@lists.php.net Message-ID: <20090125214352.GA3531@lowca.thgnet.it> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i Subject: Bug in HTTP stream context causes problems in SoapClient/get_sdl() From: giovanni@giacobbi.net (Giovanni Giacobbi) Greetings, I recently upgraded to the latest PHP 5.3 snapshot and I found the following SoapClient bug: Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://localhost/ws/catalog?wsdl' : Start tag expected, '<' not found The problem turned out to be an invalid interpretation of the HTTP/1.1 protocol with "Transfer-Encoding: chunked" by the HTTP stream context, which caused get_sdl() to parse a WSDL including the chunk tags (hex numbers). Chunked encoding is used by Apache 2.0 when "Content-Length" is unavailable, the data content being sent is large enough, and the protocol is HTTP/1.1. I initially tried using readfile() but I didn't get the same problem. Eventually I could finally reproduce the bug with the following script: array('method' => "GET", 'header' => "Accept-language: en\r\nConnection: close\r\n")); $context = stream_context_create($opts); stream_context_set_option($context, "http", "protocol_version", 1.1); fpassthru(fopen('http://localhost/ws/catalog?wsdl', 'r', false, $context)); ?> I can notice various problems here: 1) All the chunk tags are left in place and the extra newlines are not stripped, leading to corrupted data. 2) Without the "Connection: close" header the stream blocks until http timeout. It should instead detect the chunk with 0 bytes and return from the fpassthru(). In the meanwhile, the following patch is a workaround for the problem I had: it restores the default HTTP/1.0. Side note: Shouldn't the last smart_str_appendl() call also contain an EOL? Side note #2: Is there any way to avoid repeating the same string twice? It's very common in the soap extension and I think it's really error prone. Side note #3: Is it possible to create a test for this bug? Like a raw HTTP/1.1 response stored in a text file with chunk encoding and a script that loads that data...? --- ext/soap/php_sdl.c.orig 2008-12-31 12:37:12.000000000 +0100 +++ ext/soap/php_sdl.c 2009-01-25 22:09:14.000000000 +0100 @@ -3192,14 +3192,16 @@ basic_authentication(this_ptr, &headers TSRMLS_CC); /* Use HTTP/1.1 with "Connection: close" by default */ +#if 0 if (php_stream_context_get_option(context, "http", "protocol_version", &tmp) == FAILURE) { - zval *http_version; + zval *http_version; MAKE_STD_ZVAL(http_version); ZVAL_DOUBLE(http_version, 1.1); php_stream_context_set_option(context, "http", "protocol_version", http_version); zval_ptr_dtor(&http_version); smart_str_appendl(&headers, "Connection: close", sizeof("Connection: close")-1); } +#endif if (headers.len > 0) { zval *str_headers; Regards -- Giovanni Giacobbi