]> granicus.if.org Git - php/commitdiff
Fixed bug #31695 (Cannot redefine endpoint when using WSDL)
authorDmitry Stogov <dmitry@php.net>
Wed, 23 Mar 2005 07:11:39 +0000 (07:11 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 23 Mar 2005 07:11:39 +0000 (07:11 +0000)
NEWS
ext/soap/soap.c
ext/soap/tests/bugs/bug31695.phpt [new file with mode: 0644]
ext/soap/tests/bugs/bug31695.wsdl [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 4a9104d22ff6dd5dd9eeebae72a1a083f57e9047..f60216e1f14637a56e495101de42ff23f2ce6814 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -76,6 +76,7 @@ PHP                                                                        NEWS
 - Fixed bug #31710 (Wrong return values for mysqli_autocommit/commit/rollback).
   (Georg)
 - Fixed bug #31705 (parse_url() does not recognize http://foo.com#bar). (Ilia)
+- Fixed bug #31695 (Cannot redefine endpoint when using WSDL). (Dmitry)
 - Fixed bug #31684 (dio_tcsetattr(): misconfigured termios settings).
   (elod at itfais dot com)
 - Fixed bug #31683 (changes to $name in __get($name) override future 
index 39b4a5fc1fe1ec4a4d8beb26a9ddecc10c210275..25b0947c8a5ef075f8ef9918cb55773063690841 100644 (file)
@@ -236,6 +236,7 @@ PHP_METHOD(SoapClient, __getFunctions);
 PHP_METHOD(SoapClient, __getTypes);
 PHP_METHOD(SoapClient, __doRequest);
 PHP_METHOD(SoapClient, __setCookie);
+PHP_METHOD(SoapClient, __setLocation);
 
 /* SoapVar Functions */
 PHP_METHOD(SoapVar, SoapVar);
@@ -323,6 +324,7 @@ static zend_function_entry soap_client_functions[] = {
        PHP_ME(SoapClient, __getTypes, NULL, 0)
        PHP_ME(SoapClient, __doRequest, NULL, 0)
        PHP_ME(SoapClient, __setCookie, NULL, 0)
+       PHP_ME(SoapClient, __setLocation, NULL, 0)
        {NULL, NULL, NULL}
 };
 
@@ -1975,14 +1977,6 @@ PHP_METHOD(SoapClient, SoapClient)
 
                if (wsdl == NULL) {
                        /* Fetching non-WSDL mode options */
-                       if (zend_hash_find(ht, "location", sizeof("location"), (void**)&tmp) == SUCCESS &&
-                           Z_TYPE_PP(tmp) == IS_STRING) {
-                               add_property_stringl(this_ptr, "location", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
-                       } else {
-                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' option is requred in nonWSDL mode");
-                               return;
-                       }
-
                        if (zend_hash_find(ht, "uri", sizeof("uri"), (void**)&tmp) == SUCCESS &&
                            Z_TYPE_PP(tmp) == IS_STRING) {
                                add_property_stringl(this_ptr, "uri", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
@@ -2004,6 +1998,14 @@ PHP_METHOD(SoapClient, SoapClient)
                        }
                }
 
+               if (zend_hash_find(ht, "location", sizeof("location"), (void**)&tmp) == SUCCESS &&
+                   Z_TYPE_PP(tmp) == IS_STRING) {
+                       add_property_stringl(this_ptr, "location", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+               } else if (wsdl == NULL) {
+                       php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' option is requred in nonWSDL mode");
+                       return;
+               }
+
                if (zend_hash_find(ht, "soap_version", sizeof("soap_version"), (void**)&tmp) == SUCCESS) {
                        if (Z_TYPE_PP(tmp) == IS_LONG ||
                            (Z_LVAL_PP(tmp) == SOAP_1_1 && Z_LVAL_PP(tmp) == SOAP_1_2)) {
@@ -2190,6 +2192,7 @@ static void do_soap_call(zval* this_ptr,
                          int arg_count,
                          zval** real_args,
                          zval* return_value,
+                         char* location,
                          char* soap_action,
                          char* call_uri,
                          HashTable* soap_headers,
@@ -2222,6 +2225,13 @@ static void do_soap_call(zval* this_ptr,
                soap_version = SOAP_1_1;
        }
 
+       if (location == NULL) {
+               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &tmp) == SUCCESS &&
+                   Z_TYPE_PP(tmp) == IS_STRING) {
+                 location = Z_STRVAL_PP(tmp);
+               }
+       }
+
        if (FIND_SDL_PROPERTY(this_ptr,tmp) != FAILURE) {
                FETCH_SDL_RES(sdl,tmp);
        }
@@ -2250,13 +2260,16 @@ static void do_soap_call(zval* this_ptr,
                fn = get_function(sdl, function);
                if (fn != NULL) {
                        sdlBindingPtr binding = fn->binding;
+                       if (location == NULL) {
+                               location = binding->location;
+                       }
                        if (binding->bindingType == BINDING_SOAP) {
                                sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
                                request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
-                               ret = do_request(this_ptr, request, binding->location, fnb->soapAction, soap_version, &response TSRMLS_CC);
+                               ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, &response TSRMLS_CC);
                        }       else {
                                request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
-                               ret = do_request(this_ptr, request, binding->location, NULL, soap_version, &response TSRMLS_CC);
+                               ret = do_request(this_ptr, request, location, NULL, soap_version, &response TSRMLS_CC);
                        }
 
                        xmlFreeDoc(request);
@@ -2277,12 +2290,12 @@ static void do_soap_call(zval* this_ptr,
                        smart_str_free(&error);
                }
        } else {
-               zval **uri, **location;
+               zval **uri;
                smart_str action = {0};
 
                if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri) == FAILURE) {
                        add_soap_fault(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL TSRMLS_CC);
-               } else if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &location) == FAILURE) {
+               } else if (location == NULL) {
                        add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC);
                } else {
                        if (call_uri == NULL) {
@@ -2299,7 +2312,7 @@ static void do_soap_call(zval* this_ptr,
                        }
                        smart_str_0(&action);
 
-                       ret = do_request(this_ptr, request, Z_STRVAL_PP(location), action.c, soap_version, &response TSRMLS_CC);
+                       ret = do_request(this_ptr, request, location, action.c, soap_version, &response TSRMLS_CC);
 
                        smart_str_free(&action);
                        xmlFreeDoc(request);
@@ -2356,7 +2369,7 @@ static void do_soap_call(zval* this_ptr,
    Calls a SOAP function */
 PHP_METHOD(SoapClient, __call)
 {
-       char *function, *soap_action = NULL, *uri = NULL;
+       char *function, *location=NULL, *soap_action = NULL, *uri = NULL;
        int function_len, i = 0;
        HashTable* soap_headers = NULL;
        zval *options = NULL;
@@ -2379,6 +2392,11 @@ PHP_METHOD(SoapClient, __call)
                        HashTable *ht = Z_ARRVAL_P(options);
                        zval **tmp;
 
+                       if (zend_hash_find(ht, "location", sizeof("location"), (void**)&tmp) == SUCCESS &&
+                           Z_TYPE_PP(tmp) == IS_STRING) {
+                               location = Z_STRVAL_PP(tmp);
+                       }
+
                        if (zend_hash_find(ht, "soapaction", sizeof("soapaction"), (void**)&tmp) == SUCCESS &&
                            Z_TYPE_PP(tmp) == IS_STRING) {
                                soap_action = Z_STRVAL_PP(tmp);
@@ -2430,7 +2448,7 @@ PHP_METHOD(SoapClient, __call)
        if (output_headers) {
                array_init(output_headers);
        }
-       do_soap_call(this_ptr, function, function_len, arg_count, real_args, return_value, soap_action, uri, soap_headers, output_headers TSRMLS_CC);
+       do_soap_call(this_ptr, function, function_len, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers TSRMLS_CC);
        if (arg_count > 0) {
                efree(real_args);
        }
@@ -2590,6 +2608,7 @@ PHP_METHOD(SoapClient, __setCookie)
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",
            &name, &name_len, &val, &val_len) == FAILURE) {
+               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
          RETURN_NULL();
        }
 
@@ -2616,6 +2635,37 @@ PHP_METHOD(SoapClient, __setCookie)
 }
 /* }}} */
 
+/* {{{ proto string SoapClient::__setLocation([string new_location])
+   Sets the location option (the endpoint URL that will be touched by the 
+   following SOAP requests).
+   If new_location is not specified or null then SoapClient will use endpoint
+   from WSDL file. 
+   The function returns old value of location options. */
+PHP_METHOD(SoapClient, __setLocation)
+{
+       char *location = NULL;
+       int  location_len;
+       zval **tmp;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s",
+           &location, &location_len) == FAILURE) {
+               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
+         RETURN_NULL();
+       }
+       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &tmp) == SUCCESS &&
+           Z_TYPE_PP(tmp) == IS_STRING) {
+         RETVAL_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+       } else {
+         RETVAL_NULL();
+       }
+       if (location && location_len) {
+               add_property_stringl(this_ptr, "location", location, location_len, 1);
+       } else {
+               zend_hash_del(Z_OBJPROP_P(this_ptr), "location", sizeof("location"));
+       }
+}
+/* }}} */
+
 #ifndef ZEND_ENGINE_2
 static void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
 {
@@ -2635,7 +2685,7 @@ static void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_proper
                zval **arguments = (zval **) safe_emalloc(sizeof(zval *), arg_count, 0);
 
                zend_get_parameters_array(ht, arg_count, arguments);
-               do_soap_call(this_ptr, function, Z_STRLEN(function_name->element) + 1, arg_count, arguments, return_value, NULL, NULL, NULL, NULL TSRMLS_CC);
+               do_soap_call(this_ptr, function, Z_STRLEN(function_name->element) + 1, arg_count, arguments, return_value, NULL, NULL, NULL, NULL, NULL TSRMLS_CC);
                efree(arguments);
        }
        zval_dtor(&function_name->element);
diff --git a/ext/soap/tests/bugs/bug31695.phpt b/ext/soap/tests/bugs/bug31695.phpt
new file mode 100644 (file)
index 0000000..770f5b4
--- /dev/null
@@ -0,0 +1,62 @@
+--TEST--
+Bug #31695 Cannot redefine endpoint when using WSDL
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+ini_set("soap.wsdl_cache_enabled", 0);
+
+function Test($x) {
+       return $x;
+}
+
+class LocalSoapClient extends SoapClient {
+  function __construct($wsdl, $options=array()) {
+    parent::__construct($wsdl, $options);
+    $this->server = new SoapServer($wsdl, $options);
+               $this->server->addFunction("Test"); 
+  }
+
+  function __doRequest($request, $location, $action, $version) {
+       echo "$location\n";
+    ob_start();
+    $this->server->handle($request);
+    $response = ob_get_contents();
+    ob_end_clean();
+    return $response;
+  }
+}
+
+$client = new LocalSoapClient(dirname(__FILE__)."/bug31695.wsdl");
+$client->Test("str");
+$client = new LocalSoapClient(dirname(__FILE__)."/bug31695.wsdl", array("location"=>"test://1"));
+$client->Test("str");
+$client->__soapCall("Test", 
+                    array("arg1"),
+                     array("location"=>"test://2"));
+$old = $client->__setLocation("test://3");
+echo "$old\n";
+$client->Test("str");
+$client->Test("str");
+$client->__setLocation($old);
+$client->Test("str");
+$old = $client->__setLocation();
+$client->Test("str");
+$client->__setLocation($old);
+$client->Test("str");
+$client->__setLocation(null);
+$client->Test("str");
+var_dump($client->__setLocation());
+?>
+--EXPECT--
+test://0
+test://1
+test://2
+test://1
+test://3
+test://3
+test://1
+test://0
+test://1
+test://0
+NULL
diff --git a/ext/soap/tests/bugs/bug31695.wsdl b/ext/soap/tests/bugs/bug31695.wsdl
new file mode 100644 (file)
index 0000000..5785cb0
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" ?>
+<definitions
+    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
+    xmlns:si="http://soapinterop.org/xsd"
+    xmlns:tns="http://linuxsrv.home/~dmitry/soap/test.wsdl"
+    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+    xmlns="http://schemas.xmlsoap.org/wsdl/"
+    targetNamespace="http://linuxsrv.home/~dmitry/soap/test.wsdl">
+
+  <message name="TestRequest">
+    <part name="x" type="xsd:string" />
+  </message>
+  <message name="TestResponse">
+    <part name="result" type="xsd:string" />
+  </message>
+
+  <portType name="TestServicePortType">
+    <operation name="Test">
+      <input message="tns:TestRequest" />
+      <output message="tns:TestResponse" />
+    </operation>
+  </portType>
+
+  <binding name="TestServiceBinding" type="tns:TestServicePortType">
+    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+    <operation name="Test">
+      <soap:operation soapAction="Test" style="rpc" />
+      <input>
+        <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+      </input>
+      <output>
+        <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+      </output>
+    </operation>
+  </binding>
+
+  <service name="TestService">
+    <port name="TestServicePort" binding="tns:TestServiceBinding">
+      <soap:address location="test://0" />
+    </port>
+  </service>
+
+</definitions>