From de6184edee81007ca39616a0a05783f933ffce00 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 5 Jan 2004 16:44:01 +0000 Subject: [PATCH] PHP5 support, better encoding and WSDL support, interop round 2 base and groupB --- ext/soap/TODO | 115 +- ext/soap/TODO.old | 39 + ext/soap/interop/base.php | 25 - ext/soap/interop/client_round2.php | 39 +- ext/soap/interop/client_round2_interop.php | 234 +++-- ext/soap/interop/client_round2_params.php | 365 +++---- ext/soap/interop/client_round2_results.php | 2 +- ext/soap/interop/client_round2_run.php | 10 +- ext/soap/interop/config.php.dist | 4 + ext/soap/interop/database_round2.sql | 1 - ...oheadersvc.wsdl => echoheadersvc.wsdl.php} | 8 +- ext/soap/interop/endpointdata.sql | 85 -- ext/soap/interop/index.php | 8 +- ext/soap/interop/info.php | 1 - ext/soap/interop/interop.wsdl | 18 - ext/soap/interop/interop.wsdl.php | 335 ++++++ ext/soap/interop/interopB.wsdl | 13 - ext/soap/interop/server_round2.php | 35 - ext/soap/interop/server_round2_base.php | 79 +- ext/soap/interop/server_round2_groupB.php | 59 +- ext/soap/interop/server_round2_groupC.php | 10 +- ext/soap/interop/server_round2_test.php | 258 ----- ext/soap/interop/test.utility.php | 68 +- ext/soap/interop/testclient.php | 17 - ext/soap/interop/testserver.php | 17 - ext/soap/package.xml | 7 +- ext/soap/php_encoding.c | 519 ++++++--- ext/soap/php_encoding.h | 19 +- ext/soap/php_http.c | 150 +-- ext/soap/php_http.h | 8 +- ext/soap/php_packet_soap.c | 288 +++-- ext/soap/php_packet_soap.h | 4 +- ext/soap/php_schema.c | 106 +- ext/soap/php_schema.h | 22 - ext/soap/php_sdl.c | 326 +++--- ext/soap/php_sdl.h | 14 +- ext/soap/php_soap.h | 81 +- ext/soap/php_xml.c | 41 +- ext/soap/php_xml.h | 2 +- ext/soap/soap.c | 981 +++++++++--------- ext/soap/tests/server001.phpt | 33 + ext/soap/tests/server002.phpt | 37 + ext/soap/tests/server003.phpt | 32 + ext/soap/tests/server004.phpt | 40 + ext/soap/tests/server005.phpt | 36 + ext/soap/tests/server006.phpt | 42 + ext/soap/tests/server007.phpt | 26 + ext/soap/tests/server008.phpt | 29 + ext/soap/tests/server009.phpt | 61 ++ ext/soap/tests/server010.phpt | 61 ++ ext/soap/tests/server011.phpt | 26 + ext/soap/tests/server012.phpt | 18 + ext/soap/tests/server013.phpt | 44 + ext/soap/tests/server014.phpt | 37 + ext/soap/tests/skipif.inc | 3 + ext/soap/tests/test.wsdl | 55 + 56 files changed, 2918 insertions(+), 2075 deletions(-) create mode 100644 ext/soap/TODO.old delete mode 100644 ext/soap/interop/base.php create mode 100644 ext/soap/interop/config.php.dist rename ext/soap/interop/{echoheadersvc.wsdl => echoheadersvc.wsdl.php} (80%) delete mode 100644 ext/soap/interop/endpointdata.sql delete mode 100644 ext/soap/interop/info.php delete mode 100644 ext/soap/interop/interop.wsdl create mode 100644 ext/soap/interop/interop.wsdl.php delete mode 100644 ext/soap/interop/interopB.wsdl delete mode 100644 ext/soap/interop/server_round2.php delete mode 100644 ext/soap/interop/server_round2_test.php delete mode 100644 ext/soap/interop/testclient.php delete mode 100644 ext/soap/interop/testserver.php create mode 100644 ext/soap/tests/server001.phpt create mode 100644 ext/soap/tests/server002.phpt create mode 100644 ext/soap/tests/server003.phpt create mode 100644 ext/soap/tests/server004.phpt create mode 100644 ext/soap/tests/server005.phpt create mode 100644 ext/soap/tests/server006.phpt create mode 100644 ext/soap/tests/server007.phpt create mode 100644 ext/soap/tests/server008.phpt create mode 100644 ext/soap/tests/server009.phpt create mode 100644 ext/soap/tests/server010.phpt create mode 100644 ext/soap/tests/server011.phpt create mode 100644 ext/soap/tests/server012.phpt create mode 100644 ext/soap/tests/server013.phpt create mode 100644 ext/soap/tests/server014.phpt create mode 100644 ext/soap/tests/skipif.inc create mode 100644 ext/soap/tests/test.wsdl diff --git a/ext/soap/TODO b/ext/soap/TODO index 00ee6adae0..615509feb2 100644 --- a/ext/soap/TODO +++ b/ext/soap/TODO @@ -1,39 +1,82 @@ -TODO: -make sure soap 1.1 and 1.2 is supported fully -Better WSDL support Client and server (how much validation is needed here?) -UDDI?? -make internal refrences for soap encoding (use seralization logic) -add ini option for always soap_error_handler -provide user space overriding of serialization certin objects and types -serialization in general needs to be polished/finished... all xsd types -make perstistant objects and work with or without register_globals on -look to see if php-soap will work with out always_populate_raw_post_data on -see if client will work with ssl.. should be eaiser with php_streams -work on soap seralizer (php serialization) -work on a soap-service 'regiestry' and 'proxy' (apache soap style) -convert all string mainpulation to use smart_str -make the 'soap' packet abstract.. maybe incorperate xml-rpc -make the transport layer abstract.. what other transport layers are needed?... who uses smtp? what about jabber? -make $soap_object->data = 'text'; maybe invoke a set_*() and/or get_*() method -when using wsdls and function names are similar find the best match - void test(int); - void test(string); - maybe use the same alogrithim as ext/java. -investigate further http keep_alive... inital testing proved slower.. maybe php_streams will speed things up.. -provide schema 1999/2001 support.... -through memory leak testing -possible using shared memory for sdl caching... -api for clearing/checking sdl caching... -make php-soap work as a standalone server using php_streams and the new socket extension -http authication -proxy support -wsdl generation static and auto (.net style (http://server.com/soapserver.php?WSDL)) using phpdoc parsing engine -interpo testing... -BENCHMARKING...... lets prove how fast it is. -do some more work on website +General +------- +- rename soapobject to soapclient +- make sure soapvar and soapparam are really need +- make sure soapserver.map(), soap_encode_to_xml() and soap_encode_to_zval() are really need -does this list stop... what exactly have i done? -im sure im forgetting 20 thousand more things.... +SOAP +---- +- support for SOAP headers + - mustUnderstend attribute +- make sure soap 1.1 and 1.2 are supported fully +Encoding +-------- +- full support for standard simple types ( + - duration, + - anyURI, + - QName, + - NOTATION, + - normalizedString, + - token, + - language, + - NMTOKEN, + - Name, + - NCName, + - ID, + - IDREF, + - IDREFS, + - ENTITY, + - ENTITIES, + - unsignedLong) +- full support for standard date/time types ( + ? dateTime, + ? time, + ? date, + ? gYearMonth, + ? gYear, + ? gMonthDay, + ? gDay, + ? gMonth) +? proper encoding of standard hexBinary type +? proper encoding of standard base64Binary type +- full support for arrays + ? arrayType attribute + - offset attribute + - position attribute + ? multidimensional arrays + ? arrays of arrays +? provide schema 1999/2001 support??? +? make internal refrences for soap encoding (use seralization logic)??? +? provide user space overriding of serialization certin objects and types??? - - brad +WSDL +---- +? support for style "rpc"/"document" encoding +? support for "encoded"/"literal" encoding +? support for "nillable" and "nil" +- function/method overloading (test(int); test(string)) +- wsdl caching +- wsdl auto generation + +Error Handling +-------------- +- ??? + +Transport +--------- +? support for https:// +- support for persistent HTTP connections (keep_alive) +- support for HTTP compression (gzip,x-gzip,defalte) +- support for HTTP athentication +- support for HTTP proxies +- transport abstraction layer + +UDDI +---- +- ??? + +Interop Testing +--------------- +- more rounds/groups +- ??? diff --git a/ext/soap/TODO.old b/ext/soap/TODO.old new file mode 100644 index 0000000000..a1cc15c397 --- /dev/null +++ b/ext/soap/TODO.old @@ -0,0 +1,39 @@ +TODO: +make sure soap 1.1 and 1.2 is supported fully +Better WSDL support Client and server (how much validation is needed here?) +UDDI?? +make internal refrences for soap encoding (use seralization logic) +add ini option for always soap_error_handler +provide user space overriding of serialization certin objects and types +serialization in general needs to be polished/finished... all xsd types +make perstistant objects and work with or without register_globals on +look to see if php-soap will work with out always_populate_raw_post_data on +see if client will work with ssl.. should be eaiser with php_streams +work on soap seralizer (php serialization) +-work on a soap-service 'regiestry' and 'proxy' (apache soap style) +-convert all string mainpulation to use smart_str +make the 'soap' packet abstract.. maybe incorperate xml-rpc +make the transport layer abstract.. what other transport layers are needed?... who uses smtp? what about jabber? +make $soap_object->data = 'text'; maybe invoke a set_*() and/or get_*() method +when using wsdls and function names are similar find the best match + void test(int); + void test(string); + maybe use the same alogrithim as ext/java. +investigate further http keep_alive... inital testing proved slower.. maybe php_streams will speed things up.. +provide schema 1999/2001 support.... +through memory leak testing +possible using shared memory for sdl caching... +api for clearing/checking sdl caching... +make php-soap work as a standalone server using php_streams and the new socket extension +http authication +proxy support +wsdl generation static and auto (.net style (http://server.com/soapserver.php?WSDL)) using phpdoc parsing engine +interpo testing... +BENCHMARKING...... lets prove how fast it is. +do some more work on website + +does this list stop... what exactly have i done? +im sure im forgetting 20 thousand more things.... + + + - brad diff --git a/ext/soap/interop/base.php b/ext/soap/interop/base.php deleted file mode 100644 index a2bbb8a54a..0000000000 --- a/ext/soap/interop/base.php +++ /dev/null @@ -1,25 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id$ -// -class Interop_Base -{ -} - -?> \ No newline at end of file diff --git a/ext/soap/interop/client_round2.php b/ext/soap/interop/client_round2.php index 5583bb6c17..c1307472c4 100644 --- a/ext/soap/interop/client_round2.php +++ b/ext/soap/interop/client_round2.php @@ -9,7 +9,7 @@ Back to Interop Index

 

getEndpoints($test); echo "\n"; - foreach ($ml as $method) { - $selected = ''; - if ($sel_method == $method) $selected = ' SELECTED'; - echo "\n"; + echo "\n"; + $prev_method = ""; + foreach ($soap_tests[$test] as $x) { + $method = $x->test_name; + if ($method != $prev_method) { + $prev_method = $method; + $selected = ''; + if ($sel_method == $method) $selected = ' SELECTED'; + echo "\n"; + } } - echo "\n"; echo "\n"; } @@ -50,9 +56,14 @@ function endpointTestForm($test, $endpoint, $method, $paramType, $useWSDL) echo "\n"; endpointList($test, $endpoint); methodList($test, $method); - echo ""; +// echo ""; + echo ""; echo "\n"; - echo "\n"; + echo "\n"; echo "\n"; echo "
\n"; } @@ -80,7 +91,7 @@ if ($_POST['test'] && array_key_exists('endpoint', $_POST) && array_key_exists(' // here we execute the orders echo "

Calling {$_POST['method']} at {$_POST['endpoint']}

\n"; echo "NOTE: wire's are slightly modified to display better in web browsers.
\n"; - + $iop->currentTest = $_POST['test']; // see $tests above $iop->paramType = $_POST['paramType']; // 'php' or 'soapval' $iop->useWSDL = $_POST['useWSDL']; // 1= do wsdl tests @@ -88,10 +99,10 @@ if ($_POST['test'] && array_key_exists('endpoint', $_POST) && array_key_exists(' $iop->specificEndpoint = $_POST['endpoint']; // test only this endpoint $iop->testMethod = $_POST['method']=='ALL'?'':$_POST['method']; // test only this method $iop->skipEndpointList = array(); // endpoints to skip - $this->nosave = 0; // 1= disable saving results to database + $iop->nosave = 0; // 1= disable saving results to database // debug output - $iop->show = 1; - $iop->debug = 1; + $iop->show = 0; + $iop->debug = 0; $iop->showFaults = 0; // used in result table output echo '
';
     $iop->doTest();  // run a single set of tests using above options
diff --git a/ext/soap/interop/client_round2_interop.php b/ext/soap/interop/client_round2_interop.php
index b3bd98b4fc..6c4dbd6499 100644
--- a/ext/soap/interop/client_round2_interop.php
+++ b/ext/soap/interop/client_round2_interop.php
@@ -19,23 +19,23 @@
 // $Id$
 //
 require_once 'DB.php'; // PEAR/DB
-require_once 'base.php';
 require_once 'client_round2_params.php';
 require_once 'test.utility.php';
+require_once 'config.php';
 
 error_reporting(E_ALL ^ E_NOTICE);
 
-class Interop_Client extends Interop_Base
+class Interop_Client
 {
     // database DNS
-    var $DSN = 'mysql://user@localhost/interop2';
+    var $DSN = "";
 
     // our central interop server, where we can get the list of endpoints
-    var $interopServer = "http://www.whitemesa.net/interopInfo";
-    
+    var $interopServer = "http://www.whitemesa.net/wsdl/interopInfo.wsdl";
+
     // our local endpoint, will always get added to the database for all tests
     var $localEndpoint;
-    
+
     // specify testing
     var $currentTest = 'base';      // see $tests above
     var $paramType = 'php';     // 'php' or 'soapval'
@@ -50,15 +50,17 @@ class Interop_Client extends Interop_Base
     var $show = 1;
     var $debug = 0;
     var $showFaults = 0; // used in result table output
-    
+
     // PRIVATE VARIABLES
     var $dbc = NULL;
     var $totals = array();
     var $tests = array('base','GroupB', 'GroupC');
     var $paramTypes = array('php', 'soapval');
     var $endpoints = array();
-    
+
     function Interop_Client() {
+        global $interopConfig;
+    		$this->DSN = $interopConfig['DSN'];
         // set up the database connection
         $this->dbc = DB::connect($this->DSN, true);
         // if it errors out, just ignore it and rely on regular methods
@@ -67,41 +69,41 @@ class Interop_Client extends Interop_Base
             $this->dbc = NULL;
         }
         // set up local endpoint
-        $this->localEndpoint['base'] = array(
-                                'endpointName'=>'PEAR SOAP',
-                                'endpointURL'=>'http://localhost/soap_interop/server_round2.php',
-                                'wsdlURL'=>'http://localhost/soap_interop/interop.wsdl'
+        $this->localEndpoint['base'] = (object)array(
+                                'endpointName'=>'PHP ext/soap',
+                                'endpointURL'=>'http://'.$_SERVER['SERVER_NAME'].dirname($_SERVER['PHP_SELF']).'/server_round2_base.php',
+                                'wsdlURL'=>'http://'.$_SERVER['SERVER_NAME'].dirname($_SERVER['PHP_SELF']).'/interop.wsdl.php'
                               );
-        $this->localEndpoint['GroupB'] = array(
-                                'endpointName'=>'PEAR SOAP',
-                                'endpointURL'=>'http://localhost/soap_interop/server_round2.php',
-                                'wsdlURL'=>'http://localhost/soap_interop/interopB.wsdl'
+        $this->localEndpoint['GroupB'] = (object)array(
+                                'endpointName'=>'PHP ext/soap',
+                                'endpointURL'=>'http://'.$_SERVER['SERVER_NAME'].dirname($_SERVER['PHP_SELF']).'/server_round2_groupB.php',
+                                'wsdlURL'=>'http://'.$_SERVER['SERVER_NAME'].dirname($_SERVER['PHP_SELF']).'/interopB.wsdl.php'
                               );
-        $this->localEndpoint['GroupC'] = array(
-                                'endpointName'=>'PEAR SOAP',
-                                'endpointURL'=>'http://localhost/soap_interop/server_round2.php',
-                                'wsdlURL'=>'http://localhost/soap_interop/echoheadersvc.wsdl'
+        $this->localEndpoint['GroupC'] = (object)array(
+                                'endpointName'=>'PHP ext/soap',
+                                'endpointURL'=>'http://'.$_SERVER['SERVER_NAME'].dirname($_SERVER['PHP_SELF']).'/server_round2_groupC.php',
+                                'wsdlURL'=>'http://'.$_SERVER['SERVER_NAME'].dirname($_SERVER['PHP_SELF']).'/echoheadersvc.wsdl.php'
                               );
     }
-    
+
     function _fetchEndpoints(&$soapclient, $test) {
         $this->_getEndpoints($test, 1);
-        
+
         // retreive endpoints from the endpoint server
-        $endpointArray = $soapclient->call("GetEndpointInfo",array("groupName"=>$test),"http://soapinterop.org/info/","http://soapinterop.org/info/");
+        $endpointArray = $soapclient->__call("GetEndpointInfo",array("groupName"=>$test),"http://soapinterop.org/info/","http://soapinterop.org/info/");
         if (PEAR::isError($endpointArray)) {
             print $soapclient->wire;
             print_r($endpointArray);
             return;
         }
-        
+
         // add our local endpoint
         if ($this->localEndpoint[$test]) {
-        array_push($endpointArray, $this->localEndpoint[$test]);
+          array_push($endpointArray, $this->localEndpoint[$test]);
         }
-        
+
         if (!$endpointArray) return;
-        
+
         // reset the status to zero
         $res = $this->dbc->query("update endpoints set status = 0 where class='$test'");
         if (DB::isError($res)) {
@@ -110,10 +112,10 @@ class Interop_Client extends Interop_Base
         if (is_object($res)) $res->free();
         // save new endpoints into database
         foreach($endpointArray as $k => $v){
-            if (array_key_exists($v['endpointName'],$this->endpoints)) {
-                $res = $this->dbc->query("update endpoints set endpointURL='{$v['endpointURL']}', wsdlURL='{$v['wsdlURL']}', status=1 where id={$this->endpoints[$v['endpointName']]['id']}");
+            if (array_key_exists($v->endpointName,$this->endpoints)) {
+                $res = $this->dbc->query("update endpoints set endpointURL='{$v->endpointURL}', wsdlURL='{$v->wsdlURL}', status=1 where id={$this->endpoints[$v->endpointName]['id']}");
             } else {
-                $res = $this->dbc->query("insert into endpoints (endpointName,endpointURL,wsdlURL,class) values('{$v['endpointName']}','{$v['endpointURL']}','{$v['wsdlURL']}','$test')");
+                $res = $this->dbc->query("insert into endpoints (endpointName,endpointURL,wsdlURL,class) values('{$v->endpointName}','{$v->endpointURL}','{$v->wsdlURL}','$test')");
             }
             if (DB::isError($res)) {
                 die ($res->getMessage());
@@ -121,18 +123,18 @@ class Interop_Client extends Interop_Base
             if (is_object($res)) $res->free();
         }
     }
-    
+
     /**
     *  fetchEndpoints
     * retreive endpoints interop server
     *
     * @return boolean result
     * @access private
-    */    
+    */
     function fetchEndpoints($test = NULL) {
         // fetch from the interop server
         $soapclient = new SoapObject($this->interopServer);
-        
+
         if ($test) {
             $this->_fetchEndpoints($soapclient, $test);
         } else {
@@ -141,12 +143,13 @@ class Interop_Client extends Interop_Base
             }
             $test = 'base';
         }
-        
+
         // retreive all endpoints now
         $this->currentTest = $test;
-        return $this->_getEndpoints($test);
+        $x = $this->_getEndpoints();
+        return $x;
     }
-    
+
     /**
     *  getEndpoints
     * retreive endpoints from either database or interop server
@@ -155,7 +158,7 @@ class Interop_Client extends Interop_Base
     * @param boolean all (if false, only get valid endpoints, status=1)
     * @return boolean result
     * @access private
-    */    
+    */
     function getEndpoints($base = 'base', $all = 0) {
         if (!$this->_getEndpoints($base, $all)) {
             return $this->fetchEndpoints($base);
@@ -171,7 +174,7 @@ class Interop_Client extends Interop_Base
     * @param boolean all (if false, only get valid endpoints, status=1)
     * @return boolean result
     * @access private
-    */    
+    */
     function _getEndpoints($base = "", $all = 0) {
         $this->endpoints = array();
 
@@ -182,7 +185,7 @@ class Interop_Client extends Interop_Base
             if (!$all) $sql .= "and status=1";
         } else
         if (!$all) $sql .= "where status=1";
-        
+
         $db_ep = $this->dbc->getAll($sql,NULL, DB_FETCHMODE_ASSOC );
         if (DB::isError($db_ep)) {
             echo $sql."\n";
@@ -193,6 +196,13 @@ class Interop_Client extends Interop_Base
         foreach ($db_ep as $entry) {
             $this->endpoints[$entry['endpointName']] = $entry;
         }
+/*
+        $this->endpoints["PHP ext/soap"] =
+          array("endpointName" => "PHP ext/soap",
+                "endpointURL"  => "http://soap.4s4c.com/ilab/soap.asp",
+                "wsdlURL"      => "http://www.pocketsoap.com/services/ilab.wsdl",
+                "class"        => "base" "status"]=> string(1) "1" }
+*/
         if (count($this->endpoints) > 0) {
             $this->currentTest = $base;
             return TRUE;
@@ -209,7 +219,7 @@ class Interop_Client extends Interop_Base
     function getResults($test = 'base', $type = 'php', $wsdl = 0) {
         // be sure we have the right endpoints for this test result
         $this->getEndpoints($test);
-        
+
         // retreive the results and put them into the endpoint info
         $sql = "select * from results where class='$test' and type='$type' and wsdl=$wsdl";
         $results = $this->dbc->getAll($sql,NULL, DB_FETCHMODE_ASSOC );
@@ -224,7 +234,7 @@ class Interop_Client extends Interop_Base
             }
         }
     }
-    
+
     /**
     *  saveResults
     * save the results of a method test into the database
@@ -233,7 +243,7 @@ class Interop_Client extends Interop_Base
     */
     function _saveResults($endpoint_id, &$soap_test) {
         if ($this->nosave) return;
-        
+
         $result = $soap_test->result;
         $wire = $result['wire'];
         if ($result['success']) {
@@ -244,7 +254,7 @@ class Interop_Client extends Interop_Base
             $error = $result['fault']->faultstring;
             if (!$wire) $wire= $result['fault']->detail;
         }
-        
+
         $test_name = $soap_test->test_name;
         // add header info to the test name
         if ($soap_test->headers) {
@@ -261,7 +271,7 @@ class Interop_Client extends Interop_Base
                 }
             }
         }
-        
+
         $sql = "delete from results where endpoint=$endpoint_id ".
                     "and class='$this->currentTest' and type='$this->paramType' ".
                     "and wsdl=$this->useWSDL and function=".
@@ -272,7 +282,7 @@ class Interop_Client extends Interop_Base
             die ($res->getMessage());
         }
         if (is_object($res)) $res->free();
-        
+
         $sql = "insert into results (endpoint,stamp,class,type,wsdl,function,result,error,wire) ".
                     "values($endpoint_id,".time().",'$this->currentTest',".
                     "'$this->paramType',$this->useWSDL,".
@@ -282,7 +292,7 @@ class Interop_Client extends Interop_Base
                     ($wire?$this->dbc->quote($wire):"''").")";
         #echo "\n".$sql;
         $res = $this->dbc->query($sql);
-        
+
         if (DB::isError($res)) {
             die ($res->getMessage());
         }
@@ -296,7 +306,7 @@ class Interop_Client extends Interop_Base
     * @param SOAP_Value soapval
     * @return mixed result
     * @access public
-    */    
+    */
     function decodeSoapval($soapval)
     {
         if (gettype($soapval) == "object" &&
@@ -320,7 +330,7 @@ class Interop_Client extends Interop_Base
         }
         return $val;
     }
-    
+
     /**
     *  compareResult
     * compare two php types for a match
@@ -329,22 +339,10 @@ class Interop_Client extends Interop_Base
     * @param string test_result
     * @return boolean result
     * @access public
-    */    
+    */
     function compareResult($expect, $result, $type = NULL)
     {
-        $ok = 0;
-        $expect_type = gettype($expect);
-        $result_type = gettype($result);
-        if ($expect_type == "array" && $result_type == "array") {
-            # compare arrays
-            $ok = array_compare($expect, $result);
-        } else {
-            if ($type == 'boolean')
-                $ok = boolean_compare($expect, $result);
-            else
-                $ok = string_compare($expect, $result);
-        }
-        return $ok;
+    	return compare($expect, $result);
     }
 
 
@@ -356,22 +354,23 @@ class Interop_Client extends Interop_Base
     * @param SOAP_Test test
     * @return boolean result
     * @access public
-    */    
+    */
     function doEndpointMethod(&$endpoint_info, &$soap_test) {
         $ok = FALSE;
-        
+
         // prepare a holder for the test results
         $soap_test->result['class'] = $this->currentTest;
         $soap_test->result['type'] = $this->paramType;
         $soap_test->result['wsdl'] = $this->useWSDL;
-        
+
         if ($this->useWSDL) {
             if (array_key_exists('wsdlURL',$endpoint_info)) {
                 if (!array_key_exists('client',$endpoint_info)) {
                     $endpoint_info['client'] = new SoapObject($endpoint_info['wsdlURL']);
+                    $endpoint_info['client']->__trace(1);
                 }
                 $soap =& $endpoint_info['client'];
-                
+
                 # XXX how do we determine a failure on retreiving/parsing wsdl?
                 if ($soap->wsdl->fault) {
                     $fault = $soap->wsdl->fault->getFault();
@@ -404,6 +403,7 @@ class Interop_Client extends Interop_Base
             }
             if (!array_key_exists('client',$endpoint_info)) {
                 $endpoint_info['client'] = new SoapObject($endpoint_info['endpointURL'],$soapaction);
+                $endpoint_info['client']->__trace(1);
             }
             $soap = $endpoint_info['client'];
         }
@@ -417,7 +417,6 @@ class Interop_Client extends Interop_Base
         // XXX no way to set encoding
         // this lets us set UTF-8, US-ASCII or other
         //$soap->setEncoding($soap_test->encoding);
-        
         if ($this->useWSDL) {
             $args = '';
             foreach ($soap_test->method_params as $pname => $param) {
@@ -428,16 +427,16 @@ class Interop_Client extends Interop_Base
         } else {
             $return = $soap->__call($soap_test->method_name,$soap_test->method_params,$soapaction, $namespace);
         }
-        
-        // save the wire
-        $wire = $soap->__getlastrequest()."\n\n".$soap->__getlastresponse();
-        $wire = str_replace('>',">\n",$wire);
-        $wire = str_replace('" ',"\" \n",$wire);
-        #print $wire;
-        
+
+
         if(!$soap->__isfault()){
-            if (is_array($soap_test->method_params) && count($soap_test->method_params) == 1) {
-                $sent = array_shift($soap_test->method_params);
+            if ($soap_test->expect !== NULL) {
+                $sent = $soap_test->expect;
+            } else if (is_array($soap_test->method_params) && count($soap_test->method_params) == 1) {
+                reset($soap_test->method_params);
+                $sent = current($soap_test->method_params);
+            } else if (is_array($soap_test->method_params) && count($soap_test->method_params) == 0) {
+                $sent = null;
             } else {
                 $sent = $soap_test->method_params;
             }
@@ -445,7 +444,7 @@ class Interop_Client extends Interop_Base
             // compare header results
             $header_result = array();
             $headers_ok = TRUE;
-            
+
             # XXX need to implement header support!
             #
             #if ($soap_test->headers) {
@@ -476,15 +475,24 @@ class Interop_Client extends Interop_Base
 
             # we need to decode what we sent so we can compare!
             $sent_d = $this->decodeSoapval($sent);
-            
+
             $soap_test->result['sent'] = $sent;
             $soap_test->result['return'] = $return;
+
             // compare the results with what we sent
+
             $ok = $this->compareResult($sent_d,$return, $sent->type);
             if (!$ok && $soap_test->expect) {
                 $ok = $this->compareResult($soap_test->expect,$return);
             }
-            
+
+            // save the wire
+            $wire = "REQUEST:\n".str_replace('" ',"\" \n",str_replace('>',">\n",$soap->__getlastrequest()))."\n\n".
+                    "RESPONSE:\n".str_replace('" ',"\" \n",str_replace('>',">\n",$soap->__getlastresponse()))."\n\n".
+                    "EXPECTED:\n".var_dump_str($sent_d)."\n".
+                    "RESULTL:\n".var_dump_str($return);
+            #print "Wire:".htmlentities($wire);
+
             if($ok){
                 if (!$headers_ok) {
                     $fault = new SoapFault('HEADER','The returned result did not match what we expected to receive');
@@ -514,48 +522,54 @@ class Interop_Client extends Interop_Base
                 $ok = 0;
                 $res =$fault->faultcode;
             }
+            // save the wire
+            $wire = "REQUEST:\n".str_replace('" ',"\" \n",str_replace('>',">\n",$soap->__getlastrequest()))."\n\n".
+                    "RESPONSE:\n".str_replace('" ',"\" \n",str_replace('>',">\n",$soap->__getlastresponse()));
+            #print "Wire:".htmlentities($wire);
+
             $soap_test->setResult($ok,$res, $wire,$fault->faultstring, $fault);
+
         }
         return $ok;
     }
-    
+
 
     /**
     *  doTest
     *  run a single round of tests
     *
     * @access public
-    */    
+    */
     function doTest() {
         global $soap_tests;
         // get endpoints for this test
         $this->getEndpoints($this->currentTest);
         #clear totals
         $this->totals = array();
-        
+
         $i = 0;
         foreach($this->endpoints as $endpoint => $endpoint_info){
-            
+
             // if we specify an endpoint, skip until we find it
             if ($this->specificEndpoint && $endpoint != $this->specificEndpoint) continue;
             if ($this->useWSDL && !$endpoint_info['endpointURL']) continue;
-            
+
             $skipendpoint = FALSE;
             $this->totals['servers']++;
             #$endpoint_info['tests'] = array();
-            
+
             if ($this->show) print "Processing $endpoint at {$endpoint_info['endpointURL']}
\n"; - + foreach($soap_tests[$this->currentTest] as $soap_test) { //foreach(array_keys($method_params[$this->currentTest][$this->paramType]) as $method) - + // only run the type of test we're looking for (php or soapval) if ($soap_test->type != $this->paramType) continue; - + // if we haven't reached our startpoint, skip if ($this->startAt && $this->startAt != $endpoint_info['endpointName']) continue; $this->startAt = ''; - + // if this is in our skip list, skip it if (in_array($endpoint, $this->skipEndpointList)) { $skipendpoint = TRUE; @@ -570,13 +584,13 @@ class Interop_Client extends Interop_Base $soap_test->result = NULL; continue; } - + // if we're looking for a specific method, skip unless we have it - if ($this->testMethod && !strstr($this->testMethod,$soap_test->test_name)) continue; + if ($this->testMethod && strcmp($this->testMethod,$soap_test->test_name) != 0) continue; if ($this->testMethod && $this->currentTest == 'GroupC') { // we have to figure things out now if (!preg_match('/(.*):(.*),(\d),(\d)/',$this->testMethod, $m)) continue; - + // is the header in the headers list? $gotit = FALSE; foreach ($soap_test->headers as $header) { @@ -594,7 +608,7 @@ class Interop_Client extends Interop_Base } if (!$gotit) continue; } - + // if we are skipping the rest of the tests (due to error) note a fault if ($skipendpoint) { $soap_test->setResult(0,$fault->faultcode, '', @@ -623,7 +637,7 @@ class Interop_Client extends Interop_Base if ($this->numservers && ++$i >= $this->numservers) break; } } - + function doGroupTests() { $dowsdl = array(0,1); foreach($dowsdl as $usewsdl) { @@ -636,13 +650,13 @@ class Interop_Client extends Interop_Base } } } - + /** * doTests * go all out. This takes time. * * @access public - */ + */ function doTests() { // the mother of all interop tests $dowsdl = array(0,1); @@ -659,10 +673,10 @@ class Interop_Client extends Interop_Base } } } - + // *********************************************************** // output functions - + /** * getResults * retreive results from the database, stuff them into the endpoint array @@ -679,18 +693,18 @@ class Interop_Client extends Interop_Base } return $ar; } - + function outputTable() { $methods = $this->getMethodList($this->currentTest); if (!$methods) return; $this->getResults($this->currentTest,$this->paramType,$this->useWSDL); - + echo "Testing $this->currentTest "; if ($this->useWSDL) echo "using WSDL "; else echo "using Direct calls "; echo "with $this->paramType values
\n"; - + // calculate totals for this table $this->totals['success'] = 0; $this->totals['fail'] = 0; @@ -709,14 +723,14 @@ class Interop_Client extends Interop_Base } $this->totals['calls'] = count($methods) * $this->totals['servers']; - if ($this->totals['fail'] == $this->totals['calls']) { - // assume tests have not run, skip outputing table - print "No Data Available
\n"; - return; - } - +# if ($this->totals['fail'] == $this->totals['calls']) { +# // assume tests have not run, skip outputing table +# print "No Data Available
\n"; +# return; +# } + echo "\n\nServers: {$this->totals['servers']} Calls: {$this->totals['calls']} Success: {$this->totals['success']} Fail: {$this->totals['fail']}
\n"; - + echo "\n"; echo "\n"; foreach ($methods as $method) { @@ -766,7 +780,7 @@ class Interop_Client extends Interop_Base } echo "

\n"; } - + function outputTables() { // the mother of all interop tests $dowsdl = array(0,1); @@ -783,7 +797,7 @@ class Interop_Client extends Interop_Base } } } - + function showWire($id) { $results = $this->dbc->getAll("select * from results where id=$id",NULL, DB_FETCHMODE_ASSOC ); #$wire = preg_replace("/>/",">\n",$results[0]['wire']); diff --git a/ext/soap/interop/client_round2_params.php b/ext/soap/interop/client_round2_params.php index 262093c0b7..b78fb14bce 100644 --- a/ext/soap/interop/client_round2_params.php +++ b/ext/soap/interop/client_round2_params.php @@ -35,11 +35,11 @@ class SOAP_Test { var $show = 1; var $debug = 0; var $encoding = 'UTF-8'; - + function SOAP_Test($methodname, $params, $expect = NULL) { # XXX we have to do this to make php-soap happy with NULL params if (!$params) $params = array(); - + if (strchr($methodname,'(')) { preg_match('/(.*)\((.*)\)/',$methodname,$matches); $this->test_name = $methodname; @@ -48,8 +48,10 @@ class SOAP_Test { $this->test_name = $this->method_name = $methodname; } $this->method_params = $params; - $this->expect = $expect; - + if ($expect !== NULL) { + $this->expect = $expect; + } + // determine test type if ($params) { $v = array_values($params); @@ -58,7 +60,7 @@ class SOAP_Test { $this->type = 'soapval'; } } - + function setResult($ok, $result, $wire, $error = '', $fault = NULL) { $this->result['success'] = $ok; @@ -75,19 +77,19 @@ class SOAP_Test { * @param array endpoint_info * @param string method * @access public - */ + */ function showTestResult($debug = 0) { // debug output if ($debug) $this->show = 1; if ($debug) { echo str_repeat("-",50)."
\n"; } - + echo "testing $this->test_name : "; if ($this->headers) { foreach ($this->headers as $h) { if (get_class($h) == 'soap_header') { - + echo "\n {$h->name},{$h->attributes['SOAP-ENV:actor']},{$h->attributes['SOAP-ENV:mustUnderstand']} : "; } else { if (!$h[4]) $h[4] = SOAP_TEST_ACTOR_NEXT; @@ -96,22 +98,22 @@ class SOAP_Test { } } } - + if ($debug) { print "method params: "; print_r($this->params); print "\n"; } - + $ok = $this->result['success']; if ($ok) { - print "SUCCESS\n"; + print "SUCCESS\n"; } else { $fault = $this->result['fault']; if ($fault) { - print "FAILED: {$fault->faultcode} {$fault->faultstring}\n"; + print "FAILED: {$fault->faultcode} {$fault->faultstring}\n"; } else { - print "FAILED: ".$this->result['result']."\n"; + print "FAILED: ".$this->result['result']."\n"; } } if ($debug) { @@ -151,10 +153,14 @@ class SOAPStruct { $soap_tests['base'][] = new SOAP_Test('echoString', array('inputString' => 'hello world!')); $soap_tests['base'][] = new SOAP_Test('echoString', array('inputString' => soap_value('inputString','hello world',XSD_STRING))); -$soap_tests['base'][] = new SOAP_Test('echoString(null)', array('inputString' => "")); -$soap_tests['base'][] = new SOAP_Test('echoString(null)', array('inputString' => soap_value('inputString','',XSD_STRING))); -$soap_tests['base'][] = new SOAP_Test('echoString(entities)', array('inputString' => 'hello world\nline 2\n')); -$soap_tests['base'][] = new SOAP_Test('echoString(entities)', array('inputString' => soap_value('inputString','hello world\nline 2\n',XSD_STRING))); +$soap_tests['base'][] = new SOAP_Test('echoString(empty)', array('inputString' => '')); +$soap_tests['base'][] = new SOAP_Test('echoString(empty)', array('inputString' => soap_value('inputString','',XSD_STRING))); +$soap_tests['base'][] = new SOAP_Test('echoString(null)', array('inputString' => NULL)); +$soap_tests['base'][] = new SOAP_Test('echoString(null)', array('inputString' => soap_value('inputString',NULL,XSD_STRING))); +//$soap_tests['base'][] = new SOAP_Test('echoString(entities)', array('inputString' => ">,<,&,\",',0:\x00",1:\x01,2:\x02,3:\x03,4:\x04,5:\x05,6:\x06,7:\x07,8:\x08,9:\x09,10:\x0a,11:\x0b,12:\x0c,13:\x0d,14:\x0e,15:\x0f,16:\x10,17:\x11,18:\x12,19:\x13,20:\x14,21:\x15,22:\x16,23:\x17,24:\x18,25:\x19,26:\x1a,27:\x1b,28:\x1c,29:\x1d,30:\x1e,31:\x1f")); +//$soap_tests['base'][] = new SOAP_Test('echoString(entities)', array('inputString' => soap_value('inputString',">,<,&,\",',0:\x00",1:\x01,2:\x02,3:\x03,4:\x04,5:\x05,6:\x06,7:\x07,8:\x08,9:\x09,10:\x0a,11:\x0b,12:\x0c,13:\x0d,14:\x0e,15:\x0f,16:\x10,17:\x11,18:\x12,19:\x13,20:\x14,21:\x15,22:\x16,23:\x17,24:\x18,25:\x19,26:\x1a,27:\x1b,28:\x1c,29:\x1d,30:\x1e,31:\x1f",XSD_STRING))); +$soap_tests['base'][] = new SOAP_Test('echoString(entities)', array('inputString' => ">,<,&,\",',\\,\n")); +$soap_tests['base'][] = new SOAP_Test('echoString(entities)', array('inputString' => soap_value('inputString',">,<,&,\",',\\,\n",XSD_STRING))); $test = new SOAP_Test('echoString(utf-8)', array('inputString' => utf8_encode('ỗÈéóÒ₧⅜ỗỸ'))); $test->encoding = 'UTF-8'; $soap_tests['base'][] = $test; @@ -170,15 +176,25 @@ $soap_tests['base'][] = new SOAP_Test('echoStringArray', $soap_tests['base'][] = new SOAP_Test('echoStringArray', array('inputStringArray' => soap_value('inputStringArray',array('good','bad'),SOAP_ENC_ARRAY))); - -// null array test + +$soap_tests['base'][] = new SOAP_Test('echoStringArray(one)', + array('inputStringArray' => array('good'))); +$soap_tests['base'][] = new SOAP_Test('echoStringArray(one)', + array('inputStringArray' => + soap_value('inputStringArray',array('good'),SOAP_ENC_ARRAY))); + +// empty array test +$soap_tests['base'][] = new SOAP_Test('echoStringArray(empty)', array('inputStringArray' => array())); +$soap_tests['base'][] = new SOAP_Test('echoStringArray(empty)', array('inputStringArray' => soap_value('inputStringArray',array(),SOAP_ENC_ARRAY))); + # XXX NULL Arrays not supported -#$soap_tests['base'][] = new SOAP_Test('echoStringArray(null)', array('inputStringArray' => NULL)); -#$soap_tests['base'][] = new SOAP_Test('echoStringArray(null)', array('inputStringArray' => soap_value('inputStringArray',NULL,XSD_STRING))); +// null array test +$soap_tests['base'][] = new SOAP_Test('echoStringArray(null)', array('inputStringArray' => NULL)); +$soap_tests['base'][] = new SOAP_Test('echoStringArray(null)', array('inputStringArray' => soap_value('inputStringArray',NULL,SOAP_ENC_ARRAY))); //*********************************************************** // Base echoInteger - +$x = new SOAP_Test('echoInteger', array('inputInteger' => 34345)); $soap_tests['base'][] = new SOAP_Test('echoInteger', array('inputInteger' => 34345)); $soap_tests['base'][] = new SOAP_Test('echoInteger', array('inputInteger' => soap_value('inputInteger',12345,XSD_INT))); @@ -191,12 +207,7 @@ $soap_tests['base'][] = new SOAP_Test('echoIntegerArray', soap_value('inputIntegerArray', array(new soapvar(12345,XSD_INT),new soapvar(654321,XSD_INT)), SOAP_ENC_ARRAY))); -# -#// null array test -# XXX NULL Arrays not supported -#$soap_tests['base'][] = new SOAP_Test('echoIntegerArray(null)', array('inputIntegerArray' => NULL)); -#$soap_tests['base'][] = new SOAP_Test('echoIntegerArray(null)', array('inputIntegerArray' => new SOAP_Value('inputIntegerArray','Array',NULL))); -# + //*********************************************************** // Base echoFloat @@ -207,7 +218,7 @@ $soap_tests['base'][] = new SOAP_Test('echoFloat', array('inputFloat' => soap_va // Base echoFloatArray $soap_tests['base'][] = new SOAP_Test('echoFloatArray', array('inputFloatArray' => array(1.3223,34.2,325.325))); -$soap_tests['base'][] = new SOAP_Test('echoFloatArray', +$soap_tests['base'][] = new SOAP_Test('echoFloatArray', array('inputFloatArray' => soap_value('inputFloatArray', array(new soapvar(123.45,XSD_FLOAT),new soapvar(654.321,XSD_FLOAT)), @@ -243,177 +254,179 @@ $soap_tests['base'][] = $test; $soap_tests['base'][] = new SOAP_Test('echoBase64', array('inputBase64' => 'TmVicmFza2E=')); $soap_tests['base'][] = new SOAP_Test('echoBase64', array('inputBase64' => - soap_value('inputBase64','TmVicmFza2E=',XSD_BASE64BINARY))); + soap_value('inputBase64','TmVicmFza2E=',XSD_BASE64BINARY))); //*********************************************************** // Base echoHexBinary $soap_tests['base'][] = new SOAP_Test('echoHexBinary', array('inputHexBinary' => '736F61707834')); -$soap_tests['base'][] = new SOAP_Test('echoHexBinary', array('inputHexBinary' => - soap_value('inputHexBinary','736F61707834',XSD_HEXBINARY))); +$soap_tests['base'][] = new SOAP_Test('echoHexBinary', array('inputHexBinary' => + soap_value('inputHexBinary','736F61707834',XSD_HEXBINARY))); //*********************************************************** // Base echoDecimal # XXX test fails because php-soap incorrectly sets decimal to long rather than float -$soap_tests['base'][] = new SOAP_Test('echoDecimal', array('inputDecimal' => 12345.67890)); -$soap_tests['base'][] = new SOAP_Test('echoDecimal', array('inputDecimal' => - soap_value('inputDecimal',12345.67890,XSD_DECIMAL))); +$soap_tests['base'][] = new SOAP_Test('echoDecimal', array('inputDecimal' => '12345.67890')); +$soap_tests['base'][] = new SOAP_Test('echoDecimal', array('inputDecimal' => + soap_value('inputDecimal','12345.67890',XSD_DECIMAL))); //*********************************************************** // Base echoDate # php-soap doesn't handle datetime types properly yet $soap_tests['base'][] = new SOAP_Test('echoDate', array('inputDate' => '2001-05-24T17:31:41Z')); -$soap_tests['base'][] = new SOAP_Test('echoDate', array('inputDate' => +$soap_tests['base'][] = new SOAP_Test('echoDate', array('inputDate' => soap_value('inputDate','2001-05-24T17:31:41Z',XSD_DATETIME)));#'2001-04-25T13:31:41-0700' - + //*********************************************************** // Base echoBoolean # php-soap sends boolean as zero or one, which is ok, but to be explicit, send true or false. -$soap_tests['base'][] = new SOAP_Test('echoBoolean', array('inputBoolean' => TRUE)); -$soap_tests['base'][] = new SOAP_Test('echoBoolean', array('inputBoolean' => +$soap_tests['base'][] = new SOAP_Test('echoBoolean(true)', array('inputBoolean' => TRUE)); +$soap_tests['base'][] = new SOAP_Test('echoBoolean(true)', array('inputBoolean' => soap_value('inputBoolean',TRUE,XSD_BOOLEAN))); -$soap_tests['base'][] = new SOAP_Test('echoBoolean', array('inputBoolean' => FALSE)); -$soap_tests['base'][] = new SOAP_Test('echoBoolean', array('inputBoolean' => +$soap_tests['base'][] = new SOAP_Test('echoBoolean(false)', array('inputBoolean' => FALSE)); +$soap_tests['base'][] = new SOAP_Test('echoBoolean(false)', array('inputBoolean' => soap_value('inputBoolean',FALSE,XSD_BOOLEAN))); +$soap_tests['base'][] = new SOAP_Test('echoBoolean(1)', array('inputBoolean' => 1),true); +$soap_tests['base'][] = new SOAP_Test('echoBoolean(1)', array('inputBoolean' => + soap_value('inputBoolean',1,XSD_BOOLEAN)),true); +$soap_tests['base'][] = new SOAP_Test('echoBoolean(0)', array('inputBoolean' => 0),false); +$soap_tests['base'][] = new SOAP_Test('echoBoolean(0)', array('inputBoolean' => + soap_value('inputBoolean',0,XSD_BOOLEAN)),false); + + + +//*********************************************************** +// GROUP B + + +//*********************************************************** +// GroupB echoStructAsSimpleTypes + +$expect = array( + 'outputString'=>'arg', + 'outputInteger'=>34, + 'outputFloat'=>325.325 + ); +$soap_tests['GroupB'][] = new SOAP_Test('echoStructAsSimpleTypes', + array('inputStruct' => (object)array( + 'varString'=>'arg', + 'varInt'=>34, + 'varFloat'=>325.325 + )), $expect); +$soap_tests['GroupB'][] = new SOAP_Test('echoStructAsSimpleTypes', + array('inputStruct' => + soap_value('inputStruct', + (object)array('varString' => 'arg', + 'varInt' => 34, + 'varFloat' => 325.325 + ), SOAP_ENC_OBJECT)), $expect); + +//*********************************************************** +// GroupB echoSimpleTypesAsStruct + +$expect = + (object)array( + 'varString'=>'arg', + 'varInt'=>34, + 'varFloat'=>325.325 + ); +$soap_tests['GroupB'][] = new SOAP_Test('echoSimpleTypesAsStruct', + array( + 'inputString'=>'arg', + 'inputInteger'=>34, + 'inputFloat'=>325.325 + ), $expect); +$soap_tests['GroupB'][] = new SOAP_Test('echoSimpleTypesAsStruct', + array( + soap_value('inputString','arg', XSD_STRING), + soap_value('inputInteger',34, XSD_INT), + soap_value('inputFloat',325.325, XSD_FLOAT) + ), $expect); + +//*********************************************************** +// GroupB echo2DStringArray + +$soap_tests['GroupB'][] = new SOAP_Test('echo2DStringArray', + array('input2DStringArray' => make_2d(3,3))); + +$multidimarray = + soap_value('input2DStringArray', + array( + array('row0col0', 'row0col1', 'row0col2'), + array('row1col0', 'row1col1', 'row1col2') + ), SOAP_ENC_ARRAY + ); +//$multidimarray->options['flatten'] = TRUE; +$soap_tests['GroupB'][] = new SOAP_Test('echo2DStringArray', + array('input2DStringArray' => $multidimarray)); + +//*********************************************************** +// GroupB echoNestedStruct + +$soap_tests['GroupB'][] = new SOAP_Test('echoNestedStruct', + array('inputStruct' => (object)array( + 'varString'=>'arg', + 'varInt'=>34, + 'varFloat'=>325.325, + 'varStruct' => (object)array( + 'varString'=>'arg', + 'varInt'=>34, + 'varFloat'=>325.325 + ) + ))); +$soap_tests['GroupB'][] = new SOAP_Test('echoNestedStruct', + array('inputStruct' => + soap_value('inputStruct', + (object)array( + 'varString'=>'arg', + 'varInt'=>34, + 'varFloat'=>325.325, + 'varStruct' => (object)array( + 'varString'=>'arg', + 'varInt'=>34, + 'varFloat'=>325.325 + ) +// array( #push struct elements into one soap value +// soap_value('varString','arg', XSD_STRING), +// soap_value('varInt',34, XSD_INT), +// soap_value('varFloat',325.325,XSD_FLOAT), +// soap_value('varStruct', +// (object)array('varString' => 'arg', +// 'varInt' => 34, +// 'varFloat' => 325.325 +// ), SOAP_ENC_OBJECT + ), SOAP_ENC_OBJECT + ))); + +//*********************************************************** +// GroupB echoNestedArray + +$soap_tests['GroupB'][] = new SOAP_Test('echoNestedArray', + array('inputStruct' => (object)array( + 'varString'=>'arg', + 'varInt'=>34, + 'varFloat'=>325.325, + 'varArray' => array('red','blue','green') + ))); +$soap_tests['GroupB'][] = new SOAP_Test('echoNestedArray', + array('inputStruct' => + soap_value('inputStruct', + (object)array('varString' => 'arg', + 'varInt' => 34, + 'varFloat' => 325.325, + 'varArray' => + array("red", "blue", "green") +// soap_value('item','red', XSD_STRING), +// soap_value('item','blue', XSD_STRING), +// soap_value('item','green', XSD_STRING) +// ) + ), SOAP_ENC_OBJECT + ))); + -# -# -#//*********************************************************** -#// GROUP B -# -# -#//*********************************************************** -#// GroupB echoStructAsSimpleTypes -# -#$expect = array( -# 'outputString'=>'arg', -# 'outputInteger'=>34, -# 'outputFloat'=>325.325 -# ); -#$soap_tests['GroupB'][] = new SOAP_Test('echoStructAsSimpleTypes', -# array('inputStruct' => array( -# 'varString'=>'arg', -# 'varInt'=>34, -# 'varFloat'=>325.325 -# )), $expect); -#$soap_tests['GroupB'][] = new SOAP_Test('echoStructAsSimpleTypes', -# array('inputStruct' => -# new SOAP_Value('inputStruct','SOAPStruct', -# array( #push struct elements into one soap value -# new SOAP_Value('varString','string','arg'), -# new SOAP_Value('varInt','int',34), -# new SOAP_Value('varFloat','float',325.325) -# ))), $expect); -# -#//*********************************************************** -#// GroupB echoSimpleTypesAsStruct -# -#$expect = -# array( -# 'varString'=>'arg', -# 'varInt'=>34, -# 'varFloat'=>325.325 -# ); -#$soap_tests['GroupB'][] = new SOAP_Test('echoSimpleTypesAsStruct', -# array( -# 'inputString'=>'arg', -# 'inputInteger'=>34, -# 'inputFloat'=>325.325 -# ), $expect); -#$soap_tests['GroupB'][] = new SOAP_Test('echoSimpleTypesAsStruct', -# array( -# new SOAP_Value('inputString','string','arg'), -# new SOAP_Value('inputInteger','int',34), -# new SOAP_Value('inputFloat','float',325.325) -# ), $expect); -# -#//*********************************************************** -#// GroupB echo2DStringArray -# -#$soap_tests['GroupB'][] = new SOAP_Test('echo2DStringArray', -# array('input2DStringArray' => make_2d(3,3))); -# -#$multidimarray = -# new SOAP_Value('input2DStringArray','Array', -# array( -# array( -# new SOAP_Value('item','string','row0col0'), -# new SOAP_Value('item','string','row0col1'), -# new SOAP_Value('item','string','row0col2') -# ), -# array( -# new SOAP_Value('item','string','row1col0'), -# new SOAP_Value('item','string','row1col1'), -# new SOAP_Value('item','string','row1col2') -# ) -# ) -# ); -#$multidimarray->options['flatten'] = TRUE; -#$soap_tests['GroupB'][] = new SOAP_Test('echo2DStringArray', -# array('input2DStringArray' => $multidimarray)); -# -#//*********************************************************** -#// GroupB echoNestedStruct -# -#$soap_tests['GroupB'][] = new SOAP_Test('echoNestedStruct', -# array('inputStruct' => array( -# 'varString'=>'arg', -# 'varInt'=>34, -# 'varFloat'=>325.325, -# 'varStruct' => array( -# 'varString'=>'arg', -# 'varInt'=>34, -# 'varFloat'=>325.325 -# ) -# ))); -#$soap_tests['GroupB'][] = new SOAP_Test('echoNestedStruct', -# array('inputStruct' => -# new SOAP_Value('inputStruct','struct', -# array( #push struct elements into one soap value -# new SOAP_Value('varString','string','arg'), -# new SOAP_Value('varInt','int',34), -# new SOAP_Value('varFloat','float',325.325), -# new SOAP_Value('varStruct','SOAPStruct', -# array( #push struct elements into one soap value -# new SOAP_Value('varString','string','arg'), -# new SOAP_Value('varInt','int',34), -# new SOAP_Value('varFloat','float',325.325) -# ) -# /*,NULL,'http://soapinterop.org/xsd'*/) -# ) -# ))); -# -#//*********************************************************** -#// GroupB echoNestedArray -# -#$soap_tests['GroupB'][] = new SOAP_Test('echoNestedArray', -# array('inputStruct' => array( -# 'varString'=>'arg', -# 'varInt'=>34, -# 'varFloat'=>325.325, -# 'varArray' => array('red','blue','green') -# ))); -#$soap_tests['GroupB'][] = new SOAP_Test('echoNestedArray', -# array('inputStruct' => -# new SOAP_Value('inputStruct','struct', -# array( #push struct elements into one soap value -# new SOAP_Value('varString','string','arg'), -# new SOAP_Value('varInt','int',34), -# new SOAP_Value('varFloat','float',325.325), -# new SOAP_Value('varArray','Array', -# array( #push struct elements into one soap value -# new SOAP_Value('item','string','red'), -# new SOAP_Value('item','string','blue'), -# new SOAP_Value('item','string','green') -# ) -# ) -# ) -# ))); -# -# #//*********************************************************** #// GROUP C header tests # diff --git a/ext/soap/interop/client_round2_results.php b/ext/soap/interop/client_round2_results.php index 69f82ab582..42c49e2b39 100644 --- a/ext/soap/interop/client_round2_results.php +++ b/ext/soap/interop/client_round2_results.php @@ -60,7 +60,7 @@ if ($_GET['wire']) { } else { $iop->getEndpoints(); $iop->getResults(); - + if ($_GET['test']) { $iop->currentTest = $_GET['test']; $iop->useWSDL = $_GET['wsdl']?$_GET['wsdl']:0; diff --git a/ext/soap/interop/client_round2_run.php b/ext/soap/interop/client_round2_run.php index ab773c7e21..d879353694 100644 --- a/ext/soap/interop/client_round2_run.php +++ b/ext/soap/interop/client_round2_run.php @@ -29,17 +29,17 @@ $iop = new Interop_Client(); // set some options $iop->currentTest = 'base'; // see $tests above $iop->paramType = 'php'; // 'php' or 'soapval' -$iop->useWSDL = 1; // 1= do wsdl tests +$iop->useWSDL = 0; // 1= do wsdl tests $iop->numServers = 0; // 0 = all -$iop->specificEndpoint = '4s4c'; // test only this endpoint -$iop->testMethod = 'echoString'; // test only this method +//$iop->specificEndpoint = '4s4c'; // test only this endpoint +//$iop->testMethod = 'echoString'; // test only this method #XXX MS SOAP ToolKit 2.0/3.0 crashes php-soap in __getfault! // endpoints to skip -$iop->skipEndpointList = array('Apache Axis','IONA XMLBus','IONA XMLBus (CORBA)','MS SOAP ToolKit 2.0','MS SOAP ToolKit 3.0','Spheon JSOAP','SQLData SOAP Server','WASP Advanced 3.0'); +$iop->skipEndpointList = array('Apache Axis','IONA XMLBus','IONA XMLBus (CORBA)','MS SOAP ToolKit 2.0','MS SOAP ToolKit 3.0','Spheon JSOAP','SQLData SOAP Server','WASP Advanced 3.0'); $iop->startAt=''; -$this->nosave = 0; // 1= disable saving results to database +$iop->nosave = 0; // 1= disable saving results to database // debug output $iop->show = 1; $iop->debug = 0; diff --git a/ext/soap/interop/config.php.dist b/ext/soap/interop/config.php.dist new file mode 100644 index 0000000000..3e9549cdfe --- /dev/null +++ b/ext/soap/interop/config.php.dist @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/ext/soap/interop/database_round2.sql b/ext/soap/interop/database_round2.sql index 79669a04c2..6834b0eeae 100644 --- a/ext/soap/interop/database_round2.sql +++ b/ext/soap/interop/database_round2.sql @@ -42,4 +42,3 @@ CREATE TABLE results ( wire text NOT NULL, PRIMARY KEY (id) ) TYPE=MyISAM; - diff --git a/ext/soap/interop/echoheadersvc.wsdl b/ext/soap/interop/echoheadersvc.wsdl.php similarity index 80% rename from ext/soap/interop/echoheadersvc.wsdl rename to ext/soap/interop/echoheadersvc.wsdl.php index a279580dc3..2eb5c8c6e1 100644 --- a/ext/soap/interop/echoheadersvc.wsdl +++ b/ext/soap/interop/echoheadersvc.wsdl.php @@ -1,4 +1,8 @@ - +'; +echo "\n"; +?> @@ -8,7 +12,7 @@ - + diff --git a/ext/soap/interop/endpointdata.sql b/ext/soap/interop/endpointdata.sql deleted file mode 100644 index 80d9d5ac9c..0000000000 --- a/ext/soap/interop/endpointdata.sql +++ /dev/null @@ -1,85 +0,0 @@ -# phpMyAdmin MySQL-Dump -# version 2.2.5 -# http://phpwizard.net/phpMyAdmin/ -# http://phpmyadmin.sourceforge.net/ (download page) -# -# Host: localhost -# Generation Time: Jul 14, 2002 at 03:13 PM -# Server version: 3.23.49 -# PHP Version: 4.2.1 -# Database : `interop2` - -# -# Dumping data for table `endpoints` -# - -INSERT INTO endpoints VALUES (1, '4s4c', 'http://soap.4s4c.com/ilab/soap.asp', 'http://www.pocketsoap.com/services/ilab.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (2, '4s4c v2.0', 'http://soap.4s4c.com/ilab2/soap.asp', 'http://soap.4s4c.com/ilab2/ilab.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (3, 'Apache Axis', 'http://nagoya.apache.org:5049/axis/services/echo', 'http://nagoya.apache.org:5049/axis/services/echo?wsdl', 'base', 1); -INSERT INTO endpoints VALUES (4, 'Apache SOAP 2.2', 'http://nagoya.apache.org:5049/soap/servlet/rpcrouter', 'http://www.apache.org/~rubys/ApacheSoap.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (5, 'ASP.NET Web Services', 'http://www.mssoapinterop.org/asmx/simple.asmx', 'http://www.mssoapinterop.org/asmx/simple.asmx?wsdl', 'base', 1); -INSERT INTO endpoints VALUES (6, 'CapeConnect', 'http://interop.capeclear.com/ccx/soapbuilders-round2', 'http://interop.capeclear.com/wsdl/soapbuilders-round2.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (7, 'Delphi SOAP', 'http://soap-server.borland.com/WebServices/Interop/cgi-bin/InteropService.exe/soap/InteropTestPortType', 'http://soap-server.borland.com/WebServices/Interop/cgi-bin/InteropService.exe/wsdl/InteropTestPortType', 'base', 1); -INSERT INTO endpoints VALUES (8, 'EasySoap++', 'http://easysoap.sourceforge.net/cgi-bin/interopserver', 'http://easysoap.sourceforge.net/interopA.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (9, 'eSOAP', 'http://www.quakersoft.net/cgi-bin/interop2_server.cgi', 'http://www.quakersoft.net/wsdl/interop2.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (10, 'gSOAP', 'http://websrv.cs.fsu.edu/~engelen/interop2.cgi', 'http://www.cs.fsu.edu/~engelen/interop2.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (11, 'Frontier', 'http://www.soapware.org/xmethodsInterop', '', 'base', 1); -INSERT INTO endpoints VALUES (12, 'GLUE', 'http://www.themindelectric.net:8005/glue/round2', 'http://www.themindelectric.net:8005/glue/round2.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (13, 'HP SOAP', 'http://soap.bluestone.com/hpws/soap/EchoService', 'http://soap.bluestone.com/hpws/soap/EchoService.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (14, 'IONA XMLBus', 'http://interop.xmlbus.com:7002/xmlbus/container/InteropTest/BaseService/BasePort', 'http://interop.xmlbus.com:7002/xmlbus/container/InteropTest/BaseService/BasePort', 'base', 1); -INSERT INTO endpoints VALUES (15, 'IONA XMLBus (CORBA)', 'http://interop.xmlbus.com:7002/xmlbus/container/CORBAInterop/BaseService/BasePort', 'http://interop.xmlbus.com:7002/xmlbus/container/CORBAInterop/BaseService/BasePort', 'base', 1); -INSERT INTO endpoints VALUES (16, 'kSOAP', 'http://kissen.cs.uni-dortmund.de:8080/ksoapinterop', 'http://www.whitemesa.com/interop/kSOAP.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (17, 'MS .NET Remoting', 'http://www.mssoapinterop.org/remoting/ServiceA.soap', 'http://www.mssoapinterop.org/remoting/ServiceA.soap?wsdl', 'base', 1); -INSERT INTO endpoints VALUES (18, 'MS SOAP ToolKit 2.0', 'http://mssoapinterop.org/stk/Interop.wsdl', 'http://mssoapinterop.org/stk/Interop.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (19, 'MS SOAP ToolKit 3.0', 'http://mssoapinterop.org/stkV3/Interop.wsdl', 'http://mssoapinterop.org/stkV3/Interop.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (20, 'NuSOAP', 'http://dietrich.ganx4.com/nusoap/testbed/round2_base_server.php', 'http://dietrich.ganx4.com/nusoap/testbed/round2_base.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (21, 'OpenLink', 'http://demo.openlinksw.com:8890/Interop', 'http://demo.openlinksw.com:8890/Interop/services.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (24, 'SIM', 'http://soapinterop.simdb.com/round2', 'http://soapinterop.simdb.com/round2?WSDL', 'base', 1); -INSERT INTO endpoints VALUES (25, 'SOAP4R', 'http://www.jin.gr.jp/~nahi/Ruby/SOAP4R/SOAPBuildersInterop/', 'http://www.jin.gr.jp/~nahi/Ruby/SOAP4R/SOAPBuildersInterop/SOAP4R_SOAPBuildersInteropTest_R2base.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (26, 'SOAP:Lite', 'http://services.soaplite.com/interop.cgi', 'http://services.soaplite.com/interop2.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (27, 'Spheon JSOAP', 'http://213.23.125.181:8081/RPC', 'http://213.23.125.181:8081/interop.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (28, 'Spray 2001', 'http://www.dolphinharbor.org/services/interop2001', 'http://www.dolphinharbor.org/services/interop2001/service.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (29, 'SQLData SOAP Server', 'http://soapclient.com/interop/sqldatainterop.wsdl', 'http://soapclient.com/interop/sqldatainterop.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (30, 'WASP Advanced 3.0', 'http://soap.systinet.net:6060/InteropService/', 'http://soap.systinet.net:6060/InteropService/', 'base', 1); -INSERT INTO endpoints VALUES (32, 'White Mesa SOAP Server', 'http://www.whitemesa.net/interop/std', 'http://www.whitemesa.net/wsdl/std/interop.wsdl', 'base', 1); -INSERT INTO endpoints VALUES (33, 'PEAR SOAP', 'http://localhost/soap_interop/server_round2.php', 'http://localhost/soap_interop/interop.wsdl.php', 'base', 1); -INSERT INTO endpoints VALUES (34, '4s4c', 'http://soap.4s4c.com/ilab/soap.asp', 'http://www.pocketsoap.com/services/ilab_b.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (35, '4s4c v2.0', 'http://soap.4s4c.com/ilab2/soap.asp', 'http://soap.4s4c.com/ilab2/ilab_b.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (36, 'Apache Axis', 'http://nagoya.apache.org:5049/axis/services/echo', 'http://nagoya.apache.org:5049/axis/services/echo?wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (37, 'ASP.NET Web Services', 'http://www.mssoapinterop.org/asmx/simpleB.asmx', 'http://www.mssoapinterop.org/asmx/simpleb.asmx?wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (38, 'Delphi SOAP', 'http://soap-server.borland.com/WebServices/Interop/cgi-bin/InteropGroupB.exe/soap/InteropTestPortTypeB', 'http://soap-server.borland.com/WebServices/Interop/cgi-bin/InteropGroupB.exe/wsdl/InteropTestPortTypeB', 'GroupB', 1); -INSERT INTO endpoints VALUES (39, 'EasySoap++', 'http://easysoap.sourceforge.net/cgi-bin/interopserver', 'http://easysoap.sourceforge.net/interopB.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (40, 'GLUE', 'http://www.themindelectric.net:8005/glue/round2B', 'http://www.themindelectric.net:8005/glue/round2B.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (41, 'gSOAP', 'http://websrv.cs.fsu.edu/~engelen/interop2B.cgi', 'http://www.cs.fsu.edu/~engelen/interop2B.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (42, 'HP SOAP', 'http://soap.bluestone.com/hpws/soap/EchoService', 'http://soap.bluestone.com/hpws/soap/EchoService.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (43, 'IONA XMLBus', 'http://interop.xmlbus.com:7002/xmlbus/container/InteropTest/GroupBService/GroupBPort', 'http://interop.xmlbus.com:7002/xmlbus/container/InteropTest/GroupBService/GroupBPort', 'GroupB', 1); -INSERT INTO endpoints VALUES (44, 'MS .NET Remoting', 'http://www.mssoapinterop.org/remoting/ServiceB.soap', 'http://www.mssoapinterop.org/remoting/ServiceB.soap?wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (45, 'MS SOAP ToolKit 2.0', 'http://mssoapinterop.org/stk/InteropBtyped.wsdl', 'http://mssoapinterop.org/stk/InteropBtyped.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (46, 'MS SOAP ToolKit 3.0', 'http://mssoapinterop.org/stkV3/InteropB.wsdl', 'http://mssoapinterop.org/stkV3/InteropB.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (47, 'NuSOAP', 'http://dietrich.ganx4.com/nusoap/testbed/round2_groupb_server.php', 'http://dietrich.ganx4.com/nusoap/testbed/round2_groupb.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (48, 'OpenLink', 'http://demo.openlinksw.com:8890/Interop', 'http://demo.openlinksw.com:8890/Interop/services.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (50, 'SIM', 'http://soapinterop.simdb.com/round2B', 'http://soapinterop.simdb.com/round2B?WSDL', 'GroupB', 1); -INSERT INTO endpoints VALUES (51, 'SOAP4R', 'http://www.jin.gr.jp/~nahi/Ruby/SOAP4R/SOAPBuildersInterop/', 'http://www.jin.gr.jp/~nahi/Ruby/SOAP4R/SOAPBuildersInterop/SOAP4R_SOAPBuildersInteropTest_R2GroupB.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (52, 'SOAP:Lite', 'http://services.soaplite.com/interop.cgi', 'http://services.soaplite.com/InteropTestB.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (53, 'Spheon JSOAP', 'http://213.23.125.181:8081/RPC', 'http://213.23.125.181:8081/interopb.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (54, 'Spray 2001', 'http://www.dolphinharbor.org/services/interopB2001', 'http://www.dolphinharbor.org/services/interopB2001/service.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (55, 'SQLData SOAP Server', 'http://soapclient.com/interop/InteropB.wsdl', 'http://soapclient.com/interop/InteropB.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (56, 'WASP Advanced 3.0', 'http://soap.systinet.net:6060/InteropBService/', 'http://soap.systinet.net:6060/InteropBService/', 'GroupB', 1); -INSERT INTO endpoints VALUES (58, 'White Mesa SOAP Server', 'http://www.whitemesa.net/interop/std/groupB', 'http://www.whitemesa.net/wsdl/std/interopB.wsdl', 'GroupB', 1); -INSERT INTO endpoints VALUES (59, 'PEAR SOAP', 'http://localhost/soap_interop/server_round2.php', 'http://localhost/soap_interop/interopB.wsdl.php', 'GroupB', 1); -INSERT INTO endpoints VALUES (60, '4s4c v2.0', 'http://soap.4s4c.com/ilab2/soap.asp', 'http://soap.4s4c.com/ilab2/ilab_c.wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (61, 'Apache Axis', 'http://nagoya.apache.org:5049/axis/services/echo', 'http://nagoya.apache.org:5049/axis/services/echo?wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (62, 'ASP.NET Web Services', 'http://mssoapinterop.org/asmx/header.asmx', 'http://mssoapinterop.org/asmx/header.asmx?wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (63, 'EasySoap++', 'http://easysoap.sourceforge.net/cgi-bin/interopserver', 'http://easysoap.sourceforge.net/interopC.wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (64, 'MS SOAP ToolKit 2.0', 'http://mssoapinterop.org/stk/InteropC.wsdl', 'http://mssoapinterop.org/stk/InteropC.wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (65, 'MS SOAP ToolKit 3.0', 'http://mssoapinterop.org/stkV3/InteropC.wsdl', 'http://mssoapinterop.org/stkV3/InteropC.wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (66, 'OpenLink', 'http://demo.openlinksw.com:8890/Interop', 'http://demo.openlinksw.com:8890/Interop/services.wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (67, 'SOAP:Lite', 'http://services.soaplite.com/interopC.cgi', 'http://services.soaplite.com/InteropTestC.wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (68, 'Spray 2001', 'http://www.dolphinharbor.org/services/interopC', 'http://www.dolphinharbor.org/services/interopC/service.wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (69, 'SQLData SOAP Server', 'http://soapclient.com/interop/interopC.wsdl', 'http://soapclient.com/interop/interopC.wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (70, 'WASP Advanced 3.0', 'http://soap.systinet.net:6060/InteropCService/', 'http://soap.systinet.net:6060/InteropCService/', 'GroupC', 1); -INSERT INTO endpoints VALUES (71, 'White Mesa SOAP Server', 'http://www.whitemesa.net/interop/std/echohdr', 'http://www.whitemesa.net/wsdl/std/echoheadersvc.wsdl', 'GroupC', 1); -INSERT INTO endpoints VALUES (72, 'PEAR SOAP', 'http://localhost/soap_interop/server_round2.php', 'http://localhost/soap_interop/echoheadersvc.wsdl.php', 'GroupC', 1); - - - diff --git a/ext/soap/interop/index.php b/ext/soap/interop/index.php index ed222479b2..7c63ebf79f 100644 --- a/ext/soap/interop/index.php +++ b/ext/soap/interop/index.php @@ -7,10 +7,9 @@ @@ -21,7 +20,6 @@ at White Mesa.

Currently Round 2 base, Group B and Group C interop tests are enabled.

Round 2 Interop Server

-Endpoint:
Base WSDL:
Group B WSDL:
Group C WSDL:
diff --git a/ext/soap/interop/info.php b/ext/soap/interop/info.php deleted file mode 100644 index 147cebcdd4..0000000000 --- a/ext/soap/interop/info.php +++ /dev/null @@ -1 +0,0 @@ - diff --git a/ext/soap/interop/interop.wsdl b/ext/soap/interop/interop.wsdl deleted file mode 100644 index 6a835b571f..0000000000 --- a/ext/soap/interop/interop.wsdl +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/ext/soap/interop/interop.wsdl.php b/ext/soap/interop/interop.wsdl.php new file mode 100644 index 0000000000..e71a19c76d --- /dev/null +++ b/ext/soap/interop/interop.wsdl.php @@ -0,0 +1,335 @@ +'; +echo "\n"; +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/soap/interop/interopB.wsdl b/ext/soap/interop/interopB.wsdl deleted file mode 100644 index 92301af334..0000000000 --- a/ext/soap/interop/interopB.wsdl +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/ext/soap/interop/server_round2.php b/ext/soap/interop/server_round2.php deleted file mode 100644 index a8eafe1eb2..0000000000 --- a/ext/soap/interop/server_round2.php +++ /dev/null @@ -1,35 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id$ -// - -require_once 'SOAP/Server.php'; - -$server = new SOAP_Server; - -require_once 'server_round2_base.php'; -require_once 'server_round2_groupB.php'; -require_once 'server_round2_groupC.php'; - -$server->service(isset($HTTP_RAW_POST_DATA)?$HTTP_RAW_POST_DATA:NULL); -#echo "Content-Length is {$_SERVER['CONTENT_LENGTH']}\n\n"; -#echo ""; -?> \ No newline at end of file diff --git a/ext/soap/interop/server_round2_base.php b/ext/soap/interop/server_round2_base.php index 15dc48e565..314a5c85e2 100644 --- a/ext/soap/interop/server_round2_base.php +++ b/ext/soap/interop/server_round2_base.php @@ -19,7 +19,6 @@ // // $Id$ // -require_once 'SOAP/Server.php'; function generateFault($short, $long) { @@ -42,7 +41,7 @@ function hex2bin($data) class SOAP_Interop_Base { var $method_namespace = 'http://soapinterop.org/'; - + function SOAP_Interop_Base() { #if ($server) { # $server->addToMap("echoString",array("string"),array("string")); @@ -64,121 +63,83 @@ class SOAP_Interop_Base { function echoString($inputString) { - return new SOAP_Value('outputString','string',$inputString); + return $inputString; } function echoStringArray($inputStringArray) { - $ra = array(); - if ($inputStringArray) { - foreach($inputStringArray as $s) { - $ra[] = new SOAP_Value('item','string',$s); - } - } - return new SOAP_Value('outputStringArray',NULL,$ra); + return $inputStringArray; } function echoInteger($inputInteger) { - return new SOAP_Value('outputInteger','int',(integer)$inputInteger); + return $inputInteger; } function echoIntegerArray($inputIntegerArray) { - $ra = array(); - if ($inputIntegerArray) { - foreach ($inputIntegerArray as $i) { - $ra[] = new SOAP_Value('item','int',$i); - } - } - return new SOAP_Value('outputIntArray',NULL,$ra); + return $inputIntegerArray; } function echoFloat($inputFloat) { - return new SOAP_Value('outputFloat','float',(FLOAT)$inputFloat); + return $inputFloat; } function echoFloatArray($inputFloatArray) { - $ra = array(); - if ($inputFloatArray) { - foreach($inputFloatArray as $float) { - $ra[] = new SOAP_Value('item','float',(FLOAT)$float); - } - } - return new SOAP_Value('outputFloatArray',NULL,$ra); + return $inputFloatArray; } function echoStruct($inputStruct) { - return new SOAP_Value('return','{http://soapinterop.org/xsd}SOAPStruct', - array( - new SOAP_Value('varInt','int',$inputStruct['varInt']), - new SOAP_Value('varFloat','float',$inputStruct['varFloat']), - new SOAP_Value('varString','string',$inputStruct['varString']) - )); + return $inputStruct; } function echoStructArray($inputStructArray) { - $ra = array(); - if ($inputStructArray) { - foreach($inputStructArray as $struct) { - $ra[] = new SOAP_Value('item','{http://soapinterop.org/xsd}SOAPStruct', - array( - new SOAP_Value('varInt','int',$struct['varInt']), - new SOAP_Value('varFloat','float',$struct['varFloat']), - new SOAP_Value('varString','string',$struct['varString']) - )); - } - } - return $ra; + return $inputStructArray; } function echoVoid() { - return NULL; + return NULL; } function echoBase64($b_encoded) { - return new SOAP_Value('return','base64Binary',base64_encode(base64_decode($b_encoded))); + return $b_encoded; } function echoDate($timeInstant) { - $dt = new SOAP_Type_dateTime($timeInstant); - if ($dt->toUnixtime() != -1) { - $value = $dt->toSOAP(); - return new SOAP_Value('return','dateTime',$value); - } else { - return new SOAP_Fault("Value $timeInstant is not a dateTime value"); - } + return $timeInstant; } function echoHexBinary($hb) { - return new SOAP_Value('return','hexBinary',bin2hex(hex2bin($hb))); + return $hb; } function echoDecimal($dec) { - return new SOAP_Value('return','decimal',(FLOAT)$dec); + return $dec; } function echoBoolean($boolean) { - return new SOAP_Value('return','boolean',$boolean); + return $boolean; } - + function echoMimeAttachment($stuff) { return new SOAP_Attachment('return','application/octet-stream',NULL,$stuff); } } -$base = new SOAP_Interop_Base(); -$server->addObjectMap($base); +$server = new SoapServer("http://test-uri"); +$server->bind("http://".$_SERVER['SERVER_NAME'].dirname($_SERVER['PHP_SELF'])."/interop.wsdl.php"); +$server->setClass("SOAP_Interop_Base"); +$server->handle(); ?> \ No newline at end of file diff --git a/ext/soap/interop/server_round2_groupB.php b/ext/soap/interop/server_round2_groupB.php index fa5856a26e..dc36aa5027 100644 --- a/ext/soap/interop/server_round2_groupB.php +++ b/ext/soap/interop/server_round2_groupB.php @@ -19,69 +19,52 @@ // // $Id$ // -require_once 'SOAP/Server.php'; class SOAP_Interop_GroupB { var $method_namespace = 'http://soapinterop.org/'; var $dispatch_map = array(); - + function SOAP_Interop_GroupB() { - $this->dispatch_map['echoStructAsSimpleTypes'] = - array('in' => array('inputStruct' => 'SOAPStruct'), - 'out' => array('outputString' => 'string', 'outputInteger' => 'int', 'outputFloat' => 'float') - ); - -# $server->addToMap('echoSimpleTypesAsStruct', -# array('outputString' => 'string', 'outputInteger' => 'int', 'outputFloat' => 'float'), -# array('return' => 'struct')); -# $server->addToMap('echoNestedStruct', array(), array()); -# $server->addToMap('echo2DStringArray', array(), array()); -# $server->addToMap('echoNestedArray', array(), array()); + $this->dispatch_map['echoStructAsSimpleTypes'] = + array('in' => array('inputStruct' => 'SOAPStruct'), + 'out' => array('outputString' => 'string', 'outputInteger' => 'int', 'outputFloat' => 'float') + ); + } + function echoStructAsSimpleTypes ($struct) { - # convert a SOAPStruct to an array - $vals = array_values($struct); - return array( - new SOAP_Value('outputString','string',$struct['varString']), - new SOAP_Value('outputInteger','int',$struct['varInt']), - new SOAP_Value('outputFloat','float',$struct['varFloat']) - ); - return array_values($struct); + return array('outputString' => $struct->varString, + 'outputInteger' => $struct->varInt, + 'outputFloat' => $struct->varFloat); } function echoSimpleTypesAsStruct($string, $int, $float) { - # convert a input into struct - $ret = new SOAP_Value('return','{http://soapinterop.org/xsd}SOAPStruct', - array( #push struct elements into one soap value - new SOAP_Value('varString','string',$string), - new SOAP_Value('varInt','int',(int)$int), - new SOAP_Value('varFloat','float',(FLOAT)$float) - ) - ); - return $ret; + return (object)array("varString" => $string, + "varInt" => $int, + "varFloat" => $float); } function echoNestedStruct($struct) { - return $struct; + return $struct; } function echo2DStringArray($ary) { - $ret = new SOAP_Value('return','Array',$ary); - $ret->options['flatten'] = TRUE; - return $ret; +// $ret->options['flatten'] = TRUE; + return $ary; } function echoNestedArray($ary) { - return $ary; + return $ary; } } -$groupb = new SOAP_Interop_GroupB(); -$server->addObjectMap($groupb); - +$server = new SoapServer("http://test-uri"); +$server->bind("http://".$_SERVER['SERVER_NAME'].dirname($_SERVER['PHP_SELF'])."/interopB.wsdl.php"); +$server->setClass("SOAP_Interop_GroupB"); +$server->handle(); ?> \ No newline at end of file diff --git a/ext/soap/interop/server_round2_groupC.php b/ext/soap/interop/server_round2_groupC.php index b323f9ba06..0c5492cda8 100644 --- a/ext/soap/interop/server_round2_groupC.php +++ b/ext/soap/interop/server_round2_groupC.php @@ -18,12 +18,10 @@ // // $Id$ // -require_once 'SOAP/Server.php'; -require_once 'SOAP/Value.php'; class SOAP_Interop_GroupC { var $method_namespace = 'http://soapinterop.org/echoheader/'; - + function echoMeStringRequest($string) { return new SOAP_Value('{'.$this->method_namespace.'}echoMeStringResponse','string',$string); @@ -35,7 +33,7 @@ class SOAP_Interop_GroupC { } } -$groupc = new SOAP_Interop_GroupC(); -$server->addObjectMap($groupc); - +$server = new SoapServer("http://test-uri"); +$server->setClass("SOAP_Interop_GroupC"); +$server->handle(); ?> \ No newline at end of file diff --git a/ext/soap/interop/server_round2_test.php b/ext/soap/interop/server_round2_test.php deleted file mode 100644 index 3c050f7a1b..0000000000 --- a/ext/soap/interop/server_round2_test.php +++ /dev/null @@ -1,258 +0,0 @@ - Port to PEAR and more | -// +----------------------------------------------------------------------+ -// -// $Id$ -// - -require_once 'SOAP/Server.php'; - -$server = new SOAP_Server; - -require_once 'server_round2_base.php'; -require_once 'server_round2_groupB.php'; -require_once 'server_round2_groupC.php'; - -$test = ' - - - - -hello world - - - - - -'; - -$test = ' - - - - - -arg - -34 - -325.325 - - - - - - - -'; - -$test = ' - - - - - - - - - -'; -$test = ' - - - - - -'; - -$test = ' - - - -1 -234324324 -2 - - - -'; - -#$test = " -# -# -#1 -#2 -#wilma -# -# -# -# -# -# -# -# -#"; - -#$test = " -1 -1 lean on into the groove y'all 1073741824 -42.24 pocketSOAP rocks!<g> "; - -#$test = " 5 Opps, should never see me "; -#$test = " 5 Opps, should never see me "; -#$test = " 42 Orbital -42.42 "; - -// white mesa failures -/*$test = 'White Mesa Test Header String.'; -*/ -/* -$test = 'White Mesa Test Header String.'; -*/ -//$test = " "; - -$test = ' - - - - - - -row0col0 -row0col1 -row0col2 -row1col0 -row1col1 -row1col2 - -'; - -$_SERVER['REQUEST_METHOD'] = "POST"; -$_SERVER['CONTENT_TYPE'] = 'multipart/related; type=text/xml; boundary="=_d624611fe466a88d956a205651c74fdb"'; - -$test = '--=_d624611fe466a88d956a205651c74fdb -Content-Type: text/xml; charset="UTF-8" -Content-Transfer-Encoding: base64 - -PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCg0KPFNPQVAtRU5WOkVudmVs -b3BlICB4bWxuczpTT0FQLUVOVj0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvc29hcC9lbnZl -bG9wZS8iDQogIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiDQog -IHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiDQog -IHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5n -LyINCiAgU09BUC1FTlY6ZW5jb2RpbmdTdHlsZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcv -c29hcC9lbmNvZGluZy8iPg0KPFNPQVAtRU5WOkJvZHk+DQoNCjxlY2hvTWltZUF0dGFjaG1lbnQ+ -DQo8dGVzdCBocmVmPSJjaWQ6ZTZiOTg0M2JiYzUxY2JiMDAzOTk0MGVmN2VlNzY2MDMiLz48L2Vj -aG9NaW1lQXR0YWNobWVudD4NCjwvU09BUC1FTlY6Qm9keT4NCjwvU09BUC1FTlY6RW52ZWxvcGU+ -DQo= ---=_d624611fe466a88d956a205651c74fdb -Content-Disposition: attachment.php -Content-Type: text/plain -Content-Transfer-Encoding: base64 -Content-ID: - -PD9waHANCnJlcXVpcmVfb25jZSgiU09BUC9DbGllbnQucGhwIik7DQpyZXF1aXJlX29uY2UoIlNP -QVAvdGVzdC90ZXN0LnV0aWxpdHkucGhwIik7DQpyZXF1aXJlX29uY2UoIlNPQVAvVmFsdWUucGhw -Iik7DQokc29hcF9iYXNlID0gbmV3IFNPQVBfQmFzZSgpOw0KDQokdiA9ICBuZXcgU09BUF9BdHRh -Y2htZW50KCd0ZXN0JywndGV4dC9wbGFpbicsJ2F0dGFjaG1lbnQucGhwJyk7DQokbWV0aG9kVmFs -dWUgPSBuZXcgU09BUF9WYWx1ZSgndGVzdGF0dGFjaCcsICdTdHJ1Y3QnLCBhcnJheSgkdikpOw0K -DQovLyBzZWUgdGhlIG1pbWUgYXJyYXkNCi8vJHZhbCA9ICRzb2FwX2Jhc2UtPl9tYWtlRW52ZWxv -cGUoJG1ldGhvZFZhbHVlKTsNCi8vcHJpbnRfcigkdmFsKTsNCg0KJGNsaWVudCA9IG5ldyBTT0FQ -X0NsaWVudCgnaHR0cDovL2xvY2FsaG9zdC9zb2FwX2ludGVyb3Avc2VydmVyX3JvdW5kMi5waHAn -KTsNCiRyZXNwID0gJGNsaWVudC0+Y2FsbCgnZWNob01pbWVBdHRhY2htZW50JyxhcnJheSgkdikp -Ow0KcHJpbnRfcigkcmVzcCk7DQpwcmludCAkY2xpZW50LT53aXJlOw0KPz4= ---=_d624611fe466a88d956a205651c74fdb--'; - -$_SERVER['CONTENT_TYPE'] = 'multipart/related; type=text/xml; boundary="=_a2cbb051424cc43e72d3c8c8d0b8f70e"'; -$test='--=_a2cbb051424cc43e72d3c8c8d0b8f70e -Content-Type: text/xml; charset="UTF-8" - - - - - - - - - - - ---=_a2cbb051424cc43e72d3c8c8d0b8f70e -Content-Disposition: attachment.php -Content-Type: text/plain -Content-Transfer-Encoding: base64 -Content-ID: - -PD9waHANCnJlcXVpcmVfb25jZSgiU09BUC9DbGllbnQucGhwIik7DQpyZXF1aXJlX29uY2UoIlNP -QVAvdGVzdC90ZXN0LnV0aWxpdHkucGhwIik7DQpyZXF1aXJlX29uY2UoIlNPQVAvVmFsdWUucGhw -Iik7DQokc29hcF9iYXNlID0gbmV3IFNPQVBfQmFzZSgpOw0KDQokdiA9ICBuZXcgU09BUF9BdHRh -Y2htZW50KCd0ZXN0JywndGV4dC9wbGFpbicsJ2F0dGFjaG1lbnQucGhwJyk7DQokbWV0aG9kVmFs -dWUgPSBuZXcgU09BUF9WYWx1ZSgndGVzdGF0dGFjaCcsICdTdHJ1Y3QnLCBhcnJheSgkdikpOw0K -DQovLyBzZWUgdGhlIG1pbWUgYXJyYXkNCi8vJHZhbCA9ICRzb2FwX2Jhc2UtPl9tYWtlRW52ZWxv -cGUoJG1ldGhvZFZhbHVlKTsNCi8vcHJpbnRfcigkdmFsKTsNCg0KJGNsaWVudCA9IG5ldyBTT0FQ -X0NsaWVudCgnaHR0cDovL2xvY2FsaG9zdC9zb2FwX2ludGVyb3Avc2VydmVyX3JvdW5kMi5waHAn -KTsNCiRyZXNwID0gJGNsaWVudC0+Y2FsbCgnZWNob01pbWVBdHRhY2htZW50JyxhcnJheSgkdikp -Ow0KI3ByaW50X3IoJHJlc3ApOw0KcHJpbnQgJGNsaWVudC0+d2lyZTsNCj8+ ---=_a2cbb051424cc43e72d3c8c8d0b8f70e-- -'; -$server->service($test, '',TRUE); -print $server->response; -?> \ No newline at end of file diff --git a/ext/soap/interop/test.utility.php b/ext/soap/interop/test.utility.php index 9af61c22fb..bfe176dc93 100644 --- a/ext/soap/interop/test.utility.php +++ b/ext/soap/interop/test.utility.php @@ -1,6 +1,4 @@ compare($e1, $e2) == 0; +// $dt = new SOAP_Type_dateTime(); +// $ok = $dt->compare($e1, $e2) == 0; + $oj = false; } return $ok || $e1 == $e2 || strcasecmp(trim($e1), trim($e2)) == 0; } -function array_compare(&$ar1, &$ar2) -{ - if (gettype($ar1) != 'array' || gettype($ar2) != 'array') return FALSE; - # first a shallow diff - if (count($ar1) != count($ar2)) return FALSE; - $diff = array_diff($ar1, $ar2); - if (count($diff) == 0) return TRUE; +function array_compare(&$ar1, &$ar2) { + if (gettype($ar1) != 'array' || gettype($ar2) != 'array') return FALSE; + if (count($ar1) != count($ar2)) return FALSE; + foreach ($ar1 as $k => $v) { + if (!array_key_exists($k,$ar2)) return FALSE; + if (!compare($v,$ar2[$k])) return FALSE; + } + return TRUE; +} - # diff failed, do a full check of the array - foreach ($ar1 as $k => $v) { - #print "comparing $v == $ar2[$k]\n"; - if (gettype($v) == "array") { - if (!array_compare($v, $ar2[$k])) return FALSE; - } else { - if (!string_compare($v, $ar2[$k])) return FALSE; - } +function object_compare(&$obj1, &$obj2) { + if (gettype($obj1) != 'object' || gettype($obj2) != 'object') return FALSE; +// if (class_name(obj1) != class_name(obj2)) return FALSE; + $ar1 = (array)$obj1; + $ar2 = (array)$obj2; + return array_compare($ar1,$ar2); +} + +function compare(&$x,&$y) { + $ok = 0; + $x_type = gettype($x); + $y_type = gettype($y); + if ($x_type == $y_type) { + if ($x_type == "array") { + $ok = array_compare($x, $y); + } else if ($x_type == "object") { + $ok = object_compare($x, $y); + } else if ($x_type == "double") { + $ok = number_compare($x, $y); +// } else if ($x_type == 'boolean') { +// $ok = boolean_compare($x, $y); + } else { + $ok = ($x == $y); +// $ok = string_compare($expect, $result); } - return TRUE; + } + return $ok; } @@ -77,5 +96,12 @@ function parseMessage($msg) return $v; } +function var_dump_str($var) { + ob_start(); + var_dump($var); + $res = ob_get_contents(); + ob_end_clean(); + return $res; +} ?> \ No newline at end of file diff --git a/ext/soap/interop/testclient.php b/ext/soap/interop/testclient.php deleted file mode 100644 index b70c628ee5..0000000000 --- a/ext/soap/interop/testclient.php +++ /dev/null @@ -1,17 +0,0 @@ - -debug_flag = TRUE; -print_r($soapc->call("testMethod",array("txt" => $txt))); -print "
Debug: "; -print $soapc->wire; -print "

"; -unset($soapc); - -?> - \ No newline at end of file diff --git a/ext/soap/interop/testserver.php b/ext/soap/interop/testserver.php deleted file mode 100644 index 03973c8863..0000000000 --- a/ext/soap/interop/testserver.php +++ /dev/null @@ -1,17 +0,0 @@ -addToMap("testMethod",array("string"),array("string")); -$server->service($HTTP_RAW_POST_DATA); -echo ""; -?> \ No newline at end of file diff --git a/ext/soap/package.xml b/ext/soap/package.xml index 965670fcc8..5d872e6cb4 100644 --- a/ext/soap/package.xml +++ b/ext/soap/package.xml @@ -21,6 +21,12 @@ shane@caraveo.com lead + + dmitry + Dmitry Stogov + dmitry@zend.com + lead + PHP @@ -56,4 +62,3 @@ - diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 3b4909f3d6..0f312e4a81 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -5,10 +5,10 @@ encode defaultEncoding[] = { {{UNKNOWN_TYPE, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert}, - {{IS_NULL, "null", "null", NULL}, to_zval_null, to_xml_null}, + {{IS_NULL, "nil", XSI_NAMESPACE, NULL}, to_zval_null, to_xml_null}, {{IS_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string}, {{IS_LONG, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{IS_DOUBLE, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_string}, + {{IS_DOUBLE, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double}, {{IS_BOOL, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool}, {{IS_CONSTANT, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string}, {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map}, @@ -17,9 +17,9 @@ encode defaultEncoding[] = { {{XSD_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string}, {{XSD_BOOLEAN, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool}, - {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_string}, - {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_string}, - {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_string}, + {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string}, + {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double}, + {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double}, {{XSD_DATETIME, XSD_DATETIME_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_datetime}, {{XSD_TIME, XSD_TIME_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_time}, {{XSD_DATE, XSD_DATE_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_date}, @@ -32,8 +32,16 @@ encode defaultEncoding[] = { {{XSD_BASE64BINARY, XSD_BASE64BINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_stringl}, {{XSD_LONG, XSD_LONG_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_INT, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_string}, - {{XSD_SHORT, XSD_SHORT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_string}, + {{XSD_INT, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_SHORT, XSD_SHORT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_BYTE, XSD_BYTE_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_NONPOSITIVEINTEGER, XSD_NONPOSITIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_POSITIVEINTEGER, XSD_POSITIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_NONNEGATIVEINTEGER, XSD_NONNEGATIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_NEGATIVEINTEGER, XSD_NEGATIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_UNSIGNEDBYTE, XSD_UNSIGNEDBYTE_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_UNSIGNEDSHORT, XSD_UNSIGNEDSHORT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_UNSIGNEDINT, XSD_UNSIGNEDINT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, {{APACHE_MAP, APACHE_MAP_STRING, APACHE_NAMESPACE, NULL}, to_zval_map, to_xml_map}, @@ -43,12 +51,12 @@ encode defaultEncoding[] = { /* support some of the 1999 data types */ {{XSD_STRING, XSD_STRING_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_string, to_xml_string}, {{XSD_BOOLEAN, XSD_BOOLEAN_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_bool, to_xml_bool}, - {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_string}, - {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_string}, - {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_string}, + {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_string, to_xml_string}, + {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_double}, + {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_double}, {{XSD_LONG, XSD_LONG_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_INT, XSD_INT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_string}, - {{XSD_SHORT, XSD_SHORT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_string}, + {{XSD_INT, XSD_INT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long}, + {{XSD_SHORT, XSD_SHORT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long}, {{XSD_1999_TIMEINSTANT, XSD_1999_TIMEINSTANT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_string, to_xml_string}, {{END_KNOWN_TYPES, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert} @@ -63,9 +71,6 @@ encode defaultEncoding[] = { #define XSD_QNAME_STRING "QName" #define XSD_NOTATION 120 #define XSD_NOTATION_STRING "NOTATION" -*/ - -/* #define XSD_NORMALIZEDSTRING 121 #define XSD_NORMALIZEDSTRING_STRING "normalizedString" #define XSD_TOKEN 122 @@ -88,24 +93,8 @@ encode defaultEncoding[] = { #define XSD_ENTITY_STRING "ENTITY" #define XSD_ENTITYS 129 #define XSD_ENTITYS_STRING "ENTITYS" -#define XSD_INTEGER 130 -#define XSD_INTEGER_STRING "integer" -#define XSD_NONPOSITIVEINTEGER 131 -#define XSD_NONPOSITIVEINTEGER_STRING "nonPositiveInteger" -#define XSD_NEGATIVEINTEGER 132 -#define XSD_NEGATIVEINTEGER_STRING "negativeInteger" -#define XSD_NONNEGATIVEINTEGER 137 -#define XSD_NONNEGATIVEINTEGER_STRING "nonNegativeInteger" #define XSD_UNSIGNEDLONG 138 #define XSD_UNSIGNEDLONG_STRING "unsignedLong" -#define XSD_UNSIGNEDINT 139 -#define XSD_UNSIGNEDINT_STRING "unsignedInt" -#define XSD_UNSIGNEDSHORT 140 -#define XSD_UNSIGNEDSHORT_STRING "unsignedShort" -#define XSD_UNSIGNEDBYTE 141 -#define XSD_UNSIGNEDBYTE_STRING "unsignedByte" -#define XSD_POSITIVEINTEGER 142 -#define XSD_POSITIVEINTEGER_STRING "positiveInteger" */ }; @@ -126,7 +115,6 @@ xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style) zval *master_to_zval(encodePtr encode, xmlNodePtr data) { zval *ret; - data = check_and_resolve_href(data); if(encode->to_zval_before) data = encode->to_zval_before(encode->details, data, 0); @@ -267,9 +255,11 @@ zval *to_zval_string(encodeType type, xmlNodePtr data) zval *ret; MAKE_STD_ZVAL(ret); FIND_XML_NULL(data, ret); - - if(data && data->children) + if(data && data->children && data->children->content) { ZVAL_STRING(ret, data->children->content, 1); + } else { + ZVAL_EMPTY_STRING(ret); + } return ret; } @@ -278,9 +268,11 @@ zval *to_zval_stringl(encodeType type, xmlNodePtr data) zval *ret; MAKE_STD_ZVAL(ret); FIND_XML_NULL(data, ret); - - if(data && data->children) + if(data && data->children && data->children->content) { ZVAL_STRINGL(ret, data->children->content, xmlStrlen(data->children->content), 1); + } else { + ZVAL_EMPTY_STRING(ret) + } return ret; } @@ -292,16 +284,23 @@ xmlNodePtr to_xml_string(encodeType type, zval *data, int style) TSRMLS_FETCH(); ret = xmlNewNode(NULL, "BOGUS"); - FIND_ZVAL_NULL(data, ret); - - convert_to_string(data); - str = php_escape_html_entities(Z_STRVAL_P(data), Z_STRLEN_P(data), &new_len, 0, 0, NULL TSRMLS_CC); + FIND_ZVAL_NULL(data, ret, style); + + if (Z_TYPE_P(data) == IS_STRING) { + str = php_escape_html_entities(Z_STRVAL_P(data), Z_STRLEN_P(data), &new_len, 0, 0, NULL TSRMLS_CC); + } else { + zval tmp = *data; + zval_copy_ctor(&tmp); + convert_to_string(&tmp); + str = php_escape_html_entities(Z_STRVAL(tmp), Z_STRLEN(tmp), &new_len, 0, 0, NULL TSRMLS_CC); + zval_dtor(&tmp); + } pstr = malloc(new_len + 1); memcpy(pstr, str, new_len); pstr[new_len] = '\0'; efree(str); - + xmlNodeSetContentLen(ret, pstr, new_len); if(style == SOAP_ENCODED) @@ -314,10 +313,17 @@ xmlNodePtr to_xml_stringl(encodeType type, zval *data, int style) xmlNodePtr ret; ret = xmlNewNode(NULL, "BOGUS"); - FIND_ZVAL_NULL(data, ret); - - convert_to_string(data); - xmlNodeSetContentLen(ret, estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data)), Z_STRLEN_P(data)); + FIND_ZVAL_NULL(data, ret, style); + + if (Z_TYPE_P(data) == IS_STRING) { + xmlNodeSetContentLen(ret, Z_STRVAL_P(data), Z_STRLEN_P(data)); + } else { + zval tmp = *data; + zval_copy_ctor(&tmp); + convert_to_string(&tmp); + xmlNodeSetContentLen(ret, Z_STRVAL(tmp), Z_STRLEN(tmp)); + zval_dtor(&tmp); + } if(style == SOAP_ENCODED) set_ns_and_type(ret, type); @@ -330,7 +336,11 @@ zval *to_zval_double(encodeType type, xmlNodePtr data) MAKE_STD_ZVAL(ret); FIND_XML_NULL(data, ret); - ZVAL_DOUBLE(ret, atof(data->children->content)); + if (data && data->children && data->children->content) { + ZVAL_DOUBLE(ret, atof(data->children->content)); + } else { + ZVAL_NULL(ret); + } return ret; } @@ -340,21 +350,53 @@ zval *to_zval_long(encodeType type, xmlNodePtr data) MAKE_STD_ZVAL(ret); FIND_XML_NULL(data, ret); - ZVAL_LONG(ret, atol(data->children->content)); + if (data && data->children && data->children->content) { + ZVAL_LONG(ret, atol(data->children->content)); + } else { + ZVAL_NULL(ret); + } return ret; } xmlNodePtr to_xml_long(encodeType type, zval *data, int style) { xmlNodePtr ret; + zval tmp; ret = xmlNewNode(NULL, "BOGUS"); - FIND_ZVAL_NULL(data, ret); + FIND_ZVAL_NULL(data, ret, style); + + tmp = *data; + zval_copy_ctor(&tmp); + if (Z_TYPE(tmp) != IS_LONG) { + convert_to_long(&tmp); + } + convert_to_string(&tmp); + xmlNodeSetContentLen(ret, Z_STRVAL(tmp), Z_STRLEN(tmp)); + zval_dtor(&tmp); + + if(style == SOAP_ENCODED) + set_ns_and_type(ret, type); + return ret; +} + +xmlNodePtr to_xml_double(encodeType type, zval *data, int style) +{ + xmlNodePtr ret; + zval tmp; + + ret = xmlNewNode(NULL, "BOGUS"); + FIND_ZVAL_NULL(data, ret, style); + + tmp = *data; + zval_copy_ctor(&tmp); + if (Z_TYPE(tmp) != IS_DOUBLE) { + convert_to_double(&tmp); + } + convert_to_string(&tmp); + xmlNodeSetContentLen(ret, Z_STRVAL(tmp), Z_STRLEN(tmp)); + zval_dtor(&tmp); - convert_to_long(data); - convert_to_string(data); - xmlNodeSetContentLen(ret, Z_STRVAL_P(data), Z_STRLEN_P(data)); - if(style == SOAP_ENCODED) set_ns_and_type(ret, type); return ret; @@ -366,15 +408,19 @@ zval *to_zval_bool(encodeType type, xmlNodePtr data) MAKE_STD_ZVAL(ret); FIND_XML_NULL(data, ret); - if(stricmp(data->children->content,"true") == 0 || - stricmp(data->children->content,"t") == 0 || - strcmp(data->children->content,"1") == 0) - { - ZVAL_BOOL(ret, 1); - } - else - { - ZVAL_BOOL(ret, 0); + if (data && data->children && data->children->content) { + if(stricmp(data->children->content,"true") == 0 || + stricmp(data->children->content,"t") == 0 || + strcmp(data->children->content,"1") == 0) + { + ZVAL_BOOL(ret, 1); + } + else + { + ZVAL_BOOL(ret, 0); + } + } else { + ZVAL_NULL(ret); } return ret; } @@ -382,16 +428,27 @@ zval *to_zval_bool(encodeType type, xmlNodePtr data) xmlNodePtr to_xml_bool(encodeType type, zval *data, int style) { xmlNodePtr ret; + zval tmp; ret = xmlNewNode(NULL, "BOGUS"); - FIND_ZVAL_NULL(data, ret); + FIND_ZVAL_NULL(data, ret, style); + + if (Z_TYPE_P(data) != IS_BOOL) { + tmp = *data; + zval_copy_ctor(&tmp); + convert_to_boolean(data); + data = &tmp; + } - convert_to_boolean(data); if(data->value.lval == 1) xmlNodeSetContent(ret, "1"); else xmlNodeSetContent(ret, "0"); + if (data == &tmp) { + zval_dtor(&tmp); + } + if(style == SOAP_ENCODED) set_ns_and_type(ret, type); return ret; @@ -411,10 +468,10 @@ xmlNodePtr to_xml_null(encodeType type, zval *data, int style) xmlNodePtr ret; ret = xmlNewNode(NULL, "BOGUS"); - FIND_ZVAL_NULL(data, ret); - + FIND_ZVAL_NULL(data, ret, style); + if(style == SOAP_ENCODED) - xmlSetProp(ret, "xsi:null", "1"); + xmlSetProp(ret, "xsi:nil", "1"); return ret; } @@ -423,28 +480,47 @@ zval *to_zval_object(encodeType type, xmlNodePtr data) { zval *ret; xmlNodePtr trav; - encodePtr enc; + sdlPtr sdl; + sdlTypePtr sdlType = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(ret); FIND_XML_NULL(data, ret); + sdl = SOAP_GLOBAL(sdl); + if (sdl && type.sdl_type) { + sdlType = type.sdl_type; + } + object_init(ret); trav = data->children; - enc = get_conversion(UNKNOWN_TYPE); - do - { - if(trav->type == XML_ELEMENT_NODE) - { + while (trav != NULL) { + if(trav->type == XML_ELEMENT_NODE) { + sdlTypePtr *element; + encodePtr enc = NULL; zval *tmpVal; + xmlAttrPtr typeAttr = get_attribute(trav->properties,"type"); + if (typeAttr != NULL && typeAttr->children && typeAttr->children->content) { + enc = get_encoder_from_prefix(sdl, trav, typeAttr->children->content); + } + if (enc == NULL && sdlType != NULL && sdlType->elements != NULL && trav->name != NULL && + zend_hash_find(sdlType->elements, (char*)trav->name, strlen(trav->name)+1,(void **)&element) == SUCCESS) { + enc = (*element)->encode; + } + if (enc == NULL) { + enc = get_conversion(UNKNOWN_TYPE); + } + tmpVal = master_to_zval(enc, trav); +#ifdef ZEND_ENGINE_2 + tmpVal->refcount--; +#endif add_property_zval(ret, (char *)trav->name, tmpVal); } + trav = trav->next; } - while(trav = trav->next); - return ret; } @@ -456,18 +532,21 @@ xmlNodePtr to_xml_object(encodeType type, zval *data, int style) TSRMLS_FETCH(); /* Special handling of class SoapVar */ - if(data && Z_TYPE_P(data) == IS_OBJECT && !strcmp(Z_OBJCE_P(data)->name, soap_var_class_entry.name)) + if(data && Z_TYPE_P(data) == IS_OBJECT && Z_OBJCE_P(data) == soap_var_class_entry) { zval **ztype, **zdata, **zns, **zstype, **zname, **znamens; encodePtr enc; if(zend_hash_find(Z_OBJPROP_P(data), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) php_error(E_ERROR, "error encoding SoapVar"); - if(zend_hash_find(Z_OBJPROP_P(data), "enc_value", sizeof("enc_value"), (void **)&zdata) == FAILURE) - php_error(E_ERROR, "error encoding SoapVar"); enc = get_conversion(Z_LVAL_P(*ztype)); - xmlParam = master_to_xml(enc, *zdata, style); + + if(zend_hash_find(Z_OBJPROP_P(data), "enc_value", sizeof("enc_value"), (void **)&zdata) == FAILURE) { + xmlParam = master_to_xml(enc, NULL, style); + } else { + xmlParam = master_to_xml(enc, *zdata, style); + } if(zend_hash_find(Z_OBJPROP_P(data), "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) { @@ -494,7 +573,7 @@ xmlNodePtr to_xml_object(encodeType type, zval *data, int style) else { xmlParam = xmlNewNode(NULL, "BOGUS"); - FIND_ZVAL_NULL(data, xmlParam); + FIND_ZVAL_NULL(data, xmlParam, style); if(Z_TYPE_P(data) == IS_OBJECT) { @@ -520,7 +599,7 @@ xmlNodePtr to_xml_object(encodeType type, zval *data, int style) zend_hash_move_forward(prop); } } - + if(style == SOAP_ENCODED) set_ns_and_type(xmlParam, type); } @@ -535,13 +614,10 @@ xmlNodePtr guess_array_map(encodeType type, zval *data, int style) if(data && Z_TYPE_P(data) == IS_ARRAY) { - if(zend_hash_num_elements(Z_ARRVAL_P(data)) > 0) - { - if(is_map(data)) - enc = get_conversion(APACHE_MAP); - else - enc = get_conversion(SOAP_ENC_ARRAY); - } + if(is_map(data)) + enc = get_conversion(APACHE_MAP); + else + enc = get_conversion(SOAP_ENC_ARRAY); } if(!enc) enc = get_conversion(IS_NULL); @@ -558,13 +634,13 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style) xmlParam = xmlNewNode(NULL,"BOGUS"); - FIND_ZVAL_NULL(data, xmlParam); + FIND_ZVAL_NULL(data, xmlParam, style); if(Z_TYPE_P(data) == IS_ARRAY) { i = zend_hash_num_elements(Z_ARRVAL_P(data)); - if(style == SOAP_ENCODED) + if(i > 0 && style == SOAP_ENCODED) { get_array_type(data, &array_type TSRMLS_CC); smart_str_append(&array_type_and_size, &array_type); @@ -604,31 +680,157 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style) return xmlParam; } +static xmlNodePtr add_zval_array_elements(zval* ret, + sdlPtr sdl, + encodePtr enc, + int dimension, + int* dims, + xmlNodePtr data) +{ + int i; + if (dimension == 1) { + for (i = 0; i < dims[0]; i++) { + zval *tmpVal; + encodePtr typeEnc = NULL; + xmlAttrPtr type = get_attribute(data->properties,"type"); + if (type != NULL && type->children && type->children->content) { + typeEnc = get_encoder_from_prefix(sdl, data, type->children->content); + } + if (typeEnc) { + tmpVal = master_to_zval(typeEnc, data); + } else { + tmpVal = master_to_zval(enc, data); + } + zend_hash_next_index_insert(Z_ARRVAL_P(ret), &tmpVal, sizeof(zval*), NULL); + if (data != NULL) { + do { + data = data->next; + } while (data != NULL && data->type != XML_ELEMENT_NODE); + } + } + } else { + for (i = 0; i < dims[0]; i++) { + zval *tmpVal; + MAKE_STD_ZVAL(tmpVal); + array_init(tmpVal); + data = add_zval_array_elements(tmpVal,sdl,enc,dimension-1,dims+1,data); + zend_hash_next_index_insert(Z_ARRVAL_P(ret), &tmpVal, sizeof(zval*), NULL); + } + } + return data; +} + zval *to_zval_array(encodeType type, xmlNodePtr data) { zval *ret; xmlNodePtr trav; - encodePtr enc; + encodePtr enc = NULL; + int dimension = 1; + int* dims = NULL; + xmlAttrPtr arrayTypeAttr; + sdlPtr sdl; + TSRMLS_FETCH(); MAKE_STD_ZVAL(ret); FIND_XML_NULL(data, ret); + sdl = SOAP_GLOBAL(sdl); + + if (data && + (arrayTypeAttr = get_attribute(data->properties,"arrayType")) && + arrayTypeAttr->children && + arrayTypeAttr->children->content) { + char *type, *end, *ns; + xmlNsPtr nsptr; + + parse_namespace(arrayTypeAttr->children->content, &type, &ns); + nsptr = xmlSearchNs(arrayTypeAttr->doc, arrayTypeAttr->parent, ns); + + end = strrchr(type,'['); + if (end) { + int i; + char *tmp = end+1; + *end = '\0'; + end++; + while (*tmp != ']' && *tmp != '\0') { + if (*tmp == ',') { + dimension++; + } + tmp++; + } + dims = emalloc(sizeof(int)*dimension); + memset(dims,0,sizeof(int)*dimension); + tmp = end; i = 0; + while (*tmp != ']' && *tmp != '\0') { + if (*tmp >= '0' && *tmp <= '9') { + dims[i] = (dims[i]*10)+(*tmp-'0'); + } else if (*tmp == ',') { + i++; + } + tmp++; + } + } + if(nsptr != NULL) { + enc = get_encoder(SOAP_GLOBAL(sdl), nsptr->href, type); + } + efree(type); + if (ns) efree(ns); + } + if (enc == NULL) { + enc = get_conversion(UNKNOWN_TYPE); + } array_init(ret); - trav = data->children; - - enc = get_conversion(UNKNOWN_TYPE); - while(trav) - { - if(trav->type == XML_ELEMENT_NODE) - { - zval *tmpVal; - tmpVal = master_to_zval(enc, trav); - zend_hash_next_index_insert(Z_ARRVAL_P(ret), &tmpVal, sizeof(zval *), NULL); + if (dims == NULL) { + trav = data->children; + while(trav) { + if(trav->type == XML_ELEMENT_NODE) { + zval *tmpVal; + encodePtr typeEnc = NULL; + xmlAttrPtr type = get_attribute(trav->properties,"type"); + if (type != NULL && type->children && type->children->content) { + typeEnc = get_encoder_from_prefix(sdl, trav, type->children->content); + } + if (typeEnc) { + tmpVal = master_to_zval(typeEnc, trav); + } else { + tmpVal = master_to_zval(enc, trav); + } + zend_hash_next_index_insert(Z_ARRVAL_P(ret), &tmpVal, sizeof(zval *), NULL); + } + trav = trav->next; + } + } else { + trav = data->children; + while (trav != NULL && trav->type != XML_ELEMENT_NODE) { + trav = trav->next; } - trav = trav->next; + add_zval_array_elements(ret, sdl, enc, dimension, dims, trav); + } +/* + if (data) { + if (dims == NULL && dimension <= 1) { + trav = data->children; + while(trav) { + if(trav->type == XML_ELEMENT_NODE) { + zval *tmpVal; + tmpVal = master_to_zval(enc, trav); + zend_hash_next_index_insert(Z_ARRVAL_P(ret), &tmpVal, sizeof(zval *), NULL); + } + trav = trav->next; + } + } else { + trav = data->children; + while (trav != NULL && trav->type != XML_ELEMENT_NODE) { + trav = trav->next; + } + add_zval_array_elements(ret, enc, dimension, dims, trav); + } + } +*/ + if (dims) { + efree(dims); } - return ret; } @@ -640,7 +842,7 @@ xmlNodePtr to_xml_map(encodeType type, zval *data, int style) TSRMLS_FETCH(); xmlParam = xmlNewNode(NULL, "BOGUS"); - FIND_ZVAL_NULL(data, xmlParam); + FIND_ZVAL_NULL(data, xmlParam, style); if(Z_TYPE_P(data) == IS_ARRAY) { @@ -709,33 +911,36 @@ zval *to_zval_map(encodeType type, xmlNodePtr data) MAKE_STD_ZVAL(ret); FIND_XML_NULL(data, ret); - array_init(ret); - trav = data->children; + if (data && data->children) { + array_init(ret); + trav = data->children; - enc = get_conversion(UNKNOWN_TYPE); - trav = data->children; - FOREACHNODE(trav, "item", item) - { - xmlKey = get_node(item->children, "key"); - if(!xmlKey) - php_error(E_ERROR, "Error encoding apache map, missing key"); + enc = get_conversion(UNKNOWN_TYPE); + trav = data->children; + FOREACHNODE(trav, "item", item) + { + xmlKey = get_node(item->children, "key"); + if(!xmlKey) + php_error(E_ERROR, "Error encoding apache map, missing key"); - xmlValue = get_node(item->children, "value"); - if(!xmlKey) - php_error(E_ERROR, "Error encoding apache map, missing value"); + xmlValue = get_node(item->children, "value"); + if(!xmlKey) + php_error(E_ERROR, "Error encoding apache map, missing value"); - key = master_to_zval(enc, xmlKey); - value = master_to_zval(enc, xmlValue); + key = master_to_zval(enc, xmlKey); + value = master_to_zval(enc, xmlValue); - if(Z_TYPE_P(key) == IS_STRING) - zend_hash_update(Z_ARRVAL_P(ret), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL); - else if(Z_TYPE_P(key) == IS_LONG) - zend_hash_index_update(Z_ARRVAL_P(ret), Z_LVAL_P(key), &value, sizeof(zval *), NULL); - else - php_error(E_ERROR, "Error encoding apache map, only Strings or Longs are allowd as keys"); + if(Z_TYPE_P(key) == IS_STRING) + zend_hash_update(Z_ARRVAL_P(ret), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL); + else if(Z_TYPE_P(key) == IS_LONG) + zend_hash_index_update(Z_ARRVAL_P(ret), Z_LVAL_P(key), &value, sizeof(zval *), NULL); + else + php_error(E_ERROR, "Error encoding apache map, only Strings or Longs are allowd as keys"); + } + ENDFOREACH(trav); + } else { + ZVAL_NULL(ret); } - ENDFOREACH(trav); - return ret; } @@ -760,14 +965,21 @@ zval *guess_zval_convert(encodeType type, xmlNodePtr data) data = check_and_resolve_href(data); - if(data == NULL || data->children == NULL) + if (data == NULL) { + enc = get_conversion(IS_NULL); + } else if (data->properties && get_attribute(data->properties, "nil")) { enc = get_conversion(IS_NULL); + } else { tmpattr = get_attribute(data->properties,"type"); if(tmpattr != NULL) { - enc = get_conversion_from_type(data, tmpattr->children->content); + if (tmpattr->children) { + enc = get_conversion_from_type(data, tmpattr->children->content); + } else { + enc = get_conversion_from_type(data, ""); + } /* if(enc == NULL) php_error(E_ERROR, "Error (Don't know how to encode/decode \"%s\")", tmpattr->children->content); @@ -786,15 +998,14 @@ zval *guess_zval_convert(encodeType type, xmlNodePtr data) { enc = get_conversion(XSD_STRING); trav = data->children; - do - { + while (trav != NULL) { if(trav->type == XML_ELEMENT_NODE) { enc = get_conversion(SOAP_ENC_OBJECT); break; } + trav = trav->next; } - while(trav = trav->next); } } } @@ -813,23 +1024,31 @@ xmlNodePtr to_xml_datetime_ex(encodeType type, zval *data, char *format, int sty xmlNodePtr xmlParam; xmlParam = xmlNewNode(NULL, "BOGUS"); - FIND_ZVAL_NULL(data, xmlParam); + FIND_ZVAL_NULL(data, xmlParam, style); - timestamp = Z_LVAL_P(data); + if (Z_TYPE_P(data) == IS_LONG) { + timestamp = Z_LVAL_P(data); + /*time(×tamp);*/ + ta = php_localtime_r(×tamp, &tmbuf); - time(×tamp); - ta = php_localtime_r(×tamp, &tmbuf); + buf = (char *) emalloc(buf_len); + while ((real_len = strftime(buf, buf_len, format, ta)) == buf_len || real_len == 0) + { + buf_len *= 2; + buf = (char *) erealloc(buf, buf_len); + if(!--max_reallocs) break; + } - buf = (char *) emalloc(buf_len); - while ((real_len = strftime(buf, buf_len, format, ta)) == buf_len || real_len == 0) - { - buf_len *= 2; - buf = (char *) erealloc(buf, buf_len); - if(!--max_reallocs) break; - } + xmlNodeSetContent(xmlParam, buf); + efree(buf); + } else if (Z_TYPE_P(data) == IS_STRING) { + buf = malloc(Z_STRLEN_P(data)+1); + strcpy(buf, Z_STRVAL_P(data)); - xmlNodeSetContent(xmlParam, buf); - efree(buf); + xmlNodeSetContentLen(xmlParam, buf, Z_STRLEN_P(data)); + } else { + xmlSetProp(xmlParam, "xsi:nil", "1"); + } if(style == SOAP_ENCODED) set_ns_and_type(xmlParam, type); @@ -966,20 +1185,20 @@ encodePtr get_conversion_ex(HashTable *encoding, int encode) return *enc; } -encodePtr get_conversion_from_href_type_ex(HashTable *encoding, char *type, int len) +encodePtr get_conversion_from_href_type_ex(HashTable *encoding, const char *type, int len) { encodePtr *enc = NULL; if(encoding == NULL) return NULL; - if(zend_hash_find(encoding, type, len + 1, (void **)&enc) == FAILURE) + if(zend_hash_find(encoding, (char*)type, len + 1, (void **)&enc) == FAILURE) return NULL; return (*enc); } -encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, char *type) +encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, const char *type) { encodePtr *enc = NULL; xmlNsPtr nsptr; @@ -1000,14 +1219,14 @@ encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, char if(zend_hash_find(encoding, nscat.c, nscat.len + 1, (void **)&enc) == FAILURE) { - if(zend_hash_find(encoding, type, strlen(type) + 1, (void **)&enc) == FAILURE) + if(zend_hash_find(encoding, (char*)type, strlen(type) + 1, (void **)&enc) == FAILURE) enc = NULL; } smart_str_free(&nscat); } else { - if(zend_hash_find(encoding, type, strlen(type) + 1, (void **)&enc) == FAILURE) + if(zend_hash_find(encoding, (char*)type, strlen(type) + 1, (void **)&enc) == FAILURE) enc = NULL; } @@ -1035,7 +1254,6 @@ void get_array_type(zval *array, smart_str *type TSRMLS_DC) { HashTable *ht = HASH_OF(array); int i, count, cur_type, prev_type, different; - char *name = NULL; zval **tmp; /* TSRMLS_FETCH();*/ @@ -1051,7 +1269,7 @@ void get_array_type(zval *array, smart_str *type TSRMLS_DC) { zend_hash_get_current_data(ht, (void **)&tmp); - if(Z_TYPE_PP(tmp) == IS_OBJECT && !strcmp(Z_OBJCE_PP(tmp)->name, soap_var_class_entry.name)) + if(Z_TYPE_PP(tmp) == IS_OBJECT && Z_OBJCE_PP(tmp) == soap_var_class_entry) { zval **ztype; @@ -1132,4 +1350,3 @@ void delete_encoder(void *encode) delete_mapping(t->details.map); free(t); } - diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index 4a9bfc72a5..cfe509613f 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -7,6 +7,8 @@ #define XSD_NAMESPACE "http://www.w3.org/2001/XMLSchema" #define XSD_NS_PREFIX "xsd" +#define XSI_NAMESPACE "http://www.w3.org/2001/XMLSchema-instance" +#define XSI_NS_PREFIX "xsi" #define XSD_STRING 101 #define XSD_STRING_STRING "string" #define XSD_BOOLEAN 103 @@ -173,6 +175,7 @@ zval *to_zval_null(encodeType type, xmlNodePtr data); zval *guess_zval_convert(encodeType type, xmlNodePtr data); xmlNodePtr to_xml_long(encodeType type, zval *data, int style); +xmlNodePtr to_xml_double(encodeType type, zval *data, int style); xmlNodePtr to_xml_bool(encodeType type, zval *data, int style); /* String encode */ @@ -214,8 +217,8 @@ smart_str *encode_new_ns(); void set_ns_and_type(xmlNodePtr node, encodeType type); void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type); encodePtr get_conversion_ex(HashTable *encoding, int encode); -encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, char *type); -encodePtr get_conversion_from_href_type_ex(HashTable *encoding, char *type, int len); +encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, const char *type); +encodePtr get_conversion_from_href_type_ex(HashTable *encoding, const char *type, int len); int is_map(zval *array); void get_array_type(zval *array, smart_str *out_type TSRMLS_DC); @@ -227,14 +230,14 @@ extern encode defaultEncoding[]; #define FIND_XML_NULL(xml,zval) \ { \ xmlAttrPtr null; \ - if(!xml || !xml->children) \ + if(!xml) \ { \ ZVAL_NULL(zval); \ return zval; \ } \ if(xml->properties) \ { \ - null = get_attribute(xml->properties, "null"); \ + null = get_attribute(xml->properties, "nil"); \ if(null) \ { \ ZVAL_NULL(zval); \ @@ -243,11 +246,13 @@ extern encode defaultEncoding[]; } \ } -#define FIND_ZVAL_NULL(zval, xml) \ +#define FIND_ZVAL_NULL(zval, xml, style) \ { \ - if(!zval) \ + if(!zval || Z_TYPE_P(zval) == IS_NULL) \ { \ - xmlSetProp(xml, "xsi:null", "1"); \ + if (style == SOAP_ENCODED) {\ + xmlSetProp(xml, "xsi:nil", "1"); \ + }\ return xml; \ } \ } diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 5f68e94e84..c32610e154 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -1,6 +1,10 @@ #include "php_soap.h" -void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, char *soapaction TSRMLS_DC) +static char *get_http_header_value(char *headers, char *type); +static int get_http_body(php_stream *socketd, char *headers, char **response, int *out_size TSRMLS_DC); +static int get_http_headers(php_stream *socketd,char **response, int *out_size TSRMLS_DC); + +int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *soapaction TSRMLS_DC) { xmlChar *buf; char *soap_headers; @@ -15,10 +19,10 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch FETCH_THIS_SDL(sdl); xmlDocDumpMemory(doc, &buf, &buf_size); - - if(!buf) - php_error(E_ERROR, "Error build soap request"); - + if(!buf) { + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Error build soap request", NULL, NULL TSRMLS_CC); + return FALSE; + } if(zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS && Z_LVAL_PP(trace) > 0) add_property_stringl(this_ptr, "__last_request", buf, buf_size, 1); @@ -31,8 +35,10 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch if(!sdl) { zval **location; - if(zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &location) == FAILURE) - php_error(E_ERROR, "Error could not find location"); + if(zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &location) == FAILURE) { + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Error could not find location", NULL, NULL TSRMLS_CC); + return FALSE; + } url = Z_STRVAL_PP(location); } else @@ -42,22 +48,26 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch url = binding->location; } - phpurl = php_url_parse(url); + if (url[0] != '\000') { + phpurl = php_url_parse(url); + } if (phpurl == NULL) { - php_error(E_ERROR, "Unable to parse URL \"%s\"", url); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Unable to parse URL", NULL, NULL TSRMLS_CC); + return FALSE; } use_ssl = strcmp(phpurl->scheme, "https") == 0; #if !HAVE_OPENSSL_EXT if (use_ssl) { - php_error(E_ERROR, "SSL support not available in this build"); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "SSL support not available in this build", NULL, NULL TSRMLS_CC); + return FALSE; } #endif - + if (phpurl->port == 0) { phpurl->port = use_ssl ? 443 : 80; } - + stream = php_stream_sock_open_host(phpurl->host, (unsigned short)phpurl->port, SOCK_STREAM, NULL, NULL); if(stream) @@ -67,18 +77,20 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch /* fire up SSL, if requested */ if (use_ssl) { if (FAILURE == php_stream_sock_ssl_activate(stream, 1)) { - php_error(E_ERROR, "SSL Connection attempt failed"); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "SSL Connection attempt failed", NULL, NULL TSRMLS_CC); + return FALSE; } } #endif - + add_property_resource(this_ptr, "httpsocket", php_stream_get_resource_id(stream)); ret = zend_list_insert(phpurl, le_url); add_property_resource(this_ptr, "httpurl", ret); zend_list_addref(ret); } else { - php_error(E_ERROR, "Could not connect to host"); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Could not connect to host", NULL, NULL TSRMLS_CC); + return FALSE; } } @@ -88,23 +100,19 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch int size = strlen(header) + strlen(phpurl->host) + strlen(phpurl->path) + 10; /* TODO: Add authentication */ - if(sdl != NULL) - { - /* TODO: need to grab soap action from wsdl....*/ - soap_headers = emalloc(size + strlen(soapaction)); - sprintf(soap_headers, header, phpurl->path, phpurl->host, buf_size, soapaction); - } - else - { - soap_headers = emalloc(size + strlen(soapaction)); - sprintf(soap_headers, header, phpurl->path, phpurl->host, buf_size, soapaction); - } - - err = php_stream_write(stream, soap_headers, strlen(soap_headers)); - if(err != (int)strlen(soap_headers)) - php_error(E_ERROR,"Failed Sending HTTP Headers"); + /* TODO: need to grab soap action from wsdl....*/ + soap_headers = emalloc(size + strlen(soapaction)); + sprintf(soap_headers, header, phpurl->path, phpurl->host, buf_size, soapaction); + + err = php_stream_write(stream, soap_headers, strlen(soap_headers)); + if(err != (int)strlen(soap_headers)) { + php_stream_close(stream); + zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Failed Sending HTTP Headers", NULL, NULL TSRMLS_CC); + return FALSE; + } /* Send cookies along with request */ if(zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) { @@ -131,46 +139,58 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch err = php_stream_write(stream, cookie_str.c, cookie_str.len); - if(err != (int)cookie_str.len) - php_error(E_ERROR,"Failed Sending HTTP Headers"); + if(err != (int)cookie_str.len) { + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Failed Sending HTTP Headers", NULL, NULL TSRMLS_CC); + return FALSE; + } smart_str_free(&cookie_str); } err = php_stream_write(stream, "\r\n", 2); - if(err != 2) - php_error(E_ERROR,"Failed Sending HTTP Headers"); + if(err != 2) { + php_stream_close(stream); + zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Failed Sending HTTP Headers", NULL, NULL TSRMLS_CC); + return FALSE; + } err = php_stream_write(stream, buf, buf_size); - if(err != (int)strlen(buf)) - php_error(E_ERROR,"Failed Sending HTTP Content"); + if(err != (int)strlen(buf)) { + php_stream_close(stream); + zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Failed Sending HTTP Content", NULL, NULL TSRMLS_CC); + return FALSE; + } efree(soap_headers); } xmlFree(buf); + return TRUE; } -void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS_DC) +int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS_DC) { char *http_headers, *http_body, *content_type, *http_version, http_status[4], *cookie_itt; int http_header_size, http_body_size, http_close; - sdlPtr sdl; zval **socket_ref; php_stream *stream; zval **trace; - FETCH_THIS_SDL(sdl); - if(FIND_SOCKET_PROPERTY(this_ptr, socket_ref) != FAILURE) { FETCH_SOCKET_RES(stream, socket_ref); } - if(!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC)) - php_error(E_ERROR, "Error Fetching http headers"); + if(!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC)) { + php_stream_close(stream); + zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Error Fetching http headers", NULL, NULL TSRMLS_CC); + return FALSE; + } /* Check to see what HTTP status was sent */ http_version = get_http_header_value(http_headers,"HTTP/"); @@ -210,15 +230,23 @@ void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRML /* Try and get headers again */ if(!strcmp(http_status, "100")) { - if(!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC)) - php_error(E_ERROR, "Error Fetching http headers"); + if(!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC)) { + php_stream_close(stream); + zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Error Fetching http headers", NULL, NULL TSRMLS_CC); + return FALSE; + } } efree(http_version); } - - if(!get_http_body(stream, http_headers, &http_body, &http_body_size TSRMLS_CC)) - php_error(E_ERROR, "Error Fetching http body"); + + if(!get_http_body(stream, http_headers, &http_body, &http_body_size TSRMLS_CC)) { + php_stream_close(stream); + zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Error Fetching http body", NULL, NULL TSRMLS_CC); + return FALSE; + } if(zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS && Z_LVAL_PP(trace) > 0) @@ -270,14 +298,13 @@ void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRML ZVAL_STRINGL(err, http_body, http_body_size, 1); add_soap_fault(this_ptr, "SOAP-ENV:Client", "Didn't recieve an xml document", NULL, err TSRMLS_CC); efree(content_type); - return; } } efree(content_type); } /* Grab and send back every cookie */ - + /* Not going to worry about Path: because we shouldn't be changing urls so path dont matter too much @@ -326,9 +353,10 @@ void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRML *buffer = http_body; *buffer_len = http_body_size; efree(http_headers); + return TRUE; } -char *get_http_header_value(char *headers, char *type) +static char *get_http_header_value(char *headers, char *type) { char *pos, *tmp = NULL; int typelen, headerslen; @@ -343,7 +371,7 @@ char *get_http_header_value(char *headers, char *type) /* start of buffer or start of line */ if (strncasecmp(pos, type, typelen) == 0) { char *eol; - + /* match */ tmp = pos + typelen; eol = strstr(tmp, "\r\n"); @@ -352,7 +380,7 @@ char *get_http_header_value(char *headers, char *type) } return estrndup(tmp, eol - tmp); } - + /* find next line */ pos = strstr(pos, "\r\n"); if (pos) @@ -363,7 +391,7 @@ char *get_http_header_value(char *headers, char *type) return NULL; } -int get_http_body(php_stream *stream, char *headers, char **response, int *out_size TSRMLS_DC) +static int get_http_body(php_stream *stream, char *headers, char **response, int *out_size TSRMLS_DC) { char *trans_enc, *content_length, *http_buf = NULL; int http_buf_size = 0; @@ -372,7 +400,7 @@ int get_http_body(php_stream *stream, char *headers, char **response, int *out_ content_length = get_http_header_value(headers, "Content-Length: "); if (trans_enc && !strcmp(trans_enc, "chunked")) { - int cur = 0, size = 0, buf_size = 0, len_size; + int buf_size = 0, len_size; char done, chunk_size[10]; done = FALSE; @@ -384,12 +412,12 @@ int get_http_body(php_stream *stream, char *headers, char **response, int *out_ if (sscanf(chunk_size, "%x", &buf_size) != -1) { http_buf = erealloc(http_buf, http_buf_size + buf_size + 1); len_size = 0; - + while (http_buf_size < buf_size) { len_size += php_stream_read(stream, http_buf + http_buf_size, buf_size - len_size); http_buf_size += len_size; } - + /* Eat up '\r' '\n' */ php_stream_getc(stream);php_stream_getc(stream); } @@ -405,7 +433,7 @@ int get_http_body(php_stream *stream, char *headers, char **response, int *out_ } else { http_buf[http_buf_size] = '\0'; } - + } else if (content_length) { int size; size = atoi(content_length); @@ -417,7 +445,8 @@ int get_http_body(php_stream *stream, char *headers, char **response, int *out_ http_buf[size] = '\0'; efree(content_length); } else { - php_error(E_ERROR, "Don't know how to read http body, No Content-Length or chunked data"); +// php_error(E_ERROR, "Don't know how to read http body, No Content-Length or chunked data"); + return FALSE; } (*response) = http_buf; @@ -425,10 +454,9 @@ int get_http_body(php_stream *stream, char *headers, char **response, int *out_ return TRUE; } -int get_http_headers(php_stream *stream, char **response, int *out_size TSRMLS_DC) +static int get_http_headers(php_stream *stream, char **response, int *out_size TSRMLS_DC) { int done = FALSE; - char chr; smart_str tmp_response = {0}; char headerbuf[8192]; @@ -452,5 +480,3 @@ int get_http_headers(php_stream *stream, char **response, int *out_size TSRMLS_D (*out_size) = tmp_response.len; return done; } - - diff --git a/ext/soap/php_http.h b/ext/soap/php_http.h index 2aa3f75ae1..c8961c8bb4 100644 --- a/ext/soap/php_http.h +++ b/ext/soap/php_http.h @@ -1,11 +1,7 @@ #ifndef PHP_HTTP_H #define PHP_HTTP_H -void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, char *soapaction TSRMLS_DC); -void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS_DC); - -char *get_http_header_value(char *headers, char *type); -int get_http_body(php_stream *socketd, char *headers, char **response, int *out_size TSRMLS_DC); -int get_http_headers(php_stream *socketd,char **response, int *out_size TSRMLS_DC); +int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *soapaction TSRMLS_DC); +int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS_DC); #endif diff --git a/ext/soap/php_packet_soap.c b/ext/soap/php_packet_soap.c index 5411c31ee9..dc036285d6 100644 --- a/ext/soap/php_packet_soap.c +++ b/ext/soap/php_packet_soap.c @@ -1,141 +1,209 @@ #include "php_soap.h" -int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval ***ret, int *num_params TSRMLS_DC) +/* SOAP client calls this function to parse response from SOAP server */ +int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval *return_value TSRMLS_DC) { xmlDocPtr response; - xmlNodePtr trav, trav2, env, body, resp, cur, fault; - zval **tmp_ret; + xmlNodePtr trav, /*trav2,*/ env, body, resp, cur, fault; + int param_count = 0; + ZVAL_NULL(return_value); + + /* Parse XML packet */ response = xmlParseMemory(buffer, buffer_size); xmlCleanupParser(); - if (!response) { - php_error(E_ERROR, "looks like we got no XML document"); + add_soap_fault(this_ptr, "SOAP-ENV:Client", "looks like we got no XML document", NULL, NULL TSRMLS_CC); + return FALSE; } - (*num_params) = 0; - + /* Get element */ + env = NULL; trav = response->children; - FOREACHNODE(trav,"Envelope",env) - { - trav2 = env->children; - FOREACHNODE(trav2,"Body",body) - { - fault = get_node(body->children,"Fault"); - if(fault != NULL) - { - char *faultcode = NULL, *faultstring = NULL, *faultactor = NULL; - zval *details = NULL; - xmlNodePtr tmp; - - tmp = get_node(fault->children,"faultcode"); - if(tmp != NULL && tmp->children != NULL) - faultcode = tmp->children->content; - - tmp = get_node(fault->children,"faultstring"); - if(tmp != NULL && tmp->children != NULL) - faultstring = tmp->children->content; - - tmp = get_node(fault->children,"faultactor"); - if(tmp != NULL && tmp->children != NULL) - faultactor = tmp->children->content; - - tmp = get_node(fault->children,"detail"); - if(tmp != NULL) - { - encodePtr enc; - enc = get_conversion(UNKNOWN_TYPE); - details = enc->to_zval(enc->details, tmp); - } + while (trav != NULL) { + if (trav->type == XML_ELEMENT_NODE && + node_is_equal_ex(trav,"Envelope","http://schemas.xmlsoap.org/soap/envelope/")) { + if (env != NULL) { + add_soap_fault(this_ptr, "SOAP-ENV:Client", "looks like we got XML with several \"Envelope\" elements\n", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; + } + env = trav; + } + trav = trav->next; + } + if (env == NULL) { + add_soap_fault(this_ptr, "SOAP-ENV:Client", "looks like we got XML without \"Envelope\" element\n", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; + } - add_soap_fault(this_ptr, faultcode, faultstring, faultactor, details TSRMLS_CC); - } - else - { - resp = body->children; - if(fn != NULL) - { - sdlParamPtr *h_param, param = NULL; - xmlNodePtr val = NULL; - encodePtr enc; - char *name, *ns = NULL; + /* Get element */ + body = NULL; + trav = env->children; + while (trav != NULL) { + if (trav->type == XML_ELEMENT_NODE && + node_is_equal_ex(trav,"Body","http://schemas.xmlsoap.org/soap/envelope/")) { + if (body != NULL) { + add_soap_fault(this_ptr, "SOAP-ENV:Client", "looks like we got \"Envelope\" with several \"Body\" elements\n", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; + } + body = trav; + } + trav = trav->next; + } + if (body == NULL) { + add_soap_fault(this_ptr, "SOAP-ENV:Client", "looks like we got \"Envelope\" without \"Body\" element\n", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; + } - if(fn->bindingType == BINDING_SOAP) - { - sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes; + /* Check if contains element */ + fault = get_node_ex(body->children,"Fault","http://schemas.xmlsoap.org/soap/envelope/"); + if(fault != NULL) { + char *faultcode = NULL, *faultstring = NULL, *faultactor = NULL; + zval *details = NULL; + xmlNodePtr tmp; - zend_hash_internal_pointer_reset(fn->responseParameters); - if(zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) != SUCCESS) - php_error(E_ERROR, "Can't find response parameter \"%s\"", param->paramName); + tmp = get_node(fault->children,"faultcode"); + if (tmp != NULL && tmp->children != NULL) { + faultcode = tmp->children->content; + } - param = (*h_param); - if(fnb->style == SOAP_DOCUMENT) - { - name = (*h_param)->encode->details.type_str; - ns = (*h_param)->encode->details.ns; - } - else - { - name = fn->responseName; - /* ns = ? */ - } + tmp = get_node(fault->children,"faultstring"); + if (tmp != NULL && tmp->children != NULL) { + faultstring = tmp->children->content; + } - cur = get_node_ex(resp, name, ns); - /* TODO: produce warning invalid ns */ - if(!cur) - cur = get_node(resp, name); - - if(!cur) - php_error(E_ERROR, "Can't find response data"); + tmp = get_node(fault->children,"faultactor"); + if (tmp != NULL && tmp->children != NULL) { + faultactor = tmp->children->content; + } + tmp = get_node(fault->children,"detail"); + if (tmp != NULL) { + encodePtr enc; + enc = get_conversion(UNKNOWN_TYPE); + details = enc->to_zval(enc->details, tmp); + } - if(fnb->style == SOAP_DOCUMENT) - val = cur; - else - val = get_node(cur->children, param->paramName); + add_soap_fault(this_ptr, faultcode, faultstring, faultactor, details TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; + } - if(!val) - php_error(E_ERROR, "Can't find response data"); + /* Parse content of element */ + resp = body->children; + if (fn != NULL) { + /* Function has WSDL description */ + sdlParamPtr *h_param, param = NULL; + xmlNodePtr val = NULL; + char *name, *ns = NULL; + zval* tmp; + + if (fn->bindingType == BINDING_SOAP) { + sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes; + int res_count = zend_hash_num_elements(fn->responseParameters); + + array_init(return_value); + zend_hash_internal_pointer_reset(fn->responseParameters); + while (zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) == SUCCESS) { + param = (*h_param); + if (fnb->style == SOAP_DOCUMENT) { + name = param->encode->details.type_str; + ns = param->encode->details.ns; + } else { + name = fn->responseName; + /* ns = ? */ + } - tmp_ret = emalloc(sizeof(zval **)); - if(param != NULL) - enc = param->encode; - else - enc = get_conversion(UNKNOWN_TYPE); + /* Get value of parameter */ + cur = get_node_ex(resp, name, ns); + if (!cur) { + cur = get_node(resp, name); + /* TODO: produce warning invalid ns */ + } + if (cur) { + if (fnb->style == SOAP_DOCUMENT) { + val = cur; + } else { + val = get_node(cur->children, param->paramName); + if (val == NULL && res_count == 1) { + val = get_node(cur->children, "return"); + } + } + } - tmp_ret[0] = master_to_zval(enc, val); - (*ret) = tmp_ret; - (*num_params) = 1; + if (!val) { + /* TODO: may be "nil" is not OK? */ + MAKE_STD_ZVAL(tmp); + ZVAL_NULL(tmp); +/* + add_soap_fault(this_ptr, "SOAP-ENV:Client", "Can't find response data", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; +*/ + } else { + /* Decoding value of parameter */ + if (param != NULL) { + tmp = master_to_zval(param->encode, val); + } else { + tmp = master_to_zval(get_conversion(UNKNOWN_TYPE), val); } } - else - { - cur = resp; - while(cur && cur->type != XML_ELEMENT_NODE) - cur = cur->next; - if(cur != NULL) - { - xmlNodePtr val; - val = cur->children; - while(val && val->type != XML_ELEMENT_NODE) - val = val->next; - - if(val != NULL) - { - encodePtr enc; - enc = get_conversion(UNKNOWN_TYPE); - tmp_ret = emalloc(sizeof(zval **)); - tmp_ret[0] = master_to_zval(enc, val); - (*ret) = tmp_ret; - (*num_params) = 1; - } + add_assoc_zval(return_value, param->paramName, tmp); + /*add_assoc_zval(return_value, (char*)val->name, tmp);*/ + + param_count++; + + zend_hash_move_forward(fn->responseParameters); + } + } + } else { + /* Function hasn't WSDL description */ + cur = resp; + array_init(return_value); + while(cur && cur->type != XML_ELEMENT_NODE) { + cur = cur->next; + } + if (cur != NULL) { + xmlNodePtr val; + val = cur->children; + while (val != NULL) { + while(val && val->type != XML_ELEMENT_NODE) { + val = val->next; + } + if (val != NULL) { + encodePtr enc; + zval *tmp; + enc = get_conversion(UNKNOWN_TYPE); + tmp = master_to_zval(enc, val); + if (val->name) { + add_assoc_zval(return_value, (char*)val->name, tmp); + } else { + add_next_index_zval(return_value, tmp); } + ++param_count; + val = val->next; } } } - ENDFOREACH(trav2); } - ENDFOREACH(trav); + + if (Z_TYPE_P(return_value) == IS_ARRAY) { + if (param_count == 0) { + zval_dtor(return_value); + ZVAL_NULL(return_value); + } else if (param_count == 1) { + zval *tmp = *(zval**)Z_ARRVAL_P(return_value)->pListHead->pData; + tmp->refcount++; + zval_dtor(return_value); + *return_value = *tmp; + FREE_ZVAL(tmp); + } + } + xmlFreeDoc(response); return TRUE; } diff --git a/ext/soap/php_packet_soap.h b/ext/soap/php_packet_soap.h index 3d0ec74673..f82f3f5364 100644 --- a/ext/soap/php_packet_soap.h +++ b/ext/soap/php_packet_soap.h @@ -1,6 +1,6 @@ #ifndef PHP_PACKET_SOAP_H #define PHP_PACKET_SOAP_H -int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval ***ret, int *num_params TSRMLS_DC); +int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval *return_value TSRMLS_DC); -#endif \ No newline at end of file +#endif diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index da634941c1..cda21747a9 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -1,4 +1,27 @@ #include "php_soap.h" + +static int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTypePtr cur_type); +static int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlTypePtr cur_type); +static int schema_sequence(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr seqType, sdlTypePtr cur_type); +static int schema_list(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr listType, sdlTypePtr cur_type); +static int schema_union(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr unionType, sdlTypePtr cur_type); +static int schema_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpCompType, sdlTypePtr cur_type); +static int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type); +static int schema_restriction_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type); +static int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type); +static int schema_extension(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type); +static int schema_all(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type); +static int schema_group(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr groupType, sdlTypePtr cur_type); +static int schema_choice(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr choiceType, sdlTypePtr cur_type); +static int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr cur_type); +static int schema_attribute(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr attrType, sdlTypePtr cur_type); +static int schema_any(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type); + +static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr); +static void delete_restriction_var_int(void *rvi); + +static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr); +static void delete_schema_restriction_var_char(void *srvc); /* 2.6.1 xsi:type 2.6.2 xsi:nil @@ -70,7 +93,7 @@ int load_schema(sdlPtr *sdl,xmlNodePtr schema) Content: (annotation?, (restriction | list | union)) */ -int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTypePtr cur_type) +static int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTypePtr cur_type) { xmlNodePtr content; xmlAttrPtr name, ns; @@ -147,7 +170,7 @@ int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTyp Content: (annotation?, (simpleType?)) */ -int schema_list(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr listType, sdlTypePtr cur_type) +static int schema_list(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr listType, sdlTypePtr cur_type) { return TRUE; } @@ -160,7 +183,7 @@ int schema_list(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr listType, sdlTypePtr cur Content: (annotation?, (simpleType*)) */ -int schema_union(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr unionType, sdlTypePtr cur_type) +static int schema_union(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr unionType, sdlTypePtr cur_type) { return TRUE; } @@ -172,7 +195,7 @@ int schema_union(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr unionType, sdlTypePtr c Content: (annotation?, (restriction | extension)) */ -int schema_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpCompType, sdlTypePtr cur_type) +static int schema_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpCompType, sdlTypePtr cur_type) { xmlNodePtr content; @@ -203,7 +226,7 @@ int schema_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpCompType, s Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?)) */ -int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type) +static int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type) { xmlNodePtr content, trav; xmlAttrPtr base; @@ -230,8 +253,7 @@ int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restTy } trav = restType->children; - do - { + while (trav != NULL) { if(trav->type == XML_ELEMENT_NODE) { if(!strcmp(trav->name, "minExclusive")) @@ -269,7 +291,8 @@ int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restTy zend_hash_next_index_insert(cur_type->restrictions->enumeration, &enumval, sizeof(sdlRestrictionCharPtr), NULL); } } - }while(trav = trav->next); + trav = trav->next; + } return TRUE; } @@ -282,7 +305,7 @@ int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restTy Content: (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)) */ -int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type) +static int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type) { xmlAttrPtr base; xmlNodePtr trav; @@ -304,8 +327,7 @@ int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr re } trav = restType->children; - do - { + while (trav != NULL) { if(trav->type == XML_ELEMENT_NODE) { if(!strcmp(trav->name, "group")) @@ -333,7 +355,8 @@ int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr re schema_attribute(sdl, tsn, trav, cur_type); } } - }while(trav = trav->next); + trav = trav->next; + } return TRUE; } @@ -346,7 +369,7 @@ int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr re Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)) */ -int schema_restriction_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type) +static int schema_restriction_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type) { xmlNodePtr content, trav; xmlAttrPtr base; @@ -366,8 +389,7 @@ int schema_restriction_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr res cur_type->restrictions = malloc(sizeof(sdlRestrictions)); trav = restType->children; - do - { + while (trav != NULL) { if(trav->type == XML_ELEMENT_NODE) { if(!strcmp(trav->name, "minExclusive")) @@ -405,12 +427,13 @@ int schema_restriction_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr res zend_hash_next_index_insert(cur_type->restrictions->enumeration, &enumval, sizeof(sdlRestrictionCharPtr), NULL); } } - }while(trav = trav->next); + trav = trav->next; + } return TRUE; } -int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr) +static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr) { xmlAttrPtr fixed, value, id; @@ -439,7 +462,7 @@ int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr) return TRUE; } -void delete_restriction_var_int(void *rvi) +static void delete_restriction_var_int(void *rvi) { sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi); if(ptr->id); @@ -447,7 +470,7 @@ void delete_restriction_var_int(void *rvi) free(ptr); } -int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr) +static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr) { xmlAttrPtr fixed, value, id; @@ -475,7 +498,7 @@ int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr) return TRUE; } -void delete_schema_restriction_var_char(void *srvc) +static void delete_schema_restriction_var_char(void *srvc) { sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc); if(ptr->id) @@ -502,7 +525,7 @@ From complexContent: Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))) */ -int schema_extension(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type) +static int schema_extension(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type) { xmlNodePtr content; xmlAttrPtr base; @@ -548,7 +571,7 @@ int schema_extension(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr Content: (annotation?, element*) */ -int schema_all(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr all, sdlTypePtr cur_type) +static int schema_all(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr all, sdlTypePtr cur_type) { xmlNodePtr element, trav; @@ -567,7 +590,7 @@ int schema_all(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr all, sdlTypePtr cur_type) Content: (annotation?, (all | choice | sequence)) */ -int schema_group(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr groupType, sdlTypePtr cur_type) +static int schema_group(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr groupType, sdlTypePtr cur_type) { xmlNodePtr content; xmlAttrPtr name; @@ -609,7 +632,7 @@ int schema_group(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr groupType, sdlTypePtr c Content: (annotation?, (element | group | choice | sequence | any)*) */ -int schema_choice(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr choiceType, sdlTypePtr cur_type) +static int schema_choice(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr choiceType, sdlTypePtr cur_type) { xmlNodePtr trav, data; @@ -664,13 +687,12 @@ int schema_choice(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr choiceType, sdlTypePtr Content: (annotation?, (element | group | choice | sequence | any)*) */ -int schema_sequence(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr seqType, sdlTypePtr cur_type) +static int schema_sequence(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr seqType, sdlTypePtr cur_type) { xmlNodePtr trav; trav = seqType->children; - do - { + while (trav != NULL) { if(trav->type == XML_ELEMENT_NODE) { if(!strcmp(trav->name, "element")) @@ -694,13 +716,13 @@ int schema_sequence(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr seqType, sdlTypePtr schema_any(sdl, tsn, trav, cur_type); } } + trav = trav->next; } - while(trav = trav->next); return TRUE; } -int schema_any(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type) +static int schema_any(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type) { return TRUE; } @@ -713,7 +735,7 @@ int schema_any(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_t Content: (annotation?, (restriction | extension)) */ -int schema_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compCont, sdlTypePtr cur_type) +static int schema_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compCont, sdlTypePtr cur_type) { xmlNodePtr content; @@ -739,7 +761,7 @@ int schema_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compCont, sdlT Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))) */ -int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlTypePtr cur_type) +static int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlTypePtr cur_type) { xmlNodePtr content; xmlAttrPtr attrs, name, ns; @@ -848,7 +870,7 @@ int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlType Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*)) */ -int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr cur_type) +static int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr cur_type) { xmlNodePtr content; xmlAttrPtr attrs, curattr, name, ns; @@ -873,7 +895,7 @@ int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr c memset(newType, 0, sizeof(sdlType)); newType->name = strdup(name->children->content); newType->namens = strdup(tsn->children->content); - newType->nullable = FALSE; + newType->nillable = FALSE; newType->min_occurs = 1; newType->max_occurs = 1; @@ -898,7 +920,7 @@ int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr c smart_str_0(&key); zend_hash_add(addHash, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), (void **)&tmp); cur_type = (*tmp); - create_encoder((*sdl), cur_type, ns->children->content, name->children->content); +// create_encoder((*sdl), cur_type, ns->children->content, name->children->content); smart_str_free(&key); } @@ -922,12 +944,12 @@ int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr c { if(!stricmp(curattr->children->content, "true") || !stricmp(curattr->children->content, "1")) - cur_type->nullable = TRUE; + cur_type->nillable = TRUE; else - cur_type->nullable = FALSE; + cur_type->nillable = FALSE; } else - cur_type->nullable = FALSE; + cur_type->nillable = FALSE; /* type = QName */ curattr = get_attribute(attrs, "type"); @@ -939,10 +961,10 @@ int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr c xmlNsPtr nsptr; parse_namespace(curattr->children->content, &cptype, &str_ns); - if(str_ns) +// if(str_ns) nsptr = xmlSearchNs(element->doc, element, str_ns); - else - nsptr = xmlSearchNsByHref(element->doc, element, ns->children->content); +// else +// nsptr = xmlSearchNsByHref(element->doc, element, ns->children->content); cur_type->encode = get_create_encoder((*sdl), cur_type, (char *)nsptr->href, (char *)cptype); if(str_ns) efree(str_ns); @@ -977,7 +999,7 @@ int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr c Content: (annotation?, (simpleType?)) */ -int schema_attribute(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr attrType, sdlTypePtr cur_type) +static int schema_attribute(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr attrType, sdlTypePtr cur_type) { xmlAttrPtr attr; sdlAttributePtr newAttr; @@ -1077,4 +1099,4 @@ int schema_attribute(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr attrType, sdlTypePt zend_hash_next_index_insert(cur_type->attributes, &newAttr, sizeof(sdlAttributePtr), NULL); return TRUE; -} \ No newline at end of file +} diff --git a/ext/soap/php_schema.h b/ext/soap/php_schema.h index c43a221608..e094b5f3ea 100644 --- a/ext/soap/php_schema.h +++ b/ext/soap/php_schema.h @@ -2,27 +2,5 @@ #define PHP_SCHEMA_H int load_schema(sdlPtr *sdl,xmlNodePtr schema); -int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTypePtr cur_type); -int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlTypePtr cur_type); -int schema_sequence(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr seqType, sdlTypePtr cur_type); -int schema_list(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr listType, sdlTypePtr cur_type); -int schema_union(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr unionType, sdlTypePtr cur_type); -int schema_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpCompType, sdlTypePtr cur_type); -int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type); -int schema_restriction_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type); -int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type); -int schema_extension(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type); -int schema_all(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type); -int schema_group(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr groupType, sdlTypePtr cur_type); -int schema_choice(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr choiceType, sdlTypePtr cur_type); -int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr cur_type); -int schema_attribute(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr attrType, sdlTypePtr cur_type); -int schema_any(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type); - -int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr); -void delete_restriction_var_int(void *rvi); - -int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr); -void delete_schema_restriction_var_char(void *srvc); #endif diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index c34f33b9e9..80c8424922 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -1,6 +1,6 @@ #include "php_soap.h" -encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr data, char *type) +encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr data, const char *type) { encodePtr enc = NULL; TSRMLS_FETCH(); @@ -14,7 +14,7 @@ encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr data, char *type) return enc; } -encodePtr get_encoder(sdlPtr sdl, char *ns, char *type) +encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type) { encodePtr enc = NULL; char *nscat; @@ -29,7 +29,7 @@ encodePtr get_encoder(sdlPtr sdl, char *ns, char *type) return enc; } -encodePtr get_encoder_ex(sdlPtr sdl, char *nscat) +encodePtr get_encoder_ex(sdlPtr sdl, const char *nscat) { encodePtr enc = NULL; TSRMLS_FETCH(); @@ -42,7 +42,7 @@ encodePtr get_encoder_ex(sdlPtr sdl, char *nscat) return enc; } -encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type) +encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns, const char *type) { encodePtr enc = NULL; smart_str nscat = {0}; @@ -63,7 +63,7 @@ encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *ty return enc; } -encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type) +encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns, const char *type) { smart_str nscat = {0}; encodePtr enc; @@ -95,32 +95,26 @@ encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type) zval *sdl_guess_convert_zval(encodeType enc, xmlNodePtr data) { sdlTypePtr type; - zval *ret; type = enc.sdl_type; - - if(type->encode) - { + if(type->encode) { if(type->encode->details.type == IS_ARRAY || - type->encode->details.type == SOAP_ENC_ARRAY) - ret = to_zval_array(enc, data); - else - ret = master_to_zval(type->encode, data); - } - else if(zend_hash_num_elements(type->elements) == 1) - { - sdlTypePtr *t; - zend_hash_internal_pointer_reset(type->elements); - if(zend_hash_get_current_data(type->elements, (void **)&t) != FAILURE && - (*t)->max_occurs != 1) - ret = to_zval_array(enc, data); - } - if(ret) - return ret; - else + type->encode->details.type == SOAP_ENC_ARRAY) { + return to_zval_array(enc, data); + } else { + if (memcmp(&type->encode->details,&enc,sizeof(enc))!=0) { + return master_to_zval(type->encode, data); + } else { + return master_to_zval(get_conversion(UNKNOWN_TYPE), data); + } + } + } else if (type->elements) { + return to_zval_object(enc, data); + } else { return guess_zval_convert(enc, data); + } } - + xmlNodePtr sdl_guess_convert_xml(encodeType enc, zval *data, int style) { sdlTypePtr type; @@ -128,33 +122,63 @@ xmlNodePtr sdl_guess_convert_xml(encodeType enc, zval *data, int style) type = enc.sdl_type; - if(type->encode) - { + if(type->encode) { if(type->encode->details.type == IS_ARRAY || - type->encode->details.type == SOAP_ENC_ARRAY) + type->encode->details.type == SOAP_ENC_ARRAY) { ret = sdl_to_xml_array(type, data, style); - else - ret = master_to_xml(type->encode, data, style); - } - else if(type->elements) - { - sdlTypePtr *t; - if(zend_hash_num_elements(type->elements) == 1) - { - zend_hash_internal_pointer_reset(type->elements); - if(zend_hash_get_current_data(type->elements, (void **)&t) != FAILURE && - (*t)->max_occurs != 1) - ret = sdl_to_xml_array((*t), data, style); + } else { + if (memcmp(&type->encode->details,&enc,sizeof(enc))!=0) { + ret = master_to_xml(type->encode, data, style); + } else { + ret = master_to_xml(get_conversion(UNKNOWN_TYPE), data, style); + } } - if(!ret) - ret = sdl_to_xml_object(type, data, style); } - else + else if(type->elements) { + ret = sdl_to_xml_object(type, data, style); + } else { ret = guess_xml_convert(enc, data, style); - - /* + } set_ns_and_type(ret, enc); - */ + return ret; +} + +zval* sdl_to_zval_object(sdlTypePtr type, xmlNodePtr data) +{ + zval *ret; + xmlNodePtr trav; + + TSRMLS_FETCH(); + + MAKE_STD_ZVAL(ret); + FIND_XML_NULL(data, ret); + + if (data) { + object_init(ret); + trav = data->children; + + while (trav != NULL) { + if(trav->type == XML_ELEMENT_NODE) + { + sdlTypePtr *element; + encodePtr enc = NULL; + zval *tmpVal; + if (trav->name != NULL && + zend_hash_find(type->elements, (char*)trav->name, strlen(trav->name)+1,(void **)&element) == SUCCESS) { + enc = (*element)->encode; + } + if (enc == NULL) { + enc = get_conversion(UNKNOWN_TYPE); + } + tmpVal = master_to_zval(enc, trav); +#ifdef ZEND_ENGINE_2 + tmpVal->refcount--; +#endif + add_property_zval(ret, (char *)trav->name, tmpVal); + } + trav = trav->next; + } + } return ret; } @@ -164,6 +188,7 @@ xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data, int style) sdlTypePtr *t, tmp; ret = xmlNewNode(NULL, "BOGUS"); + FIND_ZVAL_NULL(data, ret, style); zend_hash_internal_pointer_reset(type->elements); while(zend_hash_get_current_data(type->elements, (void **)&t) != FAILURE) @@ -172,14 +197,20 @@ xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data, int style) tmp = *t; if(zend_hash_find(Z_OBJPROP_P(data), tmp->name, strlen(tmp->name) + 1, (void **)&prop) == FAILURE) { - if(tmp->nullable == FALSE) + if(tmp->nillable == FALSE) php_error(E_ERROR, "Error encoding object to xml missing property \"%s\"", tmp->name); } else { xmlNodePtr newNode; - - newNode = master_to_xml(tmp->encode, (*prop), style); + encodePtr enc; + + if (tmp->encode) { + enc = tmp->encode; + } else { + enc = get_conversion((*prop)->type); + } + newNode = master_to_xml(enc, (*prop), style); xmlNodeSetName(newNode, tmp->name); xmlAddChild(ret, newNode); } @@ -189,16 +220,52 @@ xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data, int style) return ret; } +static void add_xml_array_elements(xmlNodePtr xmlParam, + sdlTypePtr type, + encodePtr enc, + int dimension , + int* dims, + zval* data, + int style) +{ + int j; + + if (Z_TYPE_P(data) == IS_ARRAY) { + zend_hash_internal_pointer_reset(data->value.ht); + for (j=0; jvalue.ht, (void **)&zdata); + if (dimension == 1) { + xmlNodePtr xparam; + if (enc == NULL) { + xparam = master_to_xml(get_conversion((*zdata)->type), (*zdata), style); + } else { + xparam = master_to_xml(enc, (*zdata), style); + } + + xmlNodeSetName(xparam, type->name); + xmlAddChild(xmlParam, xparam); + } else { + add_xml_array_elements(xmlParam, type, enc, dimension-1, dims+1, *zdata, style); + } + zend_hash_move_forward(data->value.ht); + } + } +} + xmlNodePtr sdl_to_xml_array(sdlTypePtr type, zval *data, int style) { smart_str array_type_and_size = {0}, array_type = {0}; int i; + int dimension = 1; + int* dims; xmlNodePtr xmlParam; + encodePtr enc = NULL; TSRMLS_FETCH(); xmlParam = xmlNewNode(NULL,"BOGUS"); - FIND_ZVAL_NULL(data, xmlParam); + FIND_ZVAL_NULL(data, xmlParam, style); if(Z_TYPE_P(data) == IS_ARRAY) { @@ -207,65 +274,93 @@ xmlNodePtr sdl_to_xml_array(sdlTypePtr type, zval *data, int style) if(style == SOAP_ENCODED) { + xmlAttrPtr *wsdl; if(type->attributes && - zend_hash_find(type->attributes, SOAP_ENC_NAMESPACE":arrayType", - sizeof(SOAP_ENC_NAMESPACE":arrayType"), - (void **)&arrayType) == SUCCESS) - { - xmlAttrPtr *wsdl; - if(zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&wsdl) == SUCCESS) - { - char *ns = NULL, *value; - smart_str *prefix = encode_new_ns(); - smart_str smart_ns = {0}; - xmlNsPtr myNs; - - parse_namespace((*wsdl)->children->content, &value, &ns); - myNs = xmlSearchNs((*wsdl)->doc, (*wsdl)->parent, ns); - - smart_str_appendl(&smart_ns, "xmlns:", sizeof("xmlns:") - 1); - smart_str_appendl(&smart_ns, prefix->c, prefix->len); - smart_str_0(&smart_ns); - - xmlSetProp(xmlParam, smart_ns.c, myNs->href); - smart_str_appends(&array_type_and_size, prefix->c); - smart_str_appendc(&array_type_and_size, ':'); - smart_str_appends(&array_type_and_size, value); - smart_str_0(&array_type_and_size); - - smart_str_free(prefix); - efree(prefix); + zend_hash_find(type->attributes, SOAP_ENC_NAMESPACE":arrayType", + sizeof(SOAP_ENC_NAMESPACE":arrayType"), + (void **)&arrayType) == SUCCESS && + zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&wsdl) == SUCCESS) { + + char *ns = NULL, *value, *end; + smart_str *prefix = encode_new_ns(); + smart_str smart_ns = {0}; + xmlNsPtr myNs; + zval** el; + + parse_namespace((*wsdl)->children->content, &value, &ns); + myNs = xmlSearchNs((*wsdl)->doc, (*wsdl)->parent, ns); + + end = strrchr(value,'['); + if (end) { + *end = '\0'; + end++; + while (*end != ']' && *end != '\0') { + if (*end == ',') { + dimension++; + } + end++; + } } - } - else - { + if(myNs != NULL) { + enc = get_encoder(SOAP_GLOBAL(sdl), myNs->href, value); + } + + dims = emalloc(sizeof(int)*dimension); + dims[0] = i; + el = &data; + for (i = 1; i < dimension; i++) { + if (el != NULL && Z_TYPE_PP(el) == IS_ARRAY && Z_ARRVAL_PP(el)->pListHead) { + el = (zval**)Z_ARRVAL_PP(el)->pListHead->pData; + if (Z_TYPE_PP(el) == IS_ARRAY) { + dims[i] = zend_hash_num_elements(Z_ARRVAL_PP(el)); + } else { + dims[i] = 0; + } + } + } + + smart_str_appendl(&smart_ns, "xmlns:", sizeof("xmlns:") - 1); + smart_str_appendl(&smart_ns, prefix->c, prefix->len); + smart_str_0(&smart_ns); + xmlSetProp(xmlParam, smart_ns.c, myNs->href); + smart_str_free(&smart_ns); + + smart_str_appends(&array_type_and_size, prefix->c); + smart_str_appendc(&array_type_and_size, ':'); + smart_str_appends(&array_type_and_size, value); + smart_str_appendc(&array_type_and_size, '['); + smart_str_append_long(&array_type_and_size, dims[0]); + for (i=1; iname); smart_str_appendc(&array_type_and_size, '['); smart_str_append_long(&array_type_and_size, i); smart_str_appendc(&array_type_and_size, ']'); smart_str_0(&array_type_and_size); + dims = emalloc(sizeof(int)*dimension); + dims[0] = i; } xmlSetProp(xmlParam, SOAP_ENC_NS_PREFIX":arrayType", array_type_and_size.c); smart_str_free(&array_type_and_size); smart_str_free(&array_type); - } - - zend_hash_internal_pointer_reset(data->value.ht); - for(;i > 0;i--) - { - xmlNodePtr xparam; - zval **zdata; - encodePtr enc; - zend_hash_get_current_data(data->value.ht, (void **)&zdata); - - enc = get_conversion((*zdata)->type); - xparam = master_to_xml(enc, (*zdata), style); + } else { + dims = emalloc(sizeof(int)*dimension); + dims[0] = i; + } - xmlNodeSetName(xparam, type->name); - xmlAddChild(xmlParam, xparam); - zend_hash_move_forward(data->value.ht); - } + add_xml_array_elements(xmlParam, type, enc, dimension, dims, data, style); + efree(dims); } if(style == SOAP_ENCODED) @@ -273,31 +368,6 @@ xmlNodePtr sdl_to_xml_array(sdlTypePtr type, zval *data, int style) return xmlParam; } -zval *sdl_convert_zval(encodeType enc, xmlNodePtr data) -{ - zval *ret; - MAKE_STD_ZVAL(ret); - ZVAL_STRING(ret, "blah", 1); - - return ret; -} - -/* -zval *sdl_convert_zval(xmlNodePtr data, sdlTypePtr type) -{ - found = zend_hash_find(EG(class_table), class_name, class_name_len + 1, (void **)&ce); - if(found != FAILURE) - { - service->type = SOAP_CLASS; - service->soap_class.ce = ce; - } -} -// this function will take a zval and apply all attributes of sldTypePtr -zval *sdl_convert_zval_to_zval(zval *data, sdlTypePtr type) -{ -} -*/ - sdlPtr get_sdl(char *uri) { sdlPtr tmp, *hndl; @@ -323,7 +393,7 @@ sdlBindingPtr get_binding_from_type(sdlPtr sdl, int type) if (sdl == NULL) { return NULL; } - + for(zend_hash_internal_pointer_reset(sdl->bindings); zend_hash_get_current_data(sdl->bindings, (void **) &binding) == SUCCESS; zend_hash_move_forward(sdl->bindings)) @@ -568,7 +638,7 @@ sdlPtr load_wsdl(char *struri, sdlPtr parent) } ENDFOREACH(trav); } - + trav = definitions->children; FOREACHNODE(trav, "import", import) { @@ -629,7 +699,7 @@ sdlPtr load_wsdl(char *struri, sdlPtr parent) if(!binding) php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: No binding element with name \"%s\"", ctype); - + if(ns) efree(ns); if(ctype) efree(ctype); if(tmpbinding->bindingType == BINDING_SOAP) @@ -637,7 +707,7 @@ sdlPtr load_wsdl(char *struri, sdlPtr parent) sdlSoapBindingPtr soapBinding; xmlNodePtr soapBindingNode; xmlAttrPtr tmp; - + soapBinding = malloc(sizeof(sdlSoapBinding)); memset(soapBinding, 0, sizeof(sdlSoapBinding)); @@ -655,7 +725,7 @@ sdlPtr load_wsdl(char *struri, sdlPtr parent) { if(strcmp(tmp->children->content, WSDL_HTTP_TRANSPORT)) php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: PHP-SOAP doesn't support transport '%s'", tmp->children->content); - + soapBinding->transport = strdup(tmp->children->content); } tmpbinding->bindingAttributes = (void *)soapBinding; @@ -824,7 +894,7 @@ sdlPtr load_wsdl(char *struri, sdlPtr parent) function->responseName = malloc(strlen(function->functionName) + strlen("Response") + 1); - sprintf(function->responseName, "%sResponse\0", function->functionName); + sprintf(function->responseName, "%sResponse", function->functionName); function->responseParameters = malloc(sizeof(HashTable)); zend_hash_init(function->responseParameters, 0, NULL, delete_paramater, 1); diff --git a/ext/soap/php_sdl.h b/ext/soap/php_sdl.h index 38c9001e84..fd0e1ef77b 100644 --- a/ext/soap/php_sdl.h +++ b/ext/soap/php_sdl.h @@ -100,7 +100,7 @@ struct _sdlType { char *name; char *namens; - int nullable; + int nillable; int min_occurs; int max_occurs; HashTable *elements; /* array of sdlTypePtr */ @@ -145,11 +145,11 @@ sdlPtr load_wsdl(char *struri, sdlPtr parent); int load_sdl(char *struri, int force_load); int load_ms_sdl(char *struri, int force_load); -encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr data, char *type); -encodePtr get_encoder(sdlPtr sdl, char *ns, char *type); -encodePtr get_encoder_ex(sdlPtr sdl, char *nscat); -encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type); -encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type); +encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr data, const char *type); +encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type); +encodePtr get_encoder_ex(sdlPtr sdl, const char *nscat); +encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns, const char *type); +encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns, const char *type); sdlBindingPtr get_binding_from_type(sdlPtr sdl, int type); sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns); @@ -163,5 +163,3 @@ xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data, int style); void delete_type(void *type); void delete_attribute(void *attribute); #endif - - diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index 9475e3207e..7f77d02add 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -141,6 +141,8 @@ ZEND_BEGIN_MODULE_GLOBALS(soap) HashTable *services; HashTable *overrides; int cur_uniq_ns; + sdlPtr sdl; + zend_bool use_soap_error_handler; ZEND_END_MODULE_GLOBALS(soap) #ifdef PHP_WIN32 #define PHP_SOAP_API __declspec(dllexport) @@ -159,73 +161,6 @@ ZEND_EXTERN_MODULE_GLOBALS(soap); # define SOAP_GLOBAL(v) (soap_globals.v) #endif -#define PHP_SOAP_SERVER_CLASSNAME "soapserver" -#define PHP_SOAP_CLASSNAME "soapobject" -#define PHP_SOAP_VAR_CLASSNAME "soapvar" -#define PHP_SOAP_FAULT_CLASSNAME "soapfault" -#define PHP_SOAP_PARAM_CLASSNAME "soapparam" - - -extern zend_module_entry soap_module_entry; -#define soap_module_ptr & soap_module_entry - -PHP_MINIT_FUNCTION(soap); -PHP_MSHUTDOWN_FUNCTION(soap); -PHP_MINFO_FUNCTION(soap); - -/* - Registry Functions - TODO: this! -*/ -PHP_FUNCTION(load_sdl); -PHP_FUNCTION(unload_sdl); -PHP_FUNCTION(unload_all_sdls); -PHP_FUNCTION(get_available_sdls); -PHP_FUNCTION(get_available_functions); -PHP_FUNCTION(get_function_parameters); -PHP_FUNCTION(soap_encode_to_xml); -PHP_FUNCTION(soap_encode_to_zval); - - -/* Server Functions */ -PHP_FUNCTION(soapserver); -PHP_FUNCTION(setclass); -PHP_FUNCTION(addfunction); -PHP_FUNCTION(getfunctions); -PHP_FUNCTION(handle); -PHP_FUNCTION(setpersistence); -PHP_FUNCTION(bind); -#ifdef HAVE_PHP_DOMXML -PHP_FUNCTION(map); -#endif - -/* Client Functions */ -PHP_FUNCTION(soapobject); -PHP_FUNCTION(__use); -PHP_FUNCTION(__style); -PHP_FUNCTION(__isfault); -PHP_FUNCTION(__getfault); -PHP_FUNCTION(__call); -PHP_FUNCTION(__parse); -PHP_FUNCTION(__generate); -PHP_FUNCTION(__trace); -PHP_FUNCTION(__getfunctions); -PHP_FUNCTION(__gettypes); -PHP_FUNCTION(__getlastresponse); -PHP_FUNCTION(__getlastrequest); -PHP_FUNCTION(__headerclass); -PHP_FUNCTION(__headerfunction); - -/* SoapVar Functions */ -PHP_FUNCTION(soapvar); - -/* SoapFault Functions */ -PHP_FUNCTION(soapfault); - -/* SoapParam Functions */ -PHP_FUNCTION(soapparam); - - #define DECLARE_TRACE(file) \ FILE *trace_fp; \ char *trace_file = file; @@ -235,13 +170,13 @@ PHP_FUNCTION(soapparam); fwrite(place, strlen(place), 1, trace_fp); \ fclose(trace_fp); -extern zend_class_entry soap_var_class_entry; +extern zend_class_entry* soap_var_class_entry; PS_SERIALIZER_FUNCS(soap); void clear_soap_fault(zval *obj); void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC); -void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC); +zval* add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC); sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int); sdlFunctionPtr get_function(sdlBindingPtr sdl, char *function_name); @@ -256,17 +191,18 @@ void delete_http_socket(void *handle); void delete_url(void *handle); void delete_mapping(void *data); +#ifndef ZEND_ENGINE_2 void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference); zval soap_get_property_handler(zend_property_reference *property_reference); int soap_set_property_handler(zend_property_reference *property_reference, zval *value); void soap_destructor(void *jobject); +#endif void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *function_name, int *num_params, zval **parameters[] TSRMLS_DC); xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name,char *uri,zval *ret TSRMLS_DC); xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval **arguments, int arg_count TSRMLS_DC); xmlNodePtr seralize_parameter(sdlParamPtr param,zval *param_val,int index,char *name, int style TSRMLS_DC); xmlNodePtr seralize_zval(zval *val, sdlParamPtr param, char *paramName, int style TSRMLS_DC); -zval *desearlize_zval(sdlPtr sdl, xmlNodePtr data, sdlParamPtr param TSRMLS_DC); void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args); #ifndef ZEND_ENGINE_2 @@ -278,10 +214,11 @@ int my_call_user_function(HashTable *function_table, zval **object_pp, zval *fun #define HTTP_RAW_POST_DATA "HTTP_RAW_POST_DATA" #define SOAP_SERVER_BEGIN_CODE() \ - zend_error_cb = soap_error_handler + zend_bool old_handler = SOAP_GLOBAL(use_soap_error_handler);\ + SOAP_GLOBAL(use_soap_error_handler) = 1; #define SOAP_SERVER_END_CODE() \ - zend_error_cb = old_handler + SOAP_GLOBAL(use_soap_error_handler) = old_handler #define FOREACHATTRNODE(n,c,i) \ diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index 786ebc97a5..b2b2b03786 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -7,13 +7,12 @@ int php_stream_xmlIO_match_wrapper(const char *filename) { TSRMLS_FETCH(); return php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ? 1 : 0; - } void *php_stream_xmlIO_open_wrapper(const char *filename) { TSRMLS_FETCH(); - return php_stream_open_wrapper(filename, "rb", ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL); + return php_stream_open_wrapper((char*)filename, "rb", ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL); } int php_stream_xmlIO_read(void *context, char *buffer, int len) @@ -91,31 +90,29 @@ int node_is_equal_ex(xmlNodePtr node, char *name, char *ns) xmlAttrPtr get_attribute_ex(xmlAttrPtr node, char *name, char *ns) { xmlAttrPtr trav = node; - if(node == NULL) return NULL; - do { + while (trav!=NULL) { if(attr_is_equal_ex(trav, name, ns)) return trav; - } while(trav = trav->next); + trav = trav->next; + } return NULL; } xmlNodePtr get_node_ex(xmlNodePtr node, char *name, char *ns) { xmlNodePtr trav = node; - if(node == NULL) return NULL; - do { + while (trav!=NULL) { if(node_is_equal_ex(trav, name, ns)) return trav; - } while(trav = trav->next); + trav = trav->next; + } return NULL; } xmlNodePtr get_node_recurisve_ex(xmlNodePtr node, char *name, char *ns) { xmlNodePtr trav = node; - if(node == NULL) return NULL; - do - { + while (trav != NULL) { if(node_is_equal_ex(trav, name, ns)) return trav; else @@ -128,7 +125,8 @@ xmlNodePtr get_node_recurisve_ex(xmlNodePtr node, char *name, char *ns) return tmp; } } - } while(trav = trav->next); + trav = trav->next; + } return NULL; } @@ -137,9 +135,7 @@ xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns xmlNodePtr trav = node, cur = NULL; xmlAttrPtr attr; - if(node == NULL) return NULL; - do - { + while (trav != NULL) { if(name != NULL) { cur = get_node_ex(trav, name, name_ns); @@ -162,7 +158,8 @@ xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns return tmp; } } - }while(trav = trav->next); + trav = trav->next; + } return NULL; } @@ -171,9 +168,7 @@ xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, cha xmlNodePtr trav = node, cur; xmlAttrPtr attr; - if(node == NULL) return NULL; - do - { + while (trav != NULL) { if(name != NULL) { cur = get_node_recurisve_ex(trav, name, name_ns); @@ -196,7 +191,8 @@ xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, cha return tmp; } } - }while(trav = trav->next); + trav = trav->next; + } return NULL; } @@ -222,11 +218,11 @@ xmlNodePtr check_and_resolve_href(xmlNodePtr data) return ret; } -int parse_namespace(char *inval, char **value, char **namespace) +int parse_namespace(const char *inval, char **value, char **namespace) { char *found = strchr(inval, ':'); - if(found != NULL) + if(found != NULL && found != inval) { (*namespace) = estrndup(inval, found - inval); (*value) = estrdup(++found); @@ -239,4 +235,3 @@ int parse_namespace(char *inval, char **value, char **namespace) return FALSE; } - diff --git a/ext/soap/php_xml.h b/ext/soap/php_xml.h index 461bf9dd97..e791984231 100644 --- a/ext/soap/php_xml.h +++ b/ext/soap/php_xml.h @@ -17,7 +17,7 @@ xmlNodePtr get_node_ex(xmlNodePtr node,char *name, char *ns); xmlNodePtr get_node_recurisve_ex(xmlNodePtr node,char *name, char *ns); xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns); xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns); -int parse_namespace(char *inval,char **value,char **namespace); +int parse_namespace(const char *inval,char **value,char **namespace); xmlNodePtr check_and_resolve_href(xmlNodePtr data); int php_stream_xmlIO_match_wrapper(const char *filename); diff --git a/ext/soap/soap.c b/ext/soap/soap.c index a349503d86..2cc505a23d 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -2,6 +2,7 @@ #include "config.h" #endif #include "php_soap.h" +#include "ext/session/php_session.h" int le_sdl = 0; int le_url = 0; @@ -11,69 +12,143 @@ int le_service = 0; static void function_to_string(sdlFunctionPtr function, smart_str *buf); static void type_to_string(sdlTypePtr type, smart_str *buf, int level); -static zend_class_entry soap_class_entry; -static zend_class_entry soap_server_class_entry; -static zend_class_entry soap_fault_class_entry; -zend_class_entry soap_var_class_entry; -zend_class_entry soap_param_class_entry; +static zend_class_entry* soap_class_entry; +static zend_class_entry* soap_server_class_entry; +static zend_class_entry* soap_fault_class_entry; +zend_class_entry* soap_var_class_entry; +zend_class_entry* soap_param_class_entry; ZEND_DECLARE_MODULE_GLOBALS(soap); -static void (*old_handler)(int, const char *, const uint, const char*, va_list); +static void (*old_error_handler)(int, const char *, const uint, const char*, va_list); + +#define PHP_SOAP_SERVER_CLASSNAME "soapserver" +#define PHP_SOAP_CLASSNAME "soapobject" +#define PHP_SOAP_VAR_CLASSNAME "soapvar" +#define PHP_SOAP_FAULT_CLASSNAME "soapfault" +#define PHP_SOAP_PARAM_CLASSNAME "soapparam" + +extern zend_module_entry soap_module_entry; +#define soap_module_ptr & soap_module_entry + +PHP_MINIT_FUNCTION(soap); +PHP_MSHUTDOWN_FUNCTION(soap); +PHP_MINFO_FUNCTION(soap); + +#ifndef ZEND_ENGINE_2 +# ifndef PHP_METHOD +# define PHP_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name)) +# define PHP_ME(classname, name, arg_info, flags) ZEND_NAMED_FE(name, ZEND_FN(classname##_##name), arg_info) +# endif + +static char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) +{ + register unsigned char *str = (unsigned char*)source; + register unsigned char *result = (unsigned char*)dest; + register unsigned char *end = str + length; + + while (str < end) { + *result++ = tolower((int)*str++); + } + *result = *end; + + return dest; +} +#endif + +/* + Registry Functions + TODO: this! +*/ +PHP_FUNCTION(soap_encode_to_xml); +PHP_FUNCTION(soap_encode_to_zval); +PHP_FUNCTION(use_soap_error_handler); + + +/* Server Functions */ +PHP_METHOD(soapserver,soapserver); +PHP_METHOD(soapserver,setclass); +PHP_METHOD(soapserver,addfunction); +PHP_METHOD(soapserver,getfunctions); +PHP_METHOD(soapserver,handle); +PHP_METHOD(soapserver,setpersistence); +PHP_METHOD(soapserver,bind); +#ifdef HAVE_PHP_DOMXML +PHP_METHOD(soapserver,map); +#endif + +/* Client Functions */ +PHP_METHOD(soapobject, soapobject); +PHP_METHOD(soapobject, __use); +PHP_METHOD(soapobject, __style); +PHP_METHOD(soapobject, __isfault); +PHP_METHOD(soapobject, __getfault); +PHP_METHOD(soapobject, __call); +PHP_METHOD(soapobject, __trace); +PHP_METHOD(soapobject, __getfunctions); +PHP_METHOD(soapobject, __gettypes); +PHP_METHOD(soapobject, __getlastresponse); +PHP_METHOD(soapobject, __getlastrequest); + +/* SoapVar Functions */ +PHP_METHOD(soapvar, soapvar); + +/* SoapFault Functions */ +PHP_METHOD(soapfault, soapfault); + +/* SoapParam Functions */ +PHP_METHOD(soapparam, soapparam); static zend_function_entry soap_functions[] = { #ifdef HAVE_PHP_DOMXML PHP_FE(soap_encode_to_xml, NULL) PHP_FE(soap_encode_to_zval, NULL) #endif + PHP_FE(use_soap_error_handler, NULL) {NULL, NULL, NULL} }; static zend_function_entry soap_fault_functions[] = { - PHP_FE(soapfault, NULL) + PHP_ME(soapfault, soapfault, NULL, 0) {NULL, NULL, NULL} }; static zend_function_entry soap_server_functions[] = { - PHP_FE(soapserver,NULL) - PHP_FE(setpersistence,NULL) - PHP_FE(setclass,NULL) - PHP_FE(addfunction,NULL) - PHP_FE(getfunctions,NULL) - PHP_FE(handle,NULL) - PHP_FE(bind,NULL) + PHP_ME(soapserver, soapserver, NULL, 0) + PHP_ME(soapserver, setpersistence, NULL, 0) + PHP_ME(soapserver, setclass, NULL, 0) + PHP_ME(soapserver, addfunction, NULL, 0) + PHP_ME(soapserver, getfunctions, NULL, 0) + PHP_ME(soapserver, handle, NULL, 0) + PHP_ME(soapserver, bind, NULL, 0) #ifdef HAVE_PHP_DOMXML - PHP_FE(map, NULL) + PHP_ME(soapserver, map, NULL, 0) #endif {NULL, NULL, NULL} }; static zend_function_entry soap_client_functions[] = { - PHP_FE(soapobject, NULL) - PHP_FE(__isfault, NULL) - PHP_FE(__getfault, NULL) - PHP_FE(__use, NULL) - PHP_FE(__style, NULL) - PHP_FE(__call, NULL) - PHP_FE(__parse, NULL) - PHP_FE(__generate, NULL) - PHP_FE(__trace, NULL) - PHP_FE(__headerclass, NULL) - PHP_FE(__headerfunction, NULL) - PHP_FE(__getlastrequest, NULL) - PHP_FE(__getlastresponse, NULL) - PHP_FE(__getfunctions, NULL) - PHP_FE(__gettypes, NULL) + PHP_ME(soapobject, soapobject, NULL, 0) + PHP_ME(soapobject, __isfault, NULL, 0) + PHP_ME(soapobject, __getfault, NULL, 0) + PHP_ME(soapobject, __use, NULL, 0) + PHP_ME(soapobject, __style, NULL, 0) + PHP_ME(soapobject, __call, NULL, 0) + PHP_ME(soapobject, __trace, NULL, 0) + PHP_ME(soapobject, __getlastrequest, NULL, 0) + PHP_ME(soapobject, __getlastresponse, NULL, 0) + PHP_ME(soapobject, __getfunctions, NULL, 0) + PHP_ME(soapobject, __gettypes, NULL, 0) {NULL, NULL, NULL} }; static zend_function_entry soap_var_functions[] = { - PHP_FE(soapvar, NULL) + PHP_ME(soapvar, soapvar, NULL, 0) {NULL, NULL, NULL} }; static zend_function_entry soap_param_functions[] = { - PHP_FE(soapparam, NULL) + PHP_ME(soapparam, soapparam, NULL, 0) {NULL, NULL, NULL} }; @@ -160,6 +235,8 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals) zend_hash_add(soap_globals->defEncPrefix, APACHE_NS_PREFIX, sizeof(APACHE_NS_PREFIX), APACHE_NAMESPACE, sizeof(APACHE_NAMESPACE), NULL); zend_hash_add(soap_globals->defEncPrefix, SOAP_ENC_NS_PREFIX, sizeof(SOAP_ENC_NS_PREFIX), SOAP_ENC_NAMESPACE, sizeof(SOAP_ENC_NAMESPACE), NULL); + soap_globals->use_soap_error_handler = 0; + soap_globals->sdl = NULL; } static void php_soap_del_globals(zend_soap_globals *soap_globals) @@ -173,6 +250,7 @@ static void php_soap_del_globals(zend_soap_globals *soap_globals) PHP_MSHUTDOWN_FUNCTION(soap) { + zend_error_cb = old_error_handler; zend_hash_destroy(SOAP_GLOBAL(sdls)); zend_hash_destroy(SOAP_GLOBAL(services)); zend_hash_destroy(SOAP_GLOBAL(defEnc)); @@ -184,6 +262,8 @@ PHP_MSHUTDOWN_FUNCTION(soap) PHP_MINIT_FUNCTION(soap) { + zend_class_entry ce; + /* TODO: add ini entry for always use soap errors */ ZEND_INIT_MODULE_GLOBALS(soap, php_soap_init_globals, php_soap_del_globals); @@ -191,29 +271,48 @@ PHP_MINIT_FUNCTION(soap) xmlRegisterDefaultInputCallbacks(); xmlRegisterInputCallbacks(php_stream_xmlIO_match_wrapper, php_stream_xmlIO_open_wrapper, php_stream_xmlIO_read, php_stream_xmlIO_close); - + /* Register SoapObject class */ - /* BIG NOTE : THIS EMITS AN COMPILATION WARNING UNDER ZE2 - handle_function_call deprecated. + /* BIG NOTE : THIS EMITS AN COMPILATION WARNING UNDER ZE2 - handle_function_call deprecated. soap_call_function_handler should be of type struct _zend_function, not (*handle_function_call). */ - INIT_OVERLOADED_CLASS_ENTRY(soap_class_entry, PHP_SOAP_CLASSNAME, soap_client_functions, soap_call_function_handler, NULL, NULL); - zend_register_internal_class(&soap_class_entry TSRMLS_CC); +#ifdef ZEND_ENGINE_2 + { + zend_internal_function fe; + fe.type = ZEND_INTERNAL_FUNCTION; + fe.handler = zif_soapobject___call; + fe.function_name = NULL; + fe.scope = NULL; + fe.fn_flags = 0; + fe.prototype = NULL; + fe.num_args = 2; + fe.arg_info = NULL; + fe.pass_rest_by_reference = 0; + + INIT_OVERLOADED_CLASS_ENTRY(ce, PHP_SOAP_CLASSNAME, soap_client_functions, + (zend_function *)&fe, NULL, NULL); + soap_class_entry = zend_register_internal_class(&ce TSRMLS_CC); + } +#else + INIT_OVERLOADED_CLASS_ENTRY(ce, PHP_SOAP_CLASSNAME, soap_client_functions, soap_call_function_handler, NULL, NULL); + soap_class_entry = zend_register_internal_class(&ce TSRMLS_CC); +#endif /* Register SoapVar class */ - INIT_CLASS_ENTRY(soap_var_class_entry, PHP_SOAP_VAR_CLASSNAME, soap_var_functions); - zend_register_internal_class(&soap_var_class_entry TSRMLS_CC); + INIT_CLASS_ENTRY(ce, PHP_SOAP_VAR_CLASSNAME, soap_var_functions); + soap_var_class_entry = zend_register_internal_class(&ce TSRMLS_CC); /* Register SoapServer class */ - INIT_CLASS_ENTRY(soap_server_class_entry, PHP_SOAP_SERVER_CLASSNAME, soap_server_functions); - zend_register_internal_class(&soap_server_class_entry TSRMLS_CC); + INIT_CLASS_ENTRY(ce, PHP_SOAP_SERVER_CLASSNAME, soap_server_functions); + soap_server_class_entry = zend_register_internal_class(&ce TSRMLS_CC); /* Register SoapFault class */ - INIT_CLASS_ENTRY(soap_fault_class_entry, PHP_SOAP_FAULT_CLASSNAME, soap_fault_functions); - zend_register_internal_class(&soap_fault_class_entry TSRMLS_CC); + INIT_CLASS_ENTRY(ce, PHP_SOAP_FAULT_CLASSNAME, soap_fault_functions); + soap_fault_class_entry = zend_register_internal_class(&ce TSRMLS_CC); /* Register SoapParam class */ - INIT_CLASS_ENTRY(soap_param_class_entry, PHP_SOAP_PARAM_CLASSNAME, soap_param_functions); - zend_register_internal_class(&soap_param_class_entry TSRMLS_CC); + INIT_CLASS_ENTRY(ce, PHP_SOAP_PARAM_CLASSNAME, soap_param_functions); + soap_param_class_entry = zend_register_internal_class(&ce TSRMLS_CC); le_sdl = register_list_destructors(NULL, NULL); le_url = register_list_destructors(delete_url, NULL); @@ -279,7 +378,8 @@ PHP_MINIT_FUNCTION(soap) REGISTER_LONG_CONSTANT("XSD_UNSIGNEDBYTE", XSD_UNSIGNEDBYTE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("XSD_POSITIVEINTEGER", XSD_POSITIVEINTEGER, CONST_CS | CONST_PERSISTENT); - old_handler = zend_error_cb; + old_error_handler = zend_error_cb; + zend_error_cb = soap_error_handler; #if HAVE_PHP_SESSION php_session_register_serializer("soap", PS_SERIALIZER_ENCODE_NAME(soap), PS_SERIALIZER_DECODE_NAME(soap)); @@ -412,7 +512,7 @@ PHP_FUNCTION(soap_encode_to_zval) #endif /* SoapParam functions */ -PHP_FUNCTION(soapparam) +PHP_METHOD(soapparam,soapparam) { zval *thisObj, *data; char *name; @@ -423,13 +523,15 @@ PHP_FUNCTION(soapparam) GET_THIS_OBJECT(thisObj); +#ifndef ZEND_ENGINE_2 zval_add_ref(&data); +#endif add_property_stringl(thisObj, "param_name", name, name_length, 1); add_property_zval(thisObj, "param_data", data); } /* SoapFault functions */ -PHP_FUNCTION(soapfault) +PHP_METHOD(soapfault,soapfault) { char *fault_string = NULL, *fault_code = NULL, *fault_actor = NULL; int fault_string_len, fault_code_len, fault_actor_len; @@ -441,13 +543,11 @@ PHP_FUNCTION(soapfault) GET_THIS_OBJECT(thisObj); - if(details) - zval_add_ref(&details); set_soap_fault(thisObj, fault_code, fault_string, fault_actor, details TSRMLS_CC); } /* SoapVar functions */ -PHP_FUNCTION(soapvar) +PHP_METHOD(soapvar,soapvar) { zval *data, *thisObj, *type; char *stype = NULL, *ns = NULL, *name = NULL, *namens = NULL; @@ -455,9 +555,8 @@ PHP_FUNCTION(soapvar) GET_THIS_OBJECT(thisObj); if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!z|ssss", &data, &type, &stype, &stype_len, &ns, &ns_len, &name, &name_len, &namens, &namens_len) == FAILURE) - php_error(E_ERROR, "Invalid arguments to SoapVal constructor"); + php_error(E_ERROR, "Invalid arguments to SoapVar constructor"); - zval_add_ref(&data); if(Z_TYPE_P(type) == IS_NULL) add_property_long(thisObj, "enc_type", UNKNOWN_TYPE); else @@ -468,7 +567,12 @@ PHP_FUNCTION(soapvar) php_error(E_ERROR, "Cannot find encoding for SoapVar"); } - add_property_zval(thisObj, "enc_value", data); + if (data) { +#ifndef ZEND_ENGINE_2 + zval_add_ref(&data); +#endif + add_property_zval(thisObj, "enc_value", data); + } if(stype && strlen(stype) > 0) add_property_stringl(thisObj, "enc_stype", stype, stype_len, 1); @@ -481,7 +585,7 @@ PHP_FUNCTION(soapvar) } /* SoapServer functions */ -PHP_FUNCTION(soapserver) +PHP_METHOD(soapserver,soapserver) { zval *thisObj; soapServicePtr service; @@ -490,8 +594,9 @@ PHP_FUNCTION(soapserver) SOAP_SERVER_BEGIN_CODE(); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &uri_len) == FAILURE) - php_error(E_ERROR, "Wrong number of parameters to SoapServer constructor"); + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &uri_len) == FAILURE) { + php_error(E_ERROR, "Invalid arguments to SoapServer constructor"); + } GET_THIS_OBJECT(thisObj); @@ -518,7 +623,7 @@ PHP_FUNCTION(soapserver) (zval && Z_TYPE_P(zval) != IS_NULL) #ifdef HAVE_PHP_DOMXML -PHP_FUNCTION(map) +PHP_FUNCTION(SoapServer,map) { char *type, *class_name; zval *to_xml_before = NULL, *to_xml = NULL, *to_xml_after = NULL, @@ -642,7 +747,7 @@ PHP_FUNCTION(map) } #endif -PHP_FUNCTION(bind) +PHP_METHOD(soapserver,bind) { char *wsdl; int wsdl_len; @@ -659,12 +764,13 @@ PHP_FUNCTION(bind) SOAP_SERVER_END_CODE(); } -PHP_FUNCTION(setpersistence) +PHP_METHOD(soapserver,setpersistence) { soapServicePtr service; int value; SOAP_SERVER_BEGIN_CODE(); + FETCH_THIS_SERVICE(service); if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) != FAILURE) @@ -675,7 +781,7 @@ PHP_FUNCTION(setpersistence) value == SOAP_PERSISTENCE_REQUEST) service->soap_class.persistance = value; else - php_error(E_ERROR, "Tried to set persistence with bogus value (%ld)", value); + php_error(E_ERROR, "Tried to set persistence with bogus value (%d)", value); } else php_error(E_ERROR, "Tried to set persistence when you are using you SOAP SERVER in function mode, no persistence needed"); @@ -684,7 +790,7 @@ PHP_FUNCTION(setpersistence) SOAP_SERVER_END_CODE(); } -PHP_FUNCTION(setclass) +PHP_METHOD(soapserver,setclass) { soapServicePtr service; zend_class_entry *ce; @@ -714,7 +820,11 @@ PHP_FUNCTION(setclass) if(found != FAILURE) { service->type = SOAP_CLASS; +#ifdef ZEND_ENGINE_2 + service->soap_class.ce = *(zend_class_entry**)ce; +#else service->soap_class.ce = ce; +#endif service->soap_class.persistance = SOAP_PERSISTENCE_REQUEST; service->soap_class.argc = argc - 1; if(service->soap_class.argc > 0) @@ -735,46 +845,51 @@ PHP_FUNCTION(setclass) php_error(E_ERROR, "You must pass in a string to setclass"); efree(argv); + SOAP_SERVER_END_CODE(); } -PHP_FUNCTION(getfunctions) +PHP_METHOD(soapserver,getfunctions) { - soapServicePtr service; - HashPosition pos; + soapServicePtr service; + HashTable *ft = NULL; SOAP_SERVER_BEGIN_CODE(); + ZERO_PARAM() FETCH_THIS_SERVICE(service); array_init(return_value); - if(service->type == SOAP_CLASS) - { - zend_function *f; - zend_hash_internal_pointer_reset_ex(&service->soap_class.ce->function_table, &pos); - while(zend_hash_get_current_data_ex(&service->soap_class.ce->function_table, (void **)&f, &pos) != FAILURE) + if (service->type == SOAP_CLASS) { + ft = &service->soap_class.ce->function_table; + } else if (service->soap_functions.functions_all == TRUE) { + ft = EG(function_table); + } else if (service->soap_functions.ft != NULL) { + zval **name; + HashPosition pos; + + zend_hash_internal_pointer_reset_ex(service->soap_functions.ft, &pos); + while(zend_hash_get_current_data_ex(service->soap_functions.ft, (void **)&name, &pos) != FAILURE) { - add_next_index_string(return_value, f->common.function_name, 1); - zend_hash_move_forward_ex(&service->soap_class.ce->function_table, &pos); + add_next_index_string(return_value, Z_STRVAL_PP(name), 1); + zend_hash_move_forward_ex(service->soap_functions.ft, &pos); } } - else if(service->soap_functions.functions_all == TRUE) - { + if (ft != NULL) { zend_function *f; - zend_hash_internal_pointer_reset_ex(EG(function_table), &pos); - while(zend_hash_get_current_data_ex(EG(function_table), (void **)&f, &pos) != FAILURE) + HashPosition pos; + zend_hash_internal_pointer_reset_ex(ft, &pos); + while(zend_hash_get_current_data_ex(ft, (void **)&f, &pos) != FAILURE) { add_next_index_string(return_value, f->common.function_name, 1); - zend_hash_move_forward_ex(EG(function_table), &pos); + zend_hash_move_forward_ex(ft, &pos); } } - else if(service->soap_functions.ft != NULL) - zend_hash_copy(Z_ARRVAL_P(return_value), service->soap_functions.ft, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); SOAP_SERVER_END_CODE(); } -PHP_FUNCTION(addfunction) +PHP_METHOD(soapserver, addfunction) { soapServicePtr service; zval *function_name, *function_copy; @@ -788,7 +903,7 @@ PHP_FUNCTION(addfunction) php_error(E_ERROR, "Invalid parameters passed to addfunction"); /* TODO: could use zend_is_callable here */ - + if(function_name->type == IS_ARRAY) { if(service->type == SOAP_FUNCTIONS) @@ -797,6 +912,7 @@ PHP_FUNCTION(addfunction) if(service->soap_functions.ft == NULL) { + service->soap_functions.functions_all = FALSE; service->soap_functions.ft = emalloc(sizeof(HashTable)); zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0); } @@ -804,32 +920,40 @@ PHP_FUNCTION(addfunction) zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(function_name), &pos); while(zend_hash_get_current_data_ex(Z_ARRVAL_P(function_name), (void **)&tmp_function, &pos) != FAILURE) { + char *key; + int key_len; + zend_function *f; + if(Z_TYPE_PP(tmp_function) != IS_STRING) php_error(E_ERROR, "Tried to add a function that isn't a string"); - MAKE_STD_ZVAL(function_copy); - *function_copy = *(*tmp_function); - zval_copy_ctor(function_copy); - - php_strtolower(Z_STRVAL_P(function_copy), Z_STRLEN_P(function_copy)); + key_len = Z_STRLEN_PP(tmp_function); + key = emalloc(key_len + 1); + zend_str_tolower_copy(key, Z_STRVAL_PP(tmp_function), key_len); - if(zend_hash_exists(EG(function_table), Z_STRVAL_P(function_copy), Z_STRLEN_P(function_copy) + 1) == FALSE) + if(zend_hash_find(EG(function_table), key, key_len+1, (void**)&f) == FAILURE) php_error(E_ERROR, "Tried to add a non existant function (\"%s\")", Z_STRVAL_PP(tmp_function)); - zend_hash_update(service->soap_functions.ft, Z_STRVAL_P(function_copy), Z_STRLEN_P(function_copy) + 1, &function_copy, sizeof(zval *), NULL); + MAKE_STD_ZVAL(function_copy); + ZVAL_STRING(function_copy, f->common.function_name, 1); + zend_hash_update(service->soap_functions.ft, key, key_len+1, &function_copy, sizeof(zval *), NULL); + + efree(key); zend_hash_move_forward_ex(Z_ARRVAL_P(function_name), &pos); } } } else if(function_name->type == IS_STRING) { - MAKE_STD_ZVAL(function_copy); - *function_copy = *function_name; - zval_copy_ctor(function_copy); + char *key; + int key_len; + zend_function *f; - php_strtolower(Z_STRVAL_P(function_copy), Z_STRLEN_P(function_copy)); + key_len = Z_STRLEN_P(function_name); + key = emalloc(key_len + 1); + zend_str_tolower_copy(key, Z_STRVAL_P(function_name), key_len); - if(zend_hash_exists(EG(function_table), Z_STRVAL_P(function_copy), Z_STRLEN_P(function_copy) + 1) == FALSE) + if(zend_hash_find(EG(function_table), key, key_len+1, (void**)&f) == FAILURE) php_error(E_ERROR, "Tried to add a non existant function (\"%s\")", Z_STRVAL_P(function_name)); if(service->soap_functions.ft == NULL) { @@ -838,7 +962,10 @@ PHP_FUNCTION(addfunction) zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0); } - zend_hash_update(service->soap_functions.ft, Z_STRVAL_P(function_copy), Z_STRLEN_P(function_copy) + 1, &function_copy, sizeof(zval *), NULL); + MAKE_STD_ZVAL(function_copy); + ZVAL_STRING(function_copy, f->common.function_name, 1); + zend_hash_update(service->soap_functions.ft, key, key_len+1, &function_copy, sizeof(zval *), NULL); + efree(key); } else if(function_name->type == IS_LONG) { @@ -859,7 +986,7 @@ PHP_FUNCTION(addfunction) SOAP_SERVER_END_CODE(); } -PHP_FUNCTION(handle) +PHP_METHOD(soapserver, handle) { soapServicePtr service; xmlDocPtr doc_request, doc_return; @@ -869,11 +996,10 @@ PHP_FUNCTION(handle) xmlChar *buf; HashTable *function_table; - FETCH_THIS_SERVICE(service); - SOAP_SERVER_BEGIN_CODE(); - ZERO_PARAM(); + FETCH_THIS_SERVICE(service); + ZERO_PARAM(); INIT_ZVAL(retval); if(zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **)&server_vars) == SUCCESS) @@ -883,10 +1009,18 @@ PHP_FUNCTION(handle) { if(!strcmp(Z_STRVAL_PP(req_method), "GET") && zend_hash_find(Z_ARRVAL_PP(server_vars), "QUERY_STRING", sizeof("QUERY_STRING"), (void **)&query_string) == SUCCESS) { - if(!strcmp(Z_STRVAL_PP(query_string), "WSDL")) + if(strstr(Z_STRVAL_PP(query_string), "wsdl") != NULL || + strstr(Z_STRVAL_PP(query_string), "WSDL") != NULL) { if(service->sdl) { +/* + char *hdr = emalloc(sizeof("Location: ")+strlen(service->sdl->source)); + strcpy(hdr,"Location: "); + strcat(hdr,service->sdl->source); + sapi_add_header(hdr, sizeof("Location: ")+strlen(service->sdl->source)-1, 1); + efree(hdr); +*/ zval readfile, readfile_ret, *param; INIT_ZVAL(readfile); @@ -902,6 +1036,20 @@ PHP_FUNCTION(handle) zval_ptr_dtor(¶m); zval_dtor(&readfile); zval_dtor(&readfile_ret); + + SOAP_SERVER_END_CODE(); + return; + } else { + php_error(E_ERROR, "WSDL generation is not supported yet"); +/* + sapi_add_header("Content-Type: text/xml", sizeof("Content-Type: text/xml"), 1); + PUTS("\nuri); + PUTS("\">\n"); + PUTS("
"); +*/ SOAP_SERVER_END_CODE(); return; } @@ -925,6 +1073,11 @@ PHP_FUNCTION(handle) doc_request = xmlParseMemory(Z_STRVAL_PP(raw_post),Z_STRLEN_PP(raw_post)); xmlCleanupParser(); + if (doc_request == NULL) { + php_error(E_ERROR, "Bad Request"); + } + + SOAP_GLOBAL(sdl) = service->sdl; deseralize_function_call(service->sdl, doc_request, &function_name, &num_params, ¶ms TSRMLS_CC); xmlFreeDoc(doc_request); @@ -933,45 +1086,22 @@ PHP_FUNCTION(handle) sprintf(response_name,"%sResponse",fn_name); if(service->type == SOAP_CLASS) - { + { soap_obj = NULL; /* If persistent then set soap_obj from from the previous created session (if available) */ if(service->soap_class.persistance == SOAP_PERSISTENCE_SESSION) { zval **tmp_soap; - /* - Try and call session regiser for our dummy session object - The only reason that i use call_user_function is that - their isn't a way to start the session from an extension - so calling session_register will both register the var - and start the session - */ - { - zval *bogus_session_name, session_register, sess_retval; - - INIT_ZVAL(session_register); - INIT_ZVAL(sess_retval); - - if(!zend_ini_long("register_globals", sizeof("register_globals"), 0)) - php_error(E_ERROR, "PHP-SOAP requires 'register_globals' to be on when using persistent objects please check your php.ini file"); - - MAKE_STD_ZVAL(bogus_session_name); - - ZVAL_STRING(bogus_session_name, "_bogus_session_name", 1); - ZVAL_STRING(&session_register, "session_register", 1); - - if(call_user_function(EG(function_table), NULL, &session_register, &sess_retval, 1, &bogus_session_name TSRMLS_CC) == FAILURE) - php_error(E_ERROR,"session_register failed"); - - zval_ptr_dtor(&bogus_session_name); - zval_dtor(&session_register); - zval_dtor(&sess_retval); + if (PS(session_status) != php_session_active && + PS(session_status) != php_session_disabled) { + php_session_start(TSRMLS_C); } /* Find the soap object and assign */ - if(zend_hash_find(&EG(symbol_table), "_bogus_session_name", sizeof("_bogus_session_name"), (void **) &tmp_soap) == SUCCESS) + if (zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), "_bogus_session_name", sizeof("_bogus_session_name"), (void **) &tmp_soap) == SUCCESS) { soap_obj = *tmp_soap; + } } /* If new session or something wierd happned */ @@ -980,7 +1110,6 @@ PHP_FUNCTION(handle) zval *tmp_soap; MAKE_STD_ZVAL(tmp_soap); object_init_ex(tmp_soap, service->soap_class.ce); - /* Call constructor */ if(zend_hash_exists(&Z_OBJCE_P(tmp_soap)->function_table, service->soap_class.ce->name, strlen(service->soap_class.ce->name) + 1)) { @@ -1000,7 +1129,7 @@ PHP_FUNCTION(handle) if(service->soap_class.persistance == SOAP_PERSISTENCE_SESSION) { zval **tmp_soap_pp; - if(zend_hash_update(&EG(symbol_table), "_bogus_session_name", sizeof("_bogus_session_name"), &tmp_soap, sizeof(zval *), (void **)&tmp_soap_pp) == SUCCESS) + if(zend_hash_update(Z_ARRVAL_P(PS(http_session_vars)), "_bogus_session_name", sizeof("_bogus_session_name"), &tmp_soap, sizeof(zval *), (void **)&tmp_soap_pp) == SUCCESS) soap_obj = *tmp_soap_pp; } else @@ -1043,6 +1172,8 @@ PHP_FUNCTION(handle) else php_error(E_ERROR, "Function (%s) call failed", Z_STRVAL(function_name)); + SOAP_GLOBAL(sdl) = NULL; + /* Flush buffer */ php_end_ob_buffer(0, 0 TSRMLS_CC); @@ -1081,6 +1212,7 @@ PHP_FUNCTION(handle) } zval_dtor(&retval); + SOAP_SERVER_END_CODE(); } @@ -1090,6 +1222,10 @@ void soap_error_handler(int error_num, const char *error_filename, const uint er int buffer_len; TSRMLS_FETCH(); + if (!SOAP_GLOBAL(use_soap_error_handler)) { + old_error_handler(error_num, error_filename, error_lineno, format, args); + return; + } buffer_len = vsnprintf(buffer, sizeof(buffer)-1, format, args); buffer[sizeof(buffer)-1]=0; if(buffer_len > sizeof(buffer) - 1 || buffer_len < 0) { @@ -1122,7 +1258,7 @@ void soap_error_handler(int error_num, const char *error_filename, const uint er doc_return = seralize_response_call(NULL, NULL, NULL, &ret TSRMLS_CC); /* Build and send our headers + http 500 status */ - /* + /* xmlDocDumpMemoryEnc(doc_return, &buf, &size, XML_CHAR_ENCODING_UTF8); */ xmlDocDumpMemory(doc_return, &buf, &size); @@ -1130,7 +1266,7 @@ void soap_error_handler(int error_num, const char *error_filename, const uint er sapi_add_header(cont_len, strlen(cont_len) + 1, 1); sapi_add_header("Content-Type: text/xml", sizeof("Content-Type: text/xml"), 1); - /* + /* Want to return HTTP 500 but apache wants to over write our fault code with their own handling... Figure this out later sapi_add_header("HTTP/1.1 500 Internal Service Error", sizeof("HTTP/1.1 500 Internal Service Error"), 1); @@ -1148,8 +1284,19 @@ void soap_error_handler(int error_num, const char *error_filename, const uint er } } +PHP_FUNCTION(use_soap_error_handler) +{ + zend_bool handler = 1; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &handler) == SUCCESS) + { + SOAP_GLOBAL(use_soap_error_handler) = handler; + } +} + + /* SoapObject functions */ -PHP_FUNCTION(soapobject) +PHP_METHOD(soapobject, soapobject) { char *location, *uri = NULL; int location_len, uri_len = 0; @@ -1182,26 +1329,7 @@ PHP_FUNCTION(soapobject) } } -PHP_FUNCTION(__headerclass) -{ - char *classname, *ns; - int classname_len, ns_len; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &classname, &classname_len, &ns, &ns_len) == FAILURE) - php_error(E_ERROR, "Invalid arguments to SoapObject->__headerclass"); -} - -PHP_FUNCTION(__headerfunction) -{ - char *functionname, *headername, *ns; - int functionname_len, *headername_len, ns_len; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &functionname, &functionname_len, &headername, - &headername_len, &ns, &ns_len) == FAILURE) - php_error(E_ERROR, "Invalid arguments to SoapObject->__headerfunction"); -} - -PHP_FUNCTION(__use) +PHP_METHOD(soapobject, __use) { int use; zval *thisObj; @@ -1211,7 +1339,7 @@ PHP_FUNCTION(__use) if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &use) == FAILURE) php_error(E_ERROR, "Invalid arguments to SoapObject->__use"); - if(use == SOAP_DOCUMENT || use == SOAP_LITERAL) + if(use == SOAP_ENCODED || use == SOAP_LITERAL) { add_property_long(thisObj, "use", use); RETURN_TRUE; @@ -1219,7 +1347,7 @@ PHP_FUNCTION(__use) RETURN_FALSE; } -PHP_FUNCTION(__style) +PHP_METHOD(soapobject, __style) { int style; zval *thisObj; @@ -1237,7 +1365,7 @@ PHP_FUNCTION(__style) RETURN_FALSE; } -PHP_FUNCTION(__trace) +PHP_METHOD(soapobject, __trace) { int level; zval *thisObj; @@ -1251,113 +1379,113 @@ PHP_FUNCTION(__trace) RETURN_TRUE; } -PHP_FUNCTION(__generate) +static void do_soap_call(zval* thisObj, + char* function, + int function_len, + int arg_count, + zval** real_args, + zval* return_value) { - char *function, *soap_action, *uri; - int function_len, soap_action_len, uri_len, i = 0; - zval *args; - zval **real_args; - zval **param; + zval **tmp; + zval **trace; + sdlPtr sdl = NULL; + sdlFunctionPtr fn; xmlDocPtr request = NULL; - int arg_count; - xmlChar *buf; - int size; - sdlPtr sdl; - - HashPosition pos; - - FETCH_THIS_SDL(sdl); - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|ss", - &function, &function_len, &args, &soap_action, &soap_action_len, &uri, &uri_len) == FAILURE) - php_error(E_ERROR, "Invalid arguments to SoapObject->__generate"); - - arg_count = zend_hash_num_elements(Z_ARRVAL_P(args)); - - real_args = emalloc(sizeof(zval *) * arg_count); - for(zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args), &pos); - zend_hash_get_current_data_ex(Z_ARRVAL_P(args), (void **) ¶m, &pos) == SUCCESS; - zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos)) - { - zval_add_ref(param); - real_args[i++] = *param; - } - - - if(sdl) - { - sdlBindingPtr binding; - sdlFunctionPtr sdlFunction; - FETCH_THIS_PORT(binding); - - php_strtolower(function, function_len); - sdlFunction = get_function(binding, function); - request = seralize_function_call(this_ptr, sdlFunction, NULL, uri, real_args, arg_count TSRMLS_CC); - } - else - { - request = seralize_function_call(this_ptr, NULL, function, uri, real_args, arg_count TSRMLS_CC); - } - - xmlDocDumpMemory(request, &buf, &size); - ZVAL_STRINGL(return_value, buf, size, 1); - xmlFree(buf); -} - -PHP_FUNCTION(__parse) -{ - char *message, *function; - int message_len, function_len; - int num_params; - zval **ret_params = NULL; - sdlPtr sdl; - sdlFunctionPtr fn; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &message, &message_len, &function, &function_len) == FAILURE) { - php_error(E_ERROR, "Invalid arguments to SoapObject->__parse"); - } - - FETCH_THIS_SDL(sdl); - - if (sdl != NULL) { - sdlBindingPtr binding; - - FETCH_THIS_PORT(binding); - fn = get_function(binding, function); - - if (fn != NULL) { - parse_packet_soap(getThis(), message, message_len, fn, NULL, &ret_params, &num_params TSRMLS_CC); + char *buffer; + int len; + int ret = FALSE; + + if(zend_hash_find(Z_OBJPROP_P(thisObj), "trace", sizeof("trace"), (void **) &trace) == SUCCESS + && Z_LVAL_PP(trace) > 0) { + zend_hash_del(Z_OBJPROP_P(thisObj), "__last_request", sizeof("__last_request")); + zend_hash_del(Z_OBJPROP_P(thisObj), "__last_response", sizeof("__last_response")); + } + + if (FIND_SDL_PROPERTY(thisObj,tmp) != FAILURE) { + FETCH_SDL_RES(sdl,tmp); + } + + clear_soap_fault(thisObj); + +zend_try { + SOAP_GLOBAL(sdl) = sdl; + if (sdl != NULL) { + sdlBindingPtr binding; + + zval* this_ptr = thisObj; + FETCH_THIS_PORT(binding); + + php_strtolower(function, function_len); + fn = get_function(binding, function); + if(fn != NULL) { + if(binding->bindingType == BINDING_SOAP) { + sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes; + request = seralize_function_call(thisObj, fn, NULL, fnb->input.ns, real_args, arg_count TSRMLS_CC); + ret = send_http_soap_request(thisObj, request, fnb->soapAction TSRMLS_CC); + } else { + request = seralize_function_call(thisObj, fn, NULL, sdl->target_ns, real_args, arg_count TSRMLS_CC); + ret = send_http_soap_request(thisObj, request, NULL TSRMLS_CC); + } + + xmlFreeDoc(request); + + if (ret) { + ret = get_http_soap_response(thisObj, &buffer, &len TSRMLS_CC); + if (ret) { + parse_packet_soap(thisObj, buffer, len, fn, NULL, return_value TSRMLS_CC); + efree(buffer); + } + } + } else { + php_error(E_WARNING,"Function (\"%s\") not is not a valid method for this service", function); + } + } else { + zval **uri; + smart_str *action; + + if(zend_hash_find(Z_OBJPROP_P(thisObj), "uri", sizeof("uri"), (void *)&uri) == FAILURE) + php_error(E_ERROR, "Error finding uri in soap_call_function_handler"); + + request = seralize_function_call(thisObj, NULL, function, Z_STRVAL_PP(uri), real_args, arg_count TSRMLS_CC); + action = build_soap_action(thisObj, function); + ret = send_http_soap_request(thisObj, request, action->c TSRMLS_CC); + + smart_str_free(action); + efree(action); + xmlFreeDoc(request); + + if (ret) { + ret = get_http_soap_response(thisObj, &buffer, &len TSRMLS_CC); + if (ret) { + ret = parse_packet_soap(thisObj, buffer, len, NULL, function, return_value TSRMLS_CC); + efree(buffer); + } + } + } + } zend_catch { + ret = FALSE; + } zend_end_try(); + if (!ret) { + zval** fault; + if(zend_hash_find(Z_OBJPROP_P(thisObj), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) { + *return_value = **fault; + } else { + *return_value = *add_soap_fault(thisObj, "SOAP-ENV:Client", "Unknown Error", NULL, NULL TSRMLS_CC); } - } else { - parse_packet_soap(getThis(), message, message_len, NULL, function, &ret_params, &num_params TSRMLS_CC); - } - - if (num_params > 0) { - *return_value = *ret_params[0]; - /* zval_add_ref(&return_value); */ - } else { - ZVAL_NULL(return_value); - } - - if (ret_params) { - FREE_ZVAL(ret_params[0]); - efree(ret_params); } + SOAP_GLOBAL(sdl) = NULL; } -PHP_FUNCTION(__call) +PHP_METHOD(soapobject, __call) { char *function, *soap_action, *uri; int function_len, soap_action_len, uri_len, i = 0; zval *args; zval **real_args; zval **param; - xmlDocPtr request = NULL; - int num_params, arg_count; - zval **ret_params = NULL; - char *buffer; - int len; - + int arg_count; + zval *thisObj; + HashPosition pos; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|ss", @@ -1371,32 +1499,16 @@ PHP_FUNCTION(__call) zend_hash_get_current_data_ex(Z_ARRVAL_P(args), (void **) ¶m, &pos) == SUCCESS; zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos)) { - zval_add_ref(param); + /*zval_add_ref(param);*/ real_args[i++] = *param; } + GET_THIS_OBJECT(thisObj); + do_soap_call(thisObj, function, function_len, arg_count, real_args, return_value TSRMLS_CC); - request = seralize_function_call(this_ptr, NULL, function, uri, real_args, arg_count TSRMLS_CC); - send_http_soap_request(getThis(), request, function, soap_action TSRMLS_CC); - xmlFreeDoc(request); - - get_http_soap_response(getThis(), &buffer, &len TSRMLS_CC); - parse_packet_soap(getThis(), buffer, len, NULL, function, &ret_params, &num_params TSRMLS_CC); - efree(buffer); - - if(num_params > 0) { - *return_value = *ret_params[0]; - /* zval_add_ref(&return_value); */ - } else { - ZVAL_NULL(return_value); - } - - if (ret_params) { - FREE_ZVAL(ret_params[0]); - efree(ret_params); - } + efree(real_args); } -PHP_FUNCTION(__isfault) +PHP_METHOD(soapobject, __isfault) { zval *thisObj; @@ -1408,7 +1520,7 @@ PHP_FUNCTION(__isfault) RETURN_FALSE } -PHP_FUNCTION(__getfault) +PHP_METHOD(soapobject, __getfault) { zval *thisObj; zval **tmp; @@ -1424,7 +1536,7 @@ PHP_FUNCTION(__getfault) RETURN_NULL(); } -PHP_FUNCTION(__getfunctions) +PHP_METHOD(soapobject, __getfunctions) { sdlPtr sdl; zval *thisObj; @@ -1439,7 +1551,7 @@ PHP_FUNCTION(__getfunctions) smart_str buf = {0}; sdlFunctionPtr *function; sdlBindingPtr binding; - + FETCH_THIS_PORT(binding); array_init(return_value); @@ -1454,7 +1566,7 @@ PHP_FUNCTION(__getfunctions) } } -PHP_FUNCTION(__gettypes) +PHP_METHOD(soapobject, __gettypes) { sdlPtr sdl; zval *thisObj; @@ -1484,7 +1596,7 @@ PHP_FUNCTION(__gettypes) } } -PHP_FUNCTION(__getlastrequest) +PHP_METHOD(soapobject, __getlastrequest) { zval *thisObj; zval **tmp; @@ -1498,7 +1610,7 @@ PHP_FUNCTION(__getlastrequest) RETURN_NULL(); } -PHP_FUNCTION(__getlastresponse) +PHP_METHOD(soapobject, __getlastresponse) { zval *thisObj; zval **tmp; @@ -1512,6 +1624,7 @@ PHP_FUNCTION(__getlastresponse) RETURN_NULL(); } +#ifndef ZEND_ENGINE_2 void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference) { pval *object = property_reference->object; @@ -1522,7 +1635,7 @@ void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_refe GET_THIS_OBJECT(thisObj); - /* + /* Find if the function being called is already defined... ( IMHO: zend should handle this functionality ) */ @@ -1532,107 +1645,16 @@ void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_refe } else { - zval **arguments = (zval **) emalloc(sizeof(zval *) * ZEND_NUM_ARGS()); int arg_count = ZEND_NUM_ARGS(); - xmlDocPtr request = NULL; - sdlPtr sdl; - sdlFunctionPtr fn; + zval **arguments = (zval **) emalloc(sizeof(zval *) * arg_count); zend_get_parameters_array(ht, arg_count, arguments); - - FETCH_THIS_SDL(sdl); - - clear_soap_fault(thisObj); - - if (sdl != NULL) { - sdlBindingPtr binding; - - FETCH_THIS_PORT(binding); - fn = get_function(binding, function); - if(fn != NULL) - { - int num_params; - zval **ret_params = NULL; - char *buffer; - char *ns; - int len; - - if(binding->bindingType == BINDING_SOAP) - { - sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes; - request = seralize_function_call(this_ptr, fn, NULL, fnb->input.ns, arguments, arg_count TSRMLS_CC); - send_http_soap_request(getThis(), request, fn->functionName, fnb->soapAction TSRMLS_CC); - } - else - { - request = seralize_function_call(this_ptr, fn, NULL, sdl->target_ns, arguments, arg_count TSRMLS_CC); - send_http_soap_request(getThis(), request, fn->functionName, NULL TSRMLS_CC); - } - - xmlFreeDoc(request); - - get_http_soap_response(getThis(), &buffer, &len TSRMLS_CC); - parse_packet_soap(getThis(), buffer, len, fn, NULL, &ret_params, &num_params TSRMLS_CC); - efree(buffer); - - if(num_params > 0) { - *return_value = *ret_params[0]; - /* zval_add_ref(&return_value); */ - } else { - ZVAL_NULL(return_value); - } - - if (ret_params) { - FREE_ZVAL(ret_params[0]); - efree(ret_params); - } - } - else - { - php_error(E_WARNING,"Function (\"%s\") not is not a valid method for this service", function); - } - } - else - { - int num_params; - zval **ret_params = NULL; - zval **uri; - smart_str *action; - char *buffer; - int len; - - if(zend_hash_find(Z_OBJPROP_P(thisObj), "uri", sizeof("uri"), (void *)&uri) == FAILURE) - php_error(E_ERROR, "Error finding uri in soap_call_function_handler"); - - request = seralize_function_call(this_ptr, NULL, function, Z_STRVAL_PP(uri), arguments, arg_count TSRMLS_CC); - action = build_soap_action(thisObj, function); - send_http_soap_request(getThis(), request, function, action->c TSRMLS_CC); - - smart_str_free(action); - efree(action); - xmlFreeDoc(request); - - get_http_soap_response(getThis(), &buffer, &len TSRMLS_CC); - parse_packet_soap(getThis(), buffer, len, NULL, function, &ret_params, &num_params TSRMLS_CC); - efree(buffer); - - if(num_params > 0) { - *return_value = *ret_params[0]; - /* zval_add_ref(&return_value); */ - } else { - ZVAL_NULL(return_value); - } - - if (ret_params) { - FREE_ZVAL(ret_params[0]); - efree(ret_params); - } - } + do_soap_call(thisObj, function, Z_STRLEN(function_name->element) + 1, arg_count, arguments, return_value TSRMLS_CC); efree(arguments); } - zval_dtor(&function_name->element); } +#endif void clear_soap_fault(zval *obj) { @@ -1642,18 +1664,19 @@ void clear_soap_fault(zval *obj) } } -void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC) +zval* add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC) { zval *fault; MAKE_STD_ZVAL(fault); set_soap_fault(fault, fault_string, fault_code, fault_actor, fault_detail TSRMLS_CC); add_property_zval(obj, "__soap_fault", fault); + return fault; } void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC) { if(Z_TYPE_P(obj) != IS_OBJECT) - object_init_ex(obj, &soap_fault_class_entry); + object_init_ex(obj, soap_fault_class_entry); if(fault_string != NULL) add_property_string(obj, "faultstring", fault_string, 1); @@ -1666,7 +1689,9 @@ void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault if(fault_detail != NULL) { +#ifndef ZEND_ENGINE_2 zval_add_ref(&fault_detail); +#endif add_property_zval(obj, "detail", fault_detail); } } @@ -1676,6 +1701,7 @@ void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *function_name xmlNodePtr trav,trav2,trav3,trav4,env,body; int cur_param = 0,num_of_params = 0; + ZVAL_EMPTY_STRING(function_name); trav = request->children; FOREACHNODE(trav,"Envelope",env) { @@ -1731,7 +1757,6 @@ void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *function_name enc = get_conversion(UNKNOWN_TYPE); else enc = (*param)->encode; - tmp_parameters[cur_param] = master_to_zval(enc, trav4); cur_param++; } @@ -1757,6 +1782,7 @@ xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name, c xmlNs *ns; sdlParamPtr parameter = NULL; smart_str *gen_ns = NULL; + int param_count; encode_reset_ns(); @@ -1766,7 +1792,10 @@ xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name, c doc->children = xmlNewDocNode(doc, NULL, "SOAP-ENV:Envelope", NULL); envelope = doc->children; + /*TODO: if use="literal" SOAP-ENV:encodingStyle is not need */ +//???if($style == 'rpc' && $use == 'encoded') { xmlSetProp(envelope, "SOAP-ENV:encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/"); +//???} xmlSetProp(envelope, "xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"); xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); @@ -1776,7 +1805,7 @@ xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name, c body = xmlNewChild(envelope, ns, "Body", NULL); if(Z_TYPE_P(ret) == IS_OBJECT && - Z_OBJCE_P(ret)->refcount == soap_fault_class_entry.refcount) + Z_OBJCE_P(ret) == soap_fault_class_entry) { param = seralize_zval(ret, NULL, "SOAP-ENV:Fault", SOAP_ENCODED TSRMLS_CC); xmlAddChild(body, param); @@ -1794,31 +1823,45 @@ xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name, c if(uri) ns = xmlNewNs(method, uri, NULL); - parameter = get_param(function, NULL, 0, TRUE); - - if(Z_TYPE_P(ret) == IS_OBJECT && - Z_OBJCE_P(ret)->refcount == soap_param_class_entry.refcount) - { - zval **ret_name; - zval **ret_data; - - if(zend_hash_find(Z_OBJPROP_P(ret), "param_name", sizeof("param_name"), (void **)&ret_name) == SUCCESS && - zend_hash_find(Z_OBJPROP_P(ret), "param_data", sizeof("param_data"), (void **)&ret_data) == SUCCESS) - param = seralize_parameter(parameter, *ret_data, 0, Z_STRVAL_PP(ret_name), SOAP_ENCODED TSRMLS_CC); - else - param = seralize_parameter(parameter, ret, 0, "return", SOAP_ENCODED TSRMLS_CC); + if (function != NULL) { + param_count = zend_hash_num_elements(function->responseParameters); + } else { + param_count = 1; } - else + if (param_count == 1) { + parameter = get_param(function, NULL, 0, TRUE); + param = seralize_parameter(parameter, ret, 0, "return", SOAP_ENCODED TSRMLS_CC); + xmlAddChild(method,param); + } else if (param_count > 1 && Z_TYPE_P(ret) == IS_ARRAY) { + HashPosition pos; + zval **data; + int i = 0; + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ret), &pos); + while(zend_hash_get_current_data_ex(Z_ARRVAL_P(ret), (void **)&data, &pos) != FAILURE) + { + char *param_name; + int param_name_len; + long param_index; - xmlAddChild(method,param); + zend_hash_get_current_key_ex(Z_ARRVAL_P(ret), ¶m_name, ¶m_name_len, ¶m_index, 0, &pos); + parameter = get_param(function, param_name, param_index, TRUE); + + param = seralize_parameter(parameter, *data, i, param_name, SOAP_ENCODED TSRMLS_CC); + xmlAddChild(method,param); + + zend_hash_move_forward_ex(Z_ARRVAL_P(ret), &pos); + i++; + } + } } if (gen_ns) { smart_str_free(gen_ns); efree(gen_ns); } - + return doc; } @@ -1826,7 +1869,7 @@ xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, char * { xmlDoc *doc; xmlNode *envelope, *body, *method; - xmlNs *ns, *tmpns; + xmlNs *ns; zval **zstyle, **zuse; int i, style, use; smart_str *gen_ns; @@ -1842,7 +1885,7 @@ xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, char * xmlSetProp(envelope, "xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"); xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - + ns = xmlNewNs(envelope, "http://schemas.xmlsoap.org/soap/envelope/", "SOAP-ENV"); body = xmlNewChild(envelope, ns, "Body", NULL); @@ -1876,10 +1919,15 @@ xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, char * method = xmlNewChild(body, ns, function_name, NULL); } - if(zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS) - use = Z_LVAL_PP(zuse); - else + if(zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS) { + if (Z_LVAL_PP(zuse) == SOAP_LITERAL) { + use = SOAP_LITERAL; + } else { + use = SOAP_ENCODED; + } + } else { use = SOAP_ENCODED; + } } for(i = 0;i < arg_count;i++) @@ -1887,25 +1935,11 @@ xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, char * xmlNodePtr param; sdlParamPtr parameter = get_param(function, NULL, i, FALSE); - if(Z_TYPE_P(arguments[i]) == IS_OBJECT && - Z_OBJCE_P(arguments[i])->refcount == soap_param_class_entry.refcount) - { - zval **ret_name; - zval **ret_data; - - if(zend_hash_find(Z_OBJPROP_P(arguments[i]), "param_name", sizeof("param_name"), (void **)&ret_name) == SUCCESS && - zend_hash_find(Z_OBJPROP_P(arguments[i]), "param_data", sizeof("param_data"), (void **)&ret_data) == SUCCESS) - param = seralize_parameter(parameter, *ret_data, i, Z_STRVAL_PP(ret_name), use TSRMLS_CC); - else - param = seralize_parameter(parameter, arguments[i], i, NULL, use TSRMLS_CC); - } - else - param = seralize_parameter(parameter, arguments[i], i, NULL, use TSRMLS_CC); + param = seralize_parameter(parameter, arguments[i], i, NULL, use TSRMLS_CC); - if(style == SOAP_RPC) + if (style == SOAP_RPC) { xmlAddChild(method, param); - else if(style == SOAP_DOCUMENT) - { + } else if (style == SOAP_DOCUMENT) { if(function && function->bindingType == BINDING_SOAP) { sdlParamPtr *sparam; @@ -1928,10 +1962,21 @@ xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, char * xmlNodePtr seralize_parameter(sdlParamPtr param, zval *param_val, int index, char *name, int style TSRMLS_DC) { - int type = 0; char *paramName; xmlNodePtr xmlParam; + if(Z_TYPE_P(param_val) == IS_OBJECT && + Z_OBJCE_P(param_val) == soap_param_class_entry) { + zval **param_name; + zval **param_data; + + if(zend_hash_find(Z_OBJPROP_P(param_val), "param_name", sizeof("param_name"), (void **)¶m_name) == SUCCESS && + zend_hash_find(Z_OBJPROP_P(param_val), "param_data", sizeof("param_data"), (void **)¶m_data) == SUCCESS) { + param_val = *param_data; + name = Z_STRVAL_PP(param_name); + } + } + if(param != NULL && param->paramName != NULL) paramName = estrdup(param->paramName); else @@ -1952,18 +1997,6 @@ xmlNodePtr seralize_parameter(sdlParamPtr param, zval *param_val, int index, cha return xmlParam; } -zval *desearlize_zval(sdlPtr sdl, xmlNodePtr data, sdlParamPtr param TSRMLS_DC) -{ - encodePtr enc; - - if(param != NULL) - enc = param->encode; - else - enc = get_conversion(UNKNOWN_TYPE); - - return enc->to_zval(enc->details, data); -} - xmlNodePtr seralize_zval(zval *val, sdlParamPtr param, char *paramName, int style TSRMLS_DC) { xmlNodePtr xmlParam; @@ -1983,35 +2016,39 @@ xmlNodePtr seralize_zval(zval *val, sdlParamPtr param, char *paramName, int styl sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int response) { - sdlParamPtr *tmp = NULL; - HashTable *h; + sdlParamPtr *tmp; + HashTable *ht; - if(function == NULL) + if(function == NULL) { return NULL; + } - if(response == FALSE) - h = function->requestParameters; - else - h = function->responseParameters; - - if (function != NULL && (param_name == NULL || zend_hash_find(h, param_name, strlen(param_name), (void **)&tmp) == FAILURE)) - { - if(index != -1) - if(zend_hash_index_find(h, index, (void **)&tmp) != FAILURE) - return (*tmp); + if(response == FALSE) { + ht = function->requestParameters; + } else { + ht = function->responseParameters; } - else - return (*tmp); + if (param_name != NULL) { + if (zend_hash_find(ht, param_name, strlen(param_name), (void **)&tmp) != FAILURE) { + return *tmp; + } + } else { + if(zend_hash_index_find(ht, index, (void **)&tmp) != FAILURE) { + return (*tmp); + } + } return NULL; } sdlFunctionPtr get_function(sdlBindingPtr sdl, char *function_name) { sdlFunctionPtr *tmp; - if(sdl != NULL) - if(zend_hash_find(sdl->functions, function_name, strlen(function_name), (void **)&tmp) != FAILURE) + if(sdl != NULL) { + if (zend_hash_find(sdl->functions, function_name, strlen(function_name), (void **)&tmp) != FAILURE) { return (*tmp); + } + } return NULL; } @@ -2020,7 +2057,7 @@ static void function_to_string(sdlFunctionPtr function, smart_str *buf) int i = 0; HashPosition pos; - if(function->responseParameters) + if(function->responseParameters && function->responseParameters->pListHead) { sdlParamPtr *param; param = function->responseParameters->pListHead->pData; @@ -2064,6 +2101,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) smart_str_appendc(&spaces, ' '); smart_str_appendl(buf, spaces.c, spaces.len); + if(type->elements) { sdlTypePtr *t_type; @@ -2092,6 +2130,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) smart_str_appendl(buf, type->name, strlen(type->name)); smart_str_appendl(buf, ";\n", 2); } + smart_str_free(&spaces); } /* Deletes */ @@ -2255,55 +2294,3 @@ void delete_mapping(void *data) } efree(map); } - -/* Should not need */ -#ifndef ZEND_ENGINE_2 -int my_call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, int param_count, zval *params[] TSRMLS_DC) -{ - if(call_user_function(function_table, object_pp, function_name, retval_ptr, param_count, params TSRMLS_CC) == FAILURE) - { - if(Z_OBJCE_PP(object_pp)->handle_function_call != NULL) - { - zend_overloaded_element overloaded_element; - zend_property_reference property_reference; - zend_function_state function_state; - zend_function_state *original_function_state_ptr; - int i; - - overloaded_element.element = *function_name; - overloaded_element.type = OE_IS_METHOD; - - function_state.function = (zend_function *) emalloc(sizeof(zend_function)); - function_state.function->type = ZEND_OVERLOADED_FUNCTION; - function_state.function->common.arg_types = NULL; - function_state.function->overloaded_function.function_name = Z_STRVAL_P(function_name); - - property_reference.object = *object_pp; - property_reference.type = BP_VAR_NA; - property_reference.elements_list = (zend_llist *)emalloc(sizeof(zend_llist)); - zend_llist_init(property_reference.elements_list, sizeof(zend_overloaded_element), NULL, 0); - zend_llist_add_element(property_reference.elements_list, &overloaded_element); - - /* Build argument stack */ - for(i = 0;i < param_count;i++) - zend_ptr_stack_push(&EG(argument_stack), params[i]); - zend_ptr_stack_n_push(&EG(argument_stack), 2, (void *)param_count, NULL); - - original_function_state_ptr = EG(function_state_ptr); - EG(function_state_ptr) = &function_state; - Z_OBJCE_PP(object_pp)->handle_function_call(param_count, retval_ptr, *object_pp, 1 TSRMLS_CC, &property_reference); - EG(function_state_ptr) = original_function_state_ptr; - - zend_llist_destroy(property_reference.elements_list); - efree(property_reference.elements_list); - efree(function_state.function); - - zend_ptr_stack_clear_multiple(TSRMLS_C); - return SUCCESS; - } - } - return FAILURE; -} -#endif - - diff --git a/ext/soap/tests/server001.phpt b/ext/soap/tests/server001.phpt new file mode 100644 index 0000000000..7c5facaa0e --- /dev/null +++ b/ext/soap/tests/server001.phpt @@ -0,0 +1,33 @@ +--TEST-- +SOAP Server 1: new/addfunction/handle +--SKIPIF-- + +--FILE-- +addfunction("test"); + +$HTTP_RAW_POST_DATA = << + + + + + +EOF; +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +Hello World +ok diff --git a/ext/soap/tests/server002.phpt b/ext/soap/tests/server002.phpt new file mode 100644 index 0000000000..0ead0380ab --- /dev/null +++ b/ext/soap/tests/server002.phpt @@ -0,0 +1,37 @@ +--TEST-- +SOAP Server 2: function with parameters and result +--SKIPIF-- + +--FILE-- +addfunction("Add"); + +$HTTP_RAW_POST_DATA = << + + + + 22 + 33 + + + +EOF; + +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +55 +ok diff --git a/ext/soap/tests/server003.phpt b/ext/soap/tests/server003.phpt new file mode 100644 index 0000000000..5f4839162d --- /dev/null +++ b/ext/soap/tests/server003.phpt @@ -0,0 +1,32 @@ +--TEST-- +SOAP Server 3: all functions +--SKIPIF-- + +--FILE-- +addfunction(SOAP_FUNCTIONS_ALL); + +$HTTP_RAW_POST_DATA = << + + + + Hello World + + + +EOF; + +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +11 +ok diff --git a/ext/soap/tests/server004.phpt b/ext/soap/tests/server004.phpt new file mode 100644 index 0000000000..cfb5bdeb84 --- /dev/null +++ b/ext/soap/tests/server004.phpt @@ -0,0 +1,40 @@ +--TEST-- +SOAP Server 4: addfunctions +--SKIPIF-- + +--FILE-- +addfunction(array("Sub","Add")); + +$HTTP_RAW_POST_DATA = << + + + + 22 + 33 + + + +EOF; + +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +55 +ok diff --git a/ext/soap/tests/server005.phpt b/ext/soap/tests/server005.phpt new file mode 100644 index 0000000000..6116f82038 --- /dev/null +++ b/ext/soap/tests/server005.phpt @@ -0,0 +1,36 @@ +--TEST-- +SOAP Server 5: setclass +--SKIPIF-- + +--FILE-- +setclass("Foo"); + +$HTTP_RAW_POST_DATA = << + + + + + +EOF; + +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +Hello World +ok diff --git a/ext/soap/tests/server006.phpt b/ext/soap/tests/server006.phpt new file mode 100644 index 0000000000..2987a434f8 --- /dev/null +++ b/ext/soap/tests/server006.phpt @@ -0,0 +1,42 @@ +--TEST-- +SOAP Server 6: setclass with constructor +--SKIPIF-- + +--FILE-- +str = $str . " World"; + } + + function test() { + return $this->str; + } +} + +$server = new soapserver("http://testuri.org"); +$server->setclass("Foo","Hello"); + +$HTTP_RAW_POST_DATA = << + + + + + +EOF; + +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +Hello World +ok diff --git a/ext/soap/tests/server007.phpt b/ext/soap/tests/server007.phpt new file mode 100644 index 0000000000..113ddac4a3 --- /dev/null +++ b/ext/soap/tests/server007.phpt @@ -0,0 +1,26 @@ +--TEST-- +SOAP Server 7: addfunction and getfunctions +--SKIPIF-- + +--FILE-- +addfunction(array("Sub","Add")); +var_dump($server->getfunctions()); +echo "ok\n"; +?> +--EXPECT-- +array(2) { + [0]=> + string(3) "Sub" + [1]=> + string(3) "Add" +} +ok diff --git a/ext/soap/tests/server008.phpt b/ext/soap/tests/server008.phpt new file mode 100644 index 0000000000..73f91f3891 --- /dev/null +++ b/ext/soap/tests/server008.phpt @@ -0,0 +1,29 @@ +--TEST-- +SOAP Server 8: setclass and getfunctions +--SKIPIF-- + +--FILE-- +str; + } +} + +$server = new soapserver("http://testuri.org"); +$server->setclass("Foo"); +var_dump($server->getfunctions()); +echo "ok\n"; +?> +--EXPECT-- +array(2) { + [0]=> + string(3) "Foo" + [1]=> + string(4) "test" +} +ok diff --git a/ext/soap/tests/server009.phpt b/ext/soap/tests/server009.phpt new file mode 100644 index 0000000000..3082965d82 --- /dev/null +++ b/ext/soap/tests/server009.phpt @@ -0,0 +1,61 @@ +--TEST-- +SOAP Server 9: setclass and setpersistence(SOAP_PERSISTENCE_SESSION) +--SKIPIF-- + +--FILE-- +sum += $num; + } +} + +$server = new soapserver("http://testuri.org"); +$server->setclass("foo"); +$server->setpersistence(SOAP_PERSISTENCE_SESSION); + +ob_start(); +$HTTP_RAW_POST_DATA = << + + + + 5 + + + +EOF; +$server->handle(); +ob_clean(); + +$HTTP_RAW_POST_DATA = << + + + + 3 + + + +EOF; +$server->handle(); +ob_end_flush(); + +echo "ok\n"; +?> +--EXPECT-- + +8 +ok diff --git a/ext/soap/tests/server010.phpt b/ext/soap/tests/server010.phpt new file mode 100644 index 0000000000..9cea4f8a6e --- /dev/null +++ b/ext/soap/tests/server010.phpt @@ -0,0 +1,61 @@ +--TEST-- +SOAP Server 10: setclass and setpersistence(SOAP_PERSISTENCE_REQUEST) +--SKIPIF-- + +--FILE-- +sum += $num; + } +} + +$server = new soapserver("http://testuri.org"); +$server->setclass("foo"); +$server->setpersistence(SOAP_PERSISTENCE_REQUEST); + + +ob_start(); +$HTTP_RAW_POST_DATA = << + + + + 5 + + + +EOF; +$server->handle(); +ob_clean(); + +$HTTP_RAW_POST_DATA = << + + + + 3 + + + +EOF; +$server->handle(); +ob_end_flush(); +echo "ok\n"; +?> +--EXPECT-- + +3 +ok diff --git a/ext/soap/tests/server011.phpt b/ext/soap/tests/server011.phpt new file mode 100644 index 0000000000..602ce6ccb3 --- /dev/null +++ b/ext/soap/tests/server011.phpt @@ -0,0 +1,26 @@ +--TEST-- +SOAP Server 11: bind +--SKIPIF-- + +--GET-- +wsdl +--FILE-- +bind("test.wsdl"); +ob_start(); +$server->handle(); +$wsdl = ob_get_contents(); +ob_end_clean(); +if ($wsdl == file_get_contents("test.wsdl")) { + echo "ok\n"; +} else { + echo "fail\n"; +} +?> +--EXPECT-- +ok diff --git a/ext/soap/tests/server012.phpt b/ext/soap/tests/server012.phpt new file mode 100644 index 0000000000..bffcae0db5 --- /dev/null +++ b/ext/soap/tests/server012.phpt @@ -0,0 +1,18 @@ +--TEST-- +SOAP Server 12: WSDL generation +--SKIPIF-- + +--GET-- +WSDL +--FILE-- +addfunction("Add"); +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- diff --git a/ext/soap/tests/server013.phpt b/ext/soap/tests/server013.phpt new file mode 100644 index 0000000000..454114eb83 --- /dev/null +++ b/ext/soap/tests/server013.phpt @@ -0,0 +1,44 @@ +--TEST-- +SOAP Server 13: array handling +--SKIPIF-- + +--FILE-- +addfunction("Sum"); + +$HTTP_RAW_POST_DATA = << + + + + + 3 + 5 + + + + +EOF; +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +8 +ok diff --git a/ext/soap/tests/server014.phpt b/ext/soap/tests/server014.phpt new file mode 100644 index 0000000000..8e155f9e73 --- /dev/null +++ b/ext/soap/tests/server014.phpt @@ -0,0 +1,37 @@ +--TEST-- +SOAP Server 14: fault +--SKIPIF-- + +--FILE-- +addfunction("Add"); + +$HTTP_RAW_POST_DATA = << + + + + 22 + 33 + + + +EOF; + +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +Call to undefined function undefined_function_x()SOAP-ENV:Server diff --git a/ext/soap/tests/skipif.inc b/ext/soap/tests/skipif.inc new file mode 100644 index 0000000000..fa8574e6a2 --- /dev/null +++ b/ext/soap/tests/skipif.inc @@ -0,0 +1,3 @@ + diff --git a/ext/soap/tests/test.wsdl b/ext/soap/tests/test.wsdl new file mode 100644 index 0000000000..0740b7db62 --- /dev/null +++ b/ext/soap/tests/test.wsdl @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.40.0
Endpoint