Greetings, I recently upgraded to the latest PHP 5.3 snapshot and I found the following SoapClient bug:
<?php ini_set("soap.wsdl_cache_enabled", 0); new SoapClient("http://localhost/ws/catalog?wsdl"); ?> 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: <?php $opts = array('http' => 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 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php