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

 ID:                 49853
 Comment by:         michaelclark at zagg dot com
 Reported by:        rumana024 at yahoo dot com
 Summary:            Soap Client stream context header option ignored
 Status:             Open
 Type:               Bug
 Package:            SOAP related
 Operating System:   Windows XP
 PHP Version:        5.2SVN-2009-10-12 (SVN)
 Block user comment: N
 Private report:     N

 New Comment:

So, here's an SVN diff against trunk, seems to be working for the test case I 
posted. This patch should apply cleanly against anything dating back to the 
current release, PHP 5.3.8. This patch follows the simple mitigation strategy 
proposed above. There was an error in the trunk for one of the soap test cases, 
but it was there even after reverting the patch.

Index: ext/soap/php_sdl.c
===================================================================
--- ext/soap/php_sdl.c  (revision 319075)
+++ ext/soap/php_sdl.c  (working copy)
@@ -3270,7 +3270,7 @@
                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);
+               smart_str_appendl(&headers, "Connection: close\r\n", 
sizeof("Connection: close\r\n")-1);
        }
 
        if (headers.len > 0) {
@@ -3278,6 +3278,8 @@
 
                if (!context) {
                        context = php_stream_context_alloc(TSRMLS_C);
+               } else if (php_stream_context_get_option(context, "http", 
"header", &tmp) != FAILURE) {
+                       smart_str_appendl(&headers, Z_STRVAL_PP(tmp), 
Z_STRLEN_PP(tmp));
                }
 
                smart_str_0(&headers);


Previous Comments:
------------------------------------------------------------------------
[2011-11-04 21:15:55] michaelclark at zagg dot com

In the TESTCASE, please replace the last line with

unlink(ini_get('soap.wsdl_cache_dir').DIRECTORY_SEPARATOR.'wsdl-'.get_current_user().'-'.md5($wsdl));

if you need something a little bit more portable, or to change the WSDL 
location.

------------------------------------------------------------------------
[2011-11-04 19:00:21] michaelclark at zagg dot com

I suspect that my problem is the same as the submitter, so I'm adding this as a 
comment instead of as a new issue. Again, this has to do with SoapClient, 
stream_context_create, and custom http headers.

Simple TESTCASE:
#!/usr/bin/php
<?php
$wsdl = 'http://www.w3schools.com/webservices/tempconvert.asmx?WSDL';
$apikey = 'this-must-still-be-here';
$c = stream_context_create(array(
        'http' => array(
                'header' => "apikey: this-must-still-be-here",
        )
));
var_dump(stream_context_get_options($c));
$soap = new SoapClient($wsdl, array('stream_context' => $c));
var_dump(stream_context_get_options($soap->_stream_context));
unlink('/tmp/wsdl-'.get_current_user().'-d4e1ad3ff31424862843f4814eade4a8');
?>

As you can see from running the code, if the SoapClient needs to download a new 
WSDL (function get_sdl() called on line 2679 of ext/soap/soap.c - PHP source 
code is version 5.3.8, function defined at line 3154 of ext/soap/php_sdl.c), 
AND also the 'protocol_version' option isn't explicitly set in the 
stream_context (line 3267, file ext/soap/php_sdl.c), it sets the 
'protocol_version' option (3271), and sets up a new header - "Connection: 
close" (3273). The following if statement (3276) sets the http "header" option 
to the value of that string (3286) - effectively overwriting any custom headers 
that were supplied.

The following if statement (3291) might be making an effort to prevent this 
(3294,3307), but is ineffective (operating on a pointer to the original I 
suspect; any copy should be made at the point of initialization, and this might 
not be copying the context structure itself at all).

So - userland mitigation:
Set the http 'protocol_version' explicitly to 1.1 in your code, and append the 
"\r\nConnection: close" header to your custom headers.
example:
$context = stream_context_create(array(
    'http'=>array(
        'protocol_version' => 1.1,
        'header' => "token: 85E91AAC-7A4A-11E0-B46B-78E7D1E19752\r\n" .
                    "Connection: close"
    )
));

Thoughts about fixing it:
It appears to be safe to pass the Connection: close header implicitly - so the 
simple solution of appending instead of replacing the custom headers could be 
good enough, without having to copy, backup, and restore the original context 
itself. Should that be the easier solution it should be preferred. If the 
simple solution is used, it would also be nice to have it in the docs.

------------------------------------------------------------------------
[2011-10-27 08:49:00] richard dot deguilhem at laposte dot net

I have the same problem with php 5.2.6 To 5.3.8.

[VERSION]

[CODE
class CMyClass extends SoapClient
{
 
    public function CMyClass($sWsdlUri = '',$aOptions = array())
    {
        $aOptions['stream_context'] = stream_context_create(array( 'http' => 
array('header'=>"foo: bar\r\n")));
 
        parent::__construct($sWsdlUri, $aOptions);
    }
 
    public function callSoapActionX()
    {
        $aParams = array(...);
        return $this->__soapCall('GetTokenSession', $aParams);
    }
}

[REQUEST HEADERS]
POST  HTTP/1.0
Host: 127.0.0.1:8052
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.3.8
Content-Type: application/soap+xml; charset=utf-8; action="GetTokenSession"
Content-Length: 532

------------------------------------------------------------------------
[2011-09-22 10:14:14] dave dot wilcock at gmail dot com

[VERSION]
PHP 5.3.2 (cli) (built: Apr 27 2010 20:28:18)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
    with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by 
eAccelerator

[CODE]
$str_auth_header = "Authorization: Bearer ". $str_token;
      
$arr_context = array('http' =>array('header' => $str_auth_header));

$obj_context = stream_context_create($arr_context);

$arr_options = array (
   'soap_version' => 'SOAP_1_2',
   'encoding' => 'UTF-8',
   'exceptions' => true,
   'trace' => true,
   'cache_wsdl' => 'WSDL_CACHE_NONE',
   'stream_context' => $obj_context
);

$this->obj_connection = new SoapClient(self::STR_BASE_URL, $arr_options);

[EXPECTED]
Authorization header in HTTP request

[GOT]
No Authorization header in HTTP request

[WORKAROUND/CODE]
ini_set('user_agent', 'PHP-SOAP/' . PHP_VERSION . "\r\n" . $str_auth_header);

[COMMENT]
No idea why appending the user agent string with the headers would work, but it 
seemingly does. Bizarre.

------------------------------------------------------------------------
[2011-05-09 17:09:04] vidalis dot aris at gmail dot com

Using php5.3.6 i couldn't pass extra HTTP headers to the SOAP request.
stream_context_create appears to get ignored

[VERSION]
PHP 5.3.6 with Suhosin-Patch (cli) (built: Apr 18 2011 11:14:25)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies

[CODE]
$context = stream_context_create(array('http' => array('header' => "token: 
85E91AAC-7A4A-11E0-B46B-78E7D1E19752\r\n")));

        $soapparams = array(                    
                                                'stream_context' => $context,
                                                'trace' => 1,
                                                'exceptions' => 1,
                                                'soap_version' => SOAP_1_2,
                                                'encoding' => 'UTF-8',
                                                'features' => 
SOAP_SINGLE_ELEMENT_ARRAYS
                                );
$client = new SoapClient($wsdl,$soapparams);

[REQUEST HEADERS]
POST /SocialMetadataService HTTP/1.1
Host: test.host.com:9080
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.3.6
Content-Type: application/soap+xml; charset=utf-8; action="urn:getObjectID"
Content-Length: 331

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


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=49853


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

Reply via email to