cvs: pear /SOAP Base.php Client.php Disco.php Parser.php Server.php Transport.php WSDL.php package.xml /SOAP/Server Email.php /SOAP/Transport
HTTP.php /SOAP/example client.php disco_server.php server.php
| From: | Shane Caraveo | Date: | Fri, 04 Apr 2003 08:29:17 +0000 |
| Subject: | cvs: pear /SOAP Base.php Client.php Disco.php Parser.php Server.php Transport.php WSDL.php package.xml /SOAP/Server Email.php /SOAP/Transport HTTP.php /SOAP/example client.php disco_server.php server.php |
||
| Groups: | php.pear.cvs | ||
| Request: | Send a blank email to pear-cvs+get-9738@lists.php.net to get a copy of this message | ||
shane Fri Apr 4 03:29:17 2003 EDT
Added files:
/pear/SOAP Disco.php
/pear/SOAP/example disco_server.php
Modified files:
/pear/SOAP Base.php Client.php Parser.php Server.php Transport.php
WSDL.php package.xml
/pear/SOAP/Server Email.php
/pear/SOAP/Transport HTTP.php
/pear/SOAP/example client.php server.php
Log:
Add DISCO class from Dmitri Vinogradov
- provides generation of WSDL and DISCO files from class dispatch variables
New soap base class to hopefully lighten the load on objects that do not need
all the services of the existing base class.
Transport layer should support drop-in transport scripts (such as TCP transport)
Many patches from many people, thanks to (hope I don't miss anyone)
Dmitri Vinogradov
Brodie Thiesfield
Jonathon Schilling
Arnaud Limbourg
Carsten Bleek
Giuseppe Tanzilli
Patrick Bradley
Index: pear/SOAP/Base.php diff -u pear/SOAP/Base.php:1.29 pear/SOAP/Base.php:1.30 --- pear/SOAP/Base.php:1.29 Sat Jan 4 06:56:16 2003 +++ pear/SOAP/Base.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Base.php,v 1.29 2003/01/04 11:56:16 mj Exp $ +// $Id: Base.php,v 1.30 2003/04/04 08:29:16 shane Exp $ // /* @@ -54,8 +54,6 @@ $GLOBALS['SOAP_options']['DIME'] = 1; } -error_reporting(E_ALL); - /** * Enable debugging informations? * @@ -79,8 +77,8 @@ define('INF', 1.8e307); define('NAN', 0.0); -define('SOAP_LIBRARY_VERSION', '0.7.1'); -define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.7.1'); +define('SOAP_LIBRARY_VERSION', '0.7.2'); +define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.7.2-devel'); // set schema version define('SOAP_XML_SCHEMA_VERSION', 'http://www.w3.org/2001/XMLSchema'); define('SOAP_XML_SCHEMA_INSTANCE', 'http://www.w3.org/2001/XMLSchema-instance'); @@ -89,6 +87,9 @@ define('SOAP_SCHEMA_ENCODING', 'http://schemas.xmlsoap.org/soap/encoding/'); define('SOAP_ENVELOP', 'http://schemas.xmlsoap.org/soap/envelope/'); +define('SCHEMA_DISCO', 'http://schemas.xmlsoap.org/disco/'); +define('SCHEMA_DISCO_SCL', 'http://schemas.xmlsoap.org/disco/scl/'); + define('SCHEMA_SOAP', 'http://schemas.xmlsoap.org/wsdl/soap/'); define('SCHEMA_HTTP', 'http://schemas.xmlsoap.org/wsdl/http/'); define('SCHEMA_MIME', 'http://schemas.xmlsoap.org/wsdl/mime/'); @@ -108,16 +109,121 @@ } } +class SOAP_Base_Object extends PEAR +{ + /** + * Store debugging information in $debug_data? + * + * @var boolean if true debugging informations will be store in $debug_data + * @see $debug_data, SOAP_Base + */ + var $_debug_flag = false; + + /** + * String containing debugging informations if $debug_flag is set to true + * + * @var string debugging informations - mostyl error messages + * @see $debug_flag, SOAP_Base + * @access public + */ + var $_debug_data = ''; + + # supported encodings, limited by XML extension + var $_encodings = array('ISO-8859-1','US-ASCII','UTF-8'); + /** + * Fault code + * + * @var string + */ + var $_myfaultcode = ''; + + /** + * Recent PEAR error object + * + * @var object PEAR Error + */ + var $fault = NULL; + + /** + * Constructor + * + * @param string error code + * @see $debug_data, _debug() + */ + function SOAP_Base_Object($faultcode = 'Client') + { + $this->_myfaultcode = $faultcode; + $this->_debug_flag = $GLOBALS['SOAP_DEBUG']; + parent::PEAR('SOAP_Fault'); + } + + /** + * Raise a soap error + * + * Please referr to the SOAP definition for an impression of what a certain parameter + * stands for. + * + * Use $debug_flag to store errors to the member variable $debug_data + * + * @param string error message + * @param string detailed error message. + * @param string actor + * @param mixed + * @param mixed + * @param mixed + * @param boolean + * @see $debug_flag, $debug_data + */ + function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, $mode = null, $options = null, $skipmsg = false) + { + # pass through previous faults + if (is_object($str)) { + $this->fault = $str; + } else { + if (!$code) $code = $this->_myfaultcode; + $this->fault = new SOAP_Fault($str, + $code, + $actorURI, + $detail, + $mode, + $options); + } + return $this->fault; + } + + function __isfault() + { + return $this->fault != NULL; + } + + function &__getfault() + { + return $this->fault; + } + + /** + * maintains a string of debug data + * + * @param debugging message - sometimes an error message + */ + function _debug($string) + { + if ($this->_debug_flag) { + $this->_debug_data .= get_class($this) . ': ' . preg_replace("/>/", ">\r\n", $string) . "\n"; + } + } +} + /** * SOAP_Base * Common base class of all Soap lclasses * * @access public -* @version $Id: Base.php,v 1.29 2003/01/04 11:56:16 mj Exp $ +* @version $Id: Base.php,v 1.30 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates */ -class SOAP_Base extends PEAR +class SOAP_Base extends SOAP_Base_Object { var $_XMLSchema = array('http://www.w3.org/2001/XMLSchema', 'http://www.w3.org/1999/XMLSchema'); var $_XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; @@ -190,8 +296,6 @@ // load namespace uris into an array of uri => prefix var $_namespaces; var $_ns_count = 0; - # supported encodings, limited by XML extension - var $_encodings = array('ISO-8859-1','US-ASCII','UTF-8'); var $_xmlEntities = array ( '&' => '&', '<' => '<', '>' => '>', "'" => ''', '"' => '"' ); @@ -199,37 +303,6 @@ var $__attachments = array(); - /** - * Store debugging information in $debug_data? - * - * @var boolean if true debugging informations will be store in $debug_data - * @see $debug_data, SOAP_Base - */ - var $_debug_flag = false; - - /** - * String containing debugging informations if $debug_flag is set to true - * - * @var string debugging informations - mostyl error messages - * @see $debug_flag, SOAP_Base - * @access public - */ - var $_debug_data = ''; - - /** - * Fault code - * - * @var string - */ - var $_myfaultcode = ''; - - /** - * Recent PEAR error object - * - * @var object PEAR Error - */ - var $fault = NULL; - var $_wsdl = NULL; /** @@ -252,10 +325,8 @@ */ function SOAP_Base($faultcode = 'Client') { - $this->_myfaultcode = $faultcode; + parent::SOAP_Base_Object($faultcode); $this->_resetNamespaces(); - $this->_debug_flag = $GLOBALS['SOAP_DEBUG']; - parent::PEAR('SOAPfault'); } function _resetNamespaces() @@ -288,62 +359,6 @@ $this->_namespaces = array_flip($tmpNS); } - /** - * Raise a soap error - * - * Please referr to the SOAP definition for an impression of what a certain parameter - * stands for. - * - * Use $debug_flag to store errors to the member variable $debug_data - * - * @param string error message - * @param string detailed error message. - * @param string actor - * @param mixed - * @param mixed - * @param mixed - * @param boolean - * @see $debug_flag, $debug_data - */ - function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, $mode = null, $options = null, $skipmsg = false) - { - # pass through previous faults - if (is_object($str)) { - $this->fault = $str; - } else { - if (!$code) $code = $this->_myfaultcode; - $this->fault = new SOAP_Fault($str, - $code, - $actorURI, - $detail, - $mode, - $options); - } - return $this->fault; - } - - function __isfault() - { - return $this->fault != NULL; - } - - function &__getfault() - { - return $this->fault; - } - - /** - * maintains a string of debug data - * - * @param debugging message - sometimes an error message - */ - function _debug($string) - { - if ($this->_debug_flag) { - $this->_debug_data .= get_class($this) . ': ' . preg_replace("/>/", ">\r\n", $string) . "\n"; - } - } - function _getNamespacePrefix($ns) { if (array_key_exists($ns,$this->_namespaces)) { @@ -986,7 +1001,7 @@ * class used to handle QNAME values in XML * * @access public -* @version $Id: Base.php,v 1.29 2003/01/04 11:56:16 mj Exp $ +* @version $Id: Base.php,v 1.30 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates */ Index: pear/SOAP/Client.php diff -u pear/SOAP/Client.php:1.49 pear/SOAP/Client.php:1.50 --- pear/SOAP/Client.php:1.49 Mon Mar 24 17:12:40 2003 +++ pear/SOAP/Client.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Client.php,v 1.49 2003/03/24 22:12:40 arnaud Exp $ +// $Id: Client.php,v 1.50 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Value.php'; @@ -38,7 +38,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public - * @version $Id: Client.php,v 1.49 2003/03/24 22:12:40 arnaud Exp $ + * @version $Id: Client.php,v 1.50 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Stig Bakken <ssb@fast.no> Conversion to PEAR @@ -228,6 +228,8 @@ */ function call($method, $params = array(), $namespace = false, $soapAction = false) { + $this->__last_request = null; + $this->__last_response = null; $soap_data = $this->__generate($method, $params, $namespace, $soapAction); if (PEAR::isError($soap_data)) { return $this->_raiseSoapFault($soap_data); @@ -394,7 +396,7 @@ $part = $this->_wsdl->elements[$part['namespace']][$part['type']]; $name = $part['name']; } - if (isset($params[$name])) { + if (array_key_exists($name,$params)) { $nparams[$name] = $params[$name]; } else { # we now force an associative array for parameters if using wsdl @@ -555,7 +557,7 @@ function __get_wire() { - if ($this->__options['trace'] > 0) { + if ($this->__options['trace'] > 0 && ($this->__last_request || $this->__last_response)) { return "OUTGOING:\n\n". $this->__last_request. "\n\nINCOMING\n\n". Index: pear/SOAP/Parser.php diff -u pear/SOAP/Parser.php:1.28 pear/SOAP/Parser.php:1.29 --- pear/SOAP/Parser.php:1.28 Sat Jan 4 06:56:16 2003 +++ pear/SOAP/Parser.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Parser.php,v 1.28 2003/01/04 11:56:16 mj Exp $ +// $Id: Parser.php,v 1.29 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Base.php'; @@ -30,7 +30,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Parser.php,v 1.28 2003/01/04 11:56:16 mj Exp $ +* @version $Id: Parser.php,v 1.29 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Parser * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -81,10 +81,6 @@ if (preg_match('/<\?xml[^>]+encoding\s*?=\s*?(\'([^\']*)\'|"([^"]*)")[^>]*?[\?]>/',$xml,$m)) { $this->xml_encoding = strtoupper($m[2]?$m[2]:$m[3]); } - - # XXX need to do this better, remove newlines after > or before < - $this->xml = preg_replace("/>[\r\n]+/", '>', $this->xml); - $this->xml = preg_replace("/[\r\n]+</", '<', $this->xml); // determines where in the message we are (envelope,header,body,method) // Check whether content has been read. Index: pear/SOAP/Server.php diff -u pear/SOAP/Server.php:1.29 pear/SOAP/Server.php:1.30 --- pear/SOAP/Server.php:1.29 Sat Jan 4 06:56:18 2003 +++ pear/SOAP/Server.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Server.php,v 1.29 2003/01/04 11:56:18 mj Exp $ +// $Id: Server.php,v 1.30 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Base.php'; @@ -41,7 +41,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Server.php,v 1.29 2003/01/04 11:56:18 mj Exp $ +* @version $Id: Server.php,v 1.30 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -144,7 +144,7 @@ $useEncoding = 'Mime'; } if (!isset($headers['content-type'])) { - $headers['content-type'] = $_SERVER['CONTENT_TYPE']; + $headers['content-type'] = stripslashes($_SERVER['CONTENT_TYPE']); } if (!$this->fault && !$this->_getContentEncoding($headers['content-type'])) { @@ -158,7 +158,7 @@ if (!$this->fault && !$test && ($_SERVER['REQUEST_METHOD'] != 'POST' || strncmp($headers['content-type'],'text/xml',8) != 0)) { // this is not possibly a valid soap request, try to return a WSDL file - $this->_raiseSoapFault("Invalid SOAP request, must be POST with content-type: text/xml, got: {$headers['content-type']}",'','','Server'); + $this->_raiseSoapFault("Invalid SOAP request, must be POST with content-type: text/xml, got: ".(isset($headers['content-type'])?$headers['content-type']:'Nothing!'),'','','Server'); } if (!$this->fault) { Index: pear/SOAP/Transport.php diff -u pear/SOAP/Transport.php:1.18 pear/SOAP/Transport.php:1.19 --- pear/SOAP/Transport.php:1.18 Sat Jan 4 06:56:18 2003 +++ pear/SOAP/Transport.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Transport.php,v 1.18 2003/01/04 11:56:18 mj Exp $ +// $Id: Transport.php,v 1.19 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Base.php'; @@ -30,11 +30,11 @@ * no knowlege of the transport protocols is available at this level * * @access public -* @version $Id: Transport.php,v 1.18 2003/01/04 11:56:18 mj Exp $ +* @version $Id: Transport.php,v 1.19 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Transport * @author Shane Caraveo <shane@php.net> */ -class SOAP_Transport extends SOAP_Base +class SOAP_Transport extends SOAP_Base_Object { /** @@ -55,11 +55,16 @@ */ function SOAP_Transport($url, $encoding = SOAP_DEFAULT_ENCODING) { - parent::SOAP_Base('TRANSPORT'); + parent::SOAP_Base_Object('TRANSPORT'); $urlparts = @parse_url($url); $this->encoding = $encoding; + if (!$urlparts['scheme']) { + $this->_raiseSoapFault("Invalid transport URI: $url"); + return; + } + if (strcasecmp($urlparts['scheme'], 'http') == 0 || strcasecmp($urlparts['scheme'], 'https') == 0) { include_once('SOAP/Transport/HTTP.php'); $this->transport = new SOAP_Transport_HTTP($url, $encoding); @@ -69,7 +74,11 @@ $this->transport = new SOAP_Transport_SMTP($url, $encoding); return; } - $this->_raiseSoapFault("No Transport for {$urlparts['scheme']}"); + /* handle other transport types */ + $res = @include_once('SOAP/Transport/'.strtoupper($urlparts['scheme']).'.php'); + if(!res && !in_array('path/file.inc', get_included_files())) { + $this->_raiseSoapFault("No Transport for {$urlparts['scheme']}"); + } } /** Index: pear/SOAP/WSDL.php diff -u pear/SOAP/WSDL.php:1.31 pear/SOAP/WSDL.php:1.32 --- pear/SOAP/WSDL.php:1.31 Sat Jan 4 06:56:18 2003 +++ pear/SOAP/WSDL.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: WSDL.php,v 1.31 2003/01/04 11:56:18 mj Exp $ +// $Id: WSDL.php,v 1.32 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Base.php'; require_once 'SOAP/Fault.php'; @@ -39,7 +39,7 @@ * implement IDL type syntax declaration so we can generate WSDL * * @access public -* @version $Id: WSDL.php,v 1.31 2003/01/04 11:56:18 mj Exp $ +* @version $Id: WSDL.php,v 1.32 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -591,29 +591,30 @@ * add to cache, and return from cache */ function get($wsdl_fname, $proxy_params=array(), $cache=0) { - $cachename = SOAP_WSDL_Cache::_cacheDir() . "/" . md5($wsdl_fname); - $cacheinfo = $cachename.".info"; - $cachename .= ".wsdl"; - $md5_wsdl = ""; + $cachename = ''; + $md5_wsdl = ''; $file_data = ''; - if (WSDL_CACHE_USE && file_exists($cachename)) { - $wf = fopen($cachename,"rb"); - if ($wf) { - $file_data = fread($wf, filesize($cachename)); - $md5_wsdl = md5($file_data); - fclose($wf); - } - if ($cache) { - if ($cache != $md5_wsdl) { - return $this->_raiseSoapFault("WSDL Checksum error!", $wsdl_fname); + if (WSDL_CACHE_USE) { + $cachename = SOAP_WSDL_Cache::_cacheDir() . '/' . md5($wsdl_fname). '.wsdl'; + if (file_exists($cachename)) { + $wf = fopen($cachename,'rb'); + if ($wf) { + $file_data = fread($wf, filesize($cachename)); + $md5_wsdl = md5($file_data); + fclose($wf); } - } else { - $fi = stat($cachename); - $cache_mtime = $fi[8]; - #print cache_mtime, time() - if ($cache_mtime + WSDL_CACHE_MAX_AGE < time()) { - # expired - $md5_wsdl = ""; # refetch + if ($cache) { + if ($cache != $md5_wsdl) { + return $this->_raiseSoapFault("WSDL Checksum error!", $wsdl_fname); + } + } else { + $fi = stat($cachename); + $cache_mtime = $fi[8]; + #print cache_mtime, time() + if ($cache_mtime + WSDL_CACHE_MAX_AGE < time()) { + # expired + $md5_wsdl = ""; # refetch + } } } } Index: pear/SOAP/package.xml diff -u pear/SOAP/package.xml:1.21 pear/SOAP/package.xml:1.22 --- pear/SOAP/package.xml:1.21 Sun Dec 1 19:33:50 2002 +++ pear/SOAP/package.xml Fri Apr 4 03:29:17 2003 @@ -19,12 +19,10 @@ <license>PHP License</license> <release> <state>beta</state> - <version>0.7.1</version> - <date>2002-12-01</date> + <version>0.7.2</version> + <date>2003-04-01</date> <notes> - Minor bug fixes over the 0.7.0 release. - Support for the overload extension is currently - dissabled until futher work can be done. + Minor bug fixes over the 0.7.1 release. </notes> <filelist> <dir name="/" baseinstalldir="SOAP"> @@ -67,11 +65,21 @@ <dep type="ext" rel="has">pcre</dep> <dep type="pkg" rel="has">Mail_Mime</dep> <dep type="pkg" rel="has">HTTP_Request</dep> - <dep type="pkg" rel="ge" version="1.0.4">Net_URL</dep> + <dep type="pkg" rel="has">Net_URL</dep> <dep type="pkg" rel="has">Net_DIME</dep> </deps> </release> <changelog> + <release> + <state>beta</state> + <version>0.7.1</version> + <date>2002-12-01</date> + <notes> + Minor bug fixes over the 0.7.0 release. + Support for the overload extension is currently + dissabled until futher work can be done. + </notes> + </release> <release> <state>beta</state> <version>0.7.0</version> Index: pear/SOAP/Server/Email.php diff -u pear/SOAP/Server/Email.php:1.7 pear/SOAP/Server/Email.php:1.8 --- pear/SOAP/Server/Email.php:1.7 Sat Jan 4 06:56:18 2003 +++ pear/SOAP/Server/Email.php Fri Apr 4 03:29:17 2003 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more | // +----------------------------------------------------------------------+ // -// $Id: Email.php,v 1.7 2003/01/04 11:56:18 mj Exp $ +// $Id: Email.php,v 1.8 2003/04/04 08:29:17 shane Exp $ // require_once 'SOAP/Server.php'; @@ -37,7 +37,7 @@ * function call * * @access public -* @version $Id: Email.php,v 1.7 2003/01/04 11:56:18 mj Exp $ +* @version $Id: Email.php,v 1.8 2003/04/04 08:29:17 shane Exp $ * @package SOAP::Server * @author Shane Caraveo <shane@php.net> */ @@ -125,7 +125,7 @@ return $this->soapfault->getFault(); } $client = new SOAP_Client(NULL); - return $client->parseResponse($data, $this->xml_encoding, $this->attachments); + return $client->__parse($data, $this->xml_encoding, $this->attachments); } function service(&$data, $endpoint = '', $send_response = TRUE, $dump = FALSE) @@ -136,12 +136,12 @@ # if neither matches, we'll just try it anyway if (stristr($data,'Content-Type: application/dime')) { - $this->decodeDIMEMessage($data,$this->headers,$attachments); + $this->_decodeDIMEMessage($data,$this->headers,$attachments); $useEncoding = 'DIME'; } else if (stristr($data,'MIME-Version:')) { // this is a mime message, lets decode it. #$data = 'Content-Type: '.stripslashes($_SERVER['CONTENT_TYPE'])."\r\n\r\n".$data; - $this->decodeMimeMessage($data,$this->headers,$attachments); + $this->_decodeMimeMessage($data,$this->headers,$attachments); $useEncoding = 'Mime'; } else { // the old fallback, but decodeMimeMessage handles things fine. Index: pear/SOAP/Transport/HTTP.php diff -u pear/SOAP/Transport/HTTP.php:1.25 pear/SOAP/Transport/HTTP.php:1.26 --- pear/SOAP/Transport/HTTP.php:1.25 Mon Mar 24 17:12:40 2003 +++ pear/SOAP/Transport/HTTP.php Fri Apr 4 03:29:17 2003 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: HTTP.php,v 1.25 2003/03/24 22:12:40 arnaud Exp $ +// $Id: HTTP.php,v 1.26 2003/04/04 08:29:17 shane Exp $ // /** @@ -36,11 +36,11 @@ * HTTP Transport for SOAP * * @access public - * @version $Id: HTTP.php,v 1.25 2003/03/24 22:12:40 arnaud Exp $ + * @version $Id: HTTP.php,v 1.26 2003/04/04 08:29:17 shane Exp $ * @package SOAP::Transport::HTTP * @author Shane Caraveo <shane@php.net> */ -class SOAP_Transport_HTTP extends SOAP_Base +class SOAP_Transport_HTTP extends SOAP_Base_Object { /** * Basic Auth string @@ -114,7 +114,7 @@ */ function SOAP_Transport_HTTP($URL, $encoding = SOAP_DEFAULT_ENCODING) { - parent::SOAP_Base('HTTP'); + parent::SOAP_Base_Object('HTTP'); $this->urlparts = @parse_url($URL); $this->url = $URL; $this->encoding = $encoding; @@ -190,7 +190,8 @@ } if (isset($this->urlparts['user'])) { - $this->setCredentials($this->urlparts['user'], $this->urlparts['pass']); + $this->setCredentials(urldecode($this->urlparts['user']), + urldecode($this->urlparts['pass'])); } if (!isset($this->urlparts['path']) || !$this->urlparts['path']) $this->urlparts['path'] = '/'; @@ -319,9 +320,9 @@ } // send if ($this->timeout > 0) { - $fp = fsockopen($host, $port, $this->errno, $this->errmsg, $this->timeout); + $fp = @fsockopen($host, $port, $this->errno, $this->errmsg, $this->timeout); } else { - $fp = fsockopen($host, $port, $this->errno, $this->errmsg); + $fp = @fsockopen($host, $port, $this->errno, $this->errmsg); } if (!$fp) { return $this->_raiseSoapFault("Connect Error to $host:$port"); Index: pear/SOAP/example/client.php diff -u pear/SOAP/example/client.php:1.5 pear/SOAP/example/client.php:1.6 --- pear/SOAP/example/client.php:1.5 Sat Jan 4 06:56:20 2003 +++ pear/SOAP/example/client.php Fri Apr 4 03:29:17 2003 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: client.php,v 1.5 2003/01/04 11:56:20 mj Exp $ +// $Id: client.php,v 1.6 2003/04/04 08:29:17 shane Exp $ // include("SOAP/Client.php"); /** @@ -33,6 +33,19 @@ $ret = $soapclient->call("echoString",array("inputString"=>"this is a test string"),$options); print_r($ret);echo "<br>\n"; + +$ret = $soapclient->call("divide",array("dividend"=>22,"divisor"=>7),$options); +if (PEAR::isError($ret)) + print("Error: " . $ret->getMessage() . "<br>\n"); +else + print("Quotient is " . $ret . "<br>\n"); + +$ret = $soapclient->call("divide",array("dividend"=>22,"divisor"=>0),$options); +if (PEAR::isError($ret)) + print("Error: " . $ret->getMessage() . "<br>\n"); +else + print("Quotient is " . $ret . "<br>\n"); + class SOAPStruct { var $varString; Index: pear/SOAP/example/server.php diff -u pear/SOAP/example/server.php:1.5 pear/SOAP/example/server.php:1.6 --- pear/SOAP/example/server.php:1.5 Sat Jan 4 06:56:20 2003 +++ pear/SOAP/example/server.php Fri Apr 4 03:29:17 2003 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: server.php,v 1.5 2003/01/04 11:56:20 mj Exp $ +// $Id: server.php,v 1.6 2003/04/04 08:29:17 shane Exp $ // // first, include the SOAP/Server class @@ -75,6 +75,15 @@ function echoString($inputString) { return new SOAP_Value('outputString','string',$inputString); + } + + // a method that might return a fault + function divide($dividend, $divisor) + { + if ($divisor == 0) + return new SOAP_Fault('You cannot divide by zero', 'Client'); + else + return $dividend / $divisor; } function echoStruct($inputStruct) Index: pear/SOAP/Disco.php +++ pear/SOAP/Disco.php <? // // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.02 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Author: Dmitri Vinogradov <dimitri@vinogradov.de> | // +----------------------------------------------------------------------+ // // $Id: Disco.php,v 1.1 2003/04/04 08:29:16 shane Exp $ require_once 'SOAP/Base.php'; class SOAP_DISCO_Server extends SOAP_Base_Object { var $namespaces = array(SCHEMA_WSDL => 'wsdl', SCHEMA_SOAP => 'soap'); var $import_ns = array(); var $wsdl = ''; var $disco = ''; var $_wsdl = array(); var $_disco = array(); var $_service_name = ''; var $_service_desc = ''; var $_portname = ''; var $_bindingname = ''; function SOAP_DISCO_Server($soap_server, $service_name = '', $service_desc = '', $import_ns = null) { parent::SOAP_Base_Object('Server'); if ( !is_object($soap_server) || !get_class($soap_server) == 'soap_server') return; $host = isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:'localhost'; # DISCO $this->_disco['disco:discovery']['attr']['xmlns:disco'] = SCHEMA_DISCO; $this->_disco['disco:discovery']['attr']['xmlns:scl'] = SCHEMA_DISCO_SCL; $this->_disco['disco:discovery']['scl:contractRef']['attr']['ref'] = array_key_exists('HTTPS',$_SERVER) ? 'https://' . $host . $_SERVER['PHP_SELF'] . '?wsdl' : 'http://' . $host . $_SERVER['PHP_SELF'] . '?wsdl'; # generate disco xml $this->_generate_DISCO_XML($this->_disco); # WSDL if (is_array($soap_server->_namespaces)) { # need to get: typens, xsd & soapenc $this->namespaces = array_merge($this->namespaces, array($soap_server->method_namespace => 'typens')); $this->namespaces = array_merge($this->namespaces, array(array_search('xsd',$soap_server->_namespaces) => 'xsd')); $this->namespaces = array_merge($this->namespaces, array(array_search('SOAP-ENC',$soap_server->_namespaces) => 'soapenc')); } # DEFINITIONS $this->_service_name = $service_name !='' ? $service_name : ereg_replace('urn:','',$soap_server->method_namespace); $this->_service_desc = $service_desc; $this->_wsdl['definitions']['attr']['name'] = $this->_service_name; $this->_wsdl['definitions']['attr']['targetNamespace'] = $soap_server->method_namespace; foreach ($this->namespaces as $ns => $prefix) { $this->_wsdl['definitions']['attr']['xmlns:' . $prefix] = $ns; } $this->_wsdl['definitions']['attr']['xmlns'] = SCHEMA_WSDL; # import namespaces # seems to not work yet: wsdl.exe fom .NET cant handle imported complete wsdl-definitions # /* $this->import_ns = isset($import_ns) ? $import_ns : $this->import_ns; if (count($this->import_ns)>0) { $i = 0; foreach ($this->import_ns as $_ns => $_location) { $this->_wsdl['definitions']['import'][$i]['attr']['location'] = $_location; $this->_wsdl['definitions']['import'][$i]['attr']['namespace'] = $_ns; $i++; } } */ # SCHEMA $this->_wsdl['definitions']['types']['attr'] = ''; $this->_wsdl['definitions']['types']['xsd:schema']['attr']['xmlns'] = array_search('xsd',$this->namespaces); $this->_wsdl['definitions']['types']['xsd:schema']['attr']['targetNamespace'] = array_search('typens',$this->namespaces); $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'] = array(); $cTypes = 0; # foreach ($soap_server->dispatch_objects as $namespace => $namespace_objects) { if (is_array($namespace_objects)) { $_m = 0; foreach ($namespace_objects as $object) { # types definitions foreach ($object->__typedef as $_type_name => $_type_def) { if (!$this->_ifComplexTypeExists($this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'], $_type_name)) { $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['attr']['name'] = $_type_name; $z=0; foreach ($_type_def as $_varname => $_vartype) { if (!is_int($_varname)) { list($_vartypens,$_vartype) = $this->_getTypeNs($_vartype); $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:all']['attr'] = ''; $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:all']['xsd:element'][$z]['attr']['name'] = $_varname; $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:all']['xsd:element'][$z]['attr']['type'] = $_vartypens . ':' . $_vartype; } else { $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:complexContent']['attr'] = ''; $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:complexContent']['xsd:restriction']['attr']['base'] = 'soapenc:Array'; foreach ($_vartype as $array_var => $array_type) { list($_vartypens,$_vartype) = $this->_getTypeNs($array_type); $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:complexContent']['xsd:restriction']['xsd:attribute']['attr']['ref'] = 'soapenc:arrayType'; $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:complexContent']['xsd:restriction']['xsd:attribute']['attr']['wsdl:arrayType'] = $_vartypens . ':' . $_vartype . '[]'; } } $z++; } } $cTypes++; } # MESSAGES $i = $_m > 0 ? $i : 0; foreach ($object->__dispatch_map as $method_name => $method_types) { # INPUT $this->_wsdl['definitions']['message'][$i]['attr']['name'] = $method_name . 'Request'; $part_i = 0; foreach ($method_types['in'] as $name => $type) { list($typens,$type) = $this->_getTypeNs($type); $this->_wsdl['definitions']['message'][$i]['part'][$part_i]['attr']['name'] = $name; $this->_wsdl['definitions']['message'][$i]['part'][$part_i]['attr']['type'] = $typens . ':' . $type; $part_i++; } # OUTPUT $y = $i + 1; $this->_wsdl['definitions']['message'][$y]['attr']['name'] = $method_name . 'Response'; $part_i = 0; foreach ($method_types['out'] as $name => $type) { list($typens,$type) = $this->_getTypeNs($type); $this->_wsdl['definitions']['message'][$y]['part'][$part_i]['attr']['name'] = $name; $this->_wsdl['definitions']['message'][$y]['part'][$part_i]['attr']['type'] = $typens . ':' . $type; $part_i++; } # PORTTYPES $this->_wsdl['definitions']['portType']['operation'][$i]['attr']['name'] = $method_name; # INPUT $this->_wsdl['definitions']['portType']['operation'][$i]['input']['attr']['message'] = 'typens:' . $this->_wsdl['definitions']['message'][$i]['attr']['name']; # OUTPUT $this->_wsdl['definitions']['portType']['operation'][$i]['output']['attr']['message'] = 'typens:' . $this->_wsdl['definitions']['message'][$y]['attr']['name']; # BINDING $this->_wsdl['definitions']['binding']['operation'][$i]['attr']['name'] = $method_name; $this->_wsdl['definitions']['binding']['operation'][$i]['soap:operation']['attr']['soapAction'] = $soap_server->method_namespace . '#' . get_class($object) . '#' . $method_name; # INPUT $this->_wsdl['definitions']['binding']['operation'][$i]['input']['attr'] = ''; $this->_wsdl['definitions']['binding']['operation'][$i]['input']['soap:body']['attr']['use'] = 'encoded'; $this->_wsdl['definitions']['binding']['operation'][$i]['input']['soap:body']['attr']['namespace'] = $soap_server->method_namespace; $this->_wsdl['definitions']['binding']['operation'][$i]['input']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING; # OUTPUT $this->_wsdl['definitions']['binding']['operation'][$i]['output']['attr'] = ''; $this->_wsdl['definitions']['binding']['operation'][$i]['output']['soap:body']['attr']['use'] = 'encoded'; $this->_wsdl['definitions']['binding']['operation'][$i]['output']['soap:body']['attr']['namespace'] = $soap_server->method_namespace; $this->_wsdl['definitions']['binding']['operation'][$i]['output']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING; $i = $i + 2; } $_m++; } } } # PORTTYPE-NAME $this->_portname = $this->_service_name . 'Port'; $this->_wsdl['definitions']['portType']['attr']['name'] = $this->_portname; # BINDING-NAME $this->_bindingname = $this->_service_name . 'Binding'; $this->_wsdl['definitions']['binding']['attr']['name'] = $this->_bindingname; $this->_wsdl['definitions']['binding']['attr']['type'] = 'typens:' . $this->_portname; $this->_wsdl['definitions']['binding']['soap:binding']['attr']['style'] = 'rpc'; $this->_wsdl['definitions']['binding']['soap:binding']['attr']['transport'] = SCHEMA_HTTP; # SERVICE $this->_wsdl['definitions']['service']['attr']['name'] = $this->_service_name . 'Service'; $this->_wsdl['definitions']['service']['documentation']['attr'] = ''; $this->_wsdl['definitions']['service']['documentation'] = htmlentities($this->_service_desc); $this->_wsdl['definitions']['service']['port']['attr']['name'] = $this->_portname; $this->_wsdl['definitions']['service']['port']['attr']['binding'] = 'typens:' . $this->_bindingname; $this->_wsdl['definitions']['service']['port']['soap:address']['attr']['location'] = array_key_exists('HTTPS',$_SERVER) ? 'https://' . $host . $_SERVER['PHP_SELF'] : 'http://' . $host . $_SERVER['PHP_SELF']; # generate wsdl $this->_generate_WSDL_XML($this->_wsdl); } function _generate_DISCO_XML($disco_array) { $disco = '<?xml version="1.0"?>'; foreach ($disco_array as $key => $val) { $disco .= $this->_arrayToNode($key,$val); } $this->disco = $disco; } function _generate_WSDL_XML($wsdl_array) { $wsdl = '<?xml version="1.0"?>'; foreach ($wsdl_array as $key => $val) { $wsdl .= $this->_arrayToNode($key,$val); } $this->wsdl = $wsdl; } function _arrayToNode($node_name = '', $array) { $return = ''; if (is_array($array)) { # we have a node if there's key 'attr' if (array_key_exists('attr',$array)) { $return .= "<$node_name"; if (is_array($array['attr'])) { foreach ($array['attr'] as $attr_name => $attr_value) { $return .= " $attr_name=\"$attr_value\""; } } # unset 'attr' and proceed other childs... unset($array['attr']); if (count($array) > 0) { $i = 0; foreach ($array as $child_node_name => $child_node_value) { $return .= $i == 0 ? ">\n" : ''; $return .= $this->_arrayToNode($child_node_name,$child_node_value); $i++; } $return .= "</$node_name>\n"; } else { $return .= " />\n"; } } else { # we have no 'attr' key in array - so it's list of nodes with the same name ... foreach ($array as $child_node_name => $child_node_value) { $return .= $this->_arrayToNode($node_name,$child_node_value); } } } else { # $array is not an array if ($array !='') { # and its not empty $return .= "<$node_name>$array</$node_name>\n"; } else { # and its empty... $return .= "<$node_name />\n"; } } return $return; } function _getTypeNs($type) { preg_match_all("'\{(.*)\}'sm",$type,$m); if (isset($m[1][0]) && $m[1][0] != '') { if (!array_key_exists($m[1][0],$this->namespaces)) { $ns_pref = 'ns' . count($this->namespaces); $this->namespaces[$m[1][0]] = $ns_pref; $this->_wsdl['definitions']['attr']['xmlns:' . $ns_pref] = $m[1][0]; } $typens = $this->namespaces[$m[1][0]]; $type = ereg_replace($m[0][0],'',$type); } else { $typens = 'xsd'; } return array($typens,$type); } function _ifComplexTypeExists($typesArray, $type_name) { if (is_array($typesArray)) { foreach ($typesArray as $index => $type_data) { if ($typesArray[$index]['attr']['name'] == $type_name) { return true; } } } return false; } } ?> Index: pear/SOAP/example/disco_server.php +++ pear/SOAP/example/disco_server.php <? // // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.02 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Author: Dmitri Vinogradov <dimitri@vinogradov.de> | // +----------------------------------------------------------------------+ // // $Id: disco_server.php,v 1.1 2003/04/04 08:29:17 shane Exp $ /* This example shows how to mark up a server object so that wsdl files may be dynamicaly generated by the soap server. This also provides access to a generated DISCO document. The fact that this example has an MP3 class is in no way related to DISCO. ;) DISCO: http://msdn.microsoft.com/msdnmag/issues/02/02/xml/default.aspx A url accessing this server would look like: http://localhost/disco_server.php?wsdl (generate WSDL file) http://localhost/disco_server.php (GET request generates DISCO) http://localhost/disco_server.php (POST for normal soap requests) */ error_reporting(E_ALL); require_once 'SOAP/Server.php'; class MP3DB_Class { var $__dispatch_map = array(); var $__typedef = array(); function MP3DB_Class () { /** * the only way to describe all methods in WSDL (messages, * PortType-operations and bindings) is to use __dispatch_map * to describe every method (even methods using simple data * types in 'in' and 'out' parameters...) */ $this->__dispatch_map['SayHallo'] = array( 'in' => array('input' => 'string'), 'out' => array('return' => 'string') ); $this->__dispatch_map['SayThisNTimes'] = array( 'in' => array('SayThis'=>'string','NTimes' => 'int'), 'out' => array('return' => '{urn:MP3DB}ArrayOfStrings') ); $this->__dispatch_map['GetMP3Tracks'] = array( 'in' => array('query' => 'string'), 'out' => array('return' => '{urn:MP3DB}GetMP3TracksResult') ); $this->__dispatch_map['AddMP3Track'] = array( 'in' => array('MP3Track' => '{urn:MP3DB}MP3Track'), 'out' => array('return' => '{urn:MP3DB}AddMP3TrackResult') ); /** * I use __typedef to describe userdefined Types in WSDL. * Structs and one-dimensional arrays are supported: * Struct example: $this->__typedef['TypeName'] = array('VarName' => 'xsdType', ... ); * or $this->__typedef['TypeName'] = array('VarName' => '{namespace}SomeOtherType'); * Array example: $this->__typedef['TypeName'] = array(array('item' => 'xsdType')); * or $this->__typedef['TypeName'] = array(array('item' => '{namespace}SomeOtherType')); */ /** * Struct 'MP3Track' */ $this->__typedef['MP3Track'] = array( 'Title' => 'string', 'Artist' => 'string', 'Album' => 'string', 'Year' => 'int', 'Genre' => 'int', 'Comment' => 'string', 'Composer' => 'string', 'Orig_Artist' => 'string', 'URL' => 'string', 'Encoded_by' => 'string' ); /** * MP3TracksArray - array of 'MP3Track' structs */ $this->__typedef['MP3TracksArray'] = array( array( 'item' => '{urn:MP3DB}MP3Track' ) ); /** * Struct 'MethodDebug' */ $this->__typedef['MethodDebug'] = array( 'rc' => 'boolean', 'ErrNo' => 'int', 'Error' => 'string' ); /** * return Struct of method GetMP3Tracks */ $this->__typedef['GetMP3TracksResult'] = array( 'MethodDebug' => '{urn:MP3DB}MethodDebug', 'MP3Tracks' => '{urn:MP3DB}MP3TracksArray' ); /** * return Struct of method AddMP3Track */ $this->__typedef['AddMP3TrackResult'] = array( 'MethodDebug' => '{urn:MP3DB}MethodDebug' ); /** * Array of strings */ $this->__typedef['ArrayOfStrings'] = array( array('item'=>'string') ); } function SayHallo($name) { return "Hallo, " . $name; } function SayThisNTimes($SayThis,$NTimes) { for ($i = 0; $i < $NTimes; $i++) { $return[$i] = $SayThis . " $i"; } return new SOAP_Value('return','{urn:MP3DB}ArrayOfStrings',$return); } function GetMP3Tracks($query = "") { for($i = 0; $i < 5; $i++) { $this->MP3Tracks[$i] = new SOAP_Value( 'item', '{urn:MP3DB}MP3Track', array( "Title" => new SOAP_Value("Title","string","some track $i"), "Artist" => new SOAP_Value("Artist","string","some artist $i"), "Album" => new SOAP_Value("Album","string","some album $i"), "Year" => new SOAP_Value("Year","int",(integer)1999), "Genre" => new SOAP_Value("Genre","int",(integer)100), "Comment" => new SOAP_Value("Comment","string","blabla $i"), "Composer" => new SOAP_Value("Composer","string",""), "Orig_Artist" => new SOAP_Value("Orig_Artist","string",""), "URL" => new SOAP_Value("URL","string",""), "Encoded_by" => new SOAP_Value("Encoded_by","string","") ) ); } $MethodDebug["rc"] = new SOAP_Value("rc","boolean",true); $MethodDebug["ErrNo"] = new SOAP_Value("ErrNo","int",(integer)0); $MethodDebug["Error"] = new SOAP_Value("Error","string",""); return new SOAP_Value('return','{urn:MP3DB}GetMP3TracksResult',array( "MethodDebug" => new SOAP_Value('MethodDebug','{urn:MP3DB}MethodDebug',$MethodDebug), "MP3Tracks" => new SOAP_Value('MP3Tracks','{urn:MP3DB}MP3TracksArray',$this->MP3Tracks) ) ); } function AddMP3Track($MP3Track) { # well, lets imagine here some code for adding given mp3track to db or whatever... $MethodDebug["rc"] = new SOAP_Value("rc","boolean",true); $MethodDebug["ErrNo"] = new SOAP_Value("ErrNo","int",(integer)0); $MethodDebug["Error"] = new SOAP_Value("Error","string",""); return new SOAP_Value('return','{urn:MP3DB}AddMP3TrackResult',array( "MethodDebug" => new SOAP_Value('MethodDebug','{urn:MP3DB}MethodDebug',$MethodDebug) ) ); } function __dispatch($methodname) { if (isset($this->__dispatch_map[$methodname])) return $this->__dispatch_map[$methodname]; return NULL; } } $server = new SOAP_Server; $server->_auto_translation = true; $server->method_namespace = "urn:MP3DB"; $MP3DB_Class = new MP3DB_Class(); $server->addObjectMap($MP3DB_Class,$server->method_namespace); if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD']=='POST') { $server->service($HTTP_RAW_POST_DATA); } else { require_once 'SOAP/Disco.php'; $disco = new SOAP_DISCO_Server($server,"MP3DB"); header("Content-type: text/xml"); if (isset($_SERVER['QUERY_STRING']) && strcasecmp($_SERVER['QUERY_STRING'],'wsdl')==0) { echo $disco->wsdl; } else { echo $disco->disco; } exit; } ?>
Index: pear/SOAP/Base.php diff -u pear/SOAP/Base.php:1.29 pear/SOAP/Base.php:1.30 --- pear/SOAP/Base.php:1.29 Sat Jan 4 06:56:16 2003 +++ pear/SOAP/Base.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Base.php,v 1.29 2003/01/04 11:56:16 mj Exp $ +// $Id: Base.php,v 1.30 2003/04/04 08:29:16 shane Exp $ // /* @@ -54,8 +54,6 @@ $GLOBALS['SOAP_options']['DIME'] = 1; } -error_reporting(E_ALL); - /** * Enable debugging informations? * @@ -79,8 +77,8 @@ define('INF', 1.8e307); define('NAN', 0.0); -define('SOAP_LIBRARY_VERSION', '0.7.1'); -define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.7.1'); +define('SOAP_LIBRARY_VERSION', '0.7.2'); +define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.7.2-devel'); // set schema version define('SOAP_XML_SCHEMA_VERSION', 'http://www.w3.org/2001/XMLSchema'); define('SOAP_XML_SCHEMA_INSTANCE', 'http://www.w3.org/2001/XMLSchema-instance'); @@ -89,6 +87,9 @@ define('SOAP_SCHEMA_ENCODING', 'http://schemas.xmlsoap.org/soap/encoding/'); define('SOAP_ENVELOP', 'http://schemas.xmlsoap.org/soap/envelope/'); +define('SCHEMA_DISCO', 'http://schemas.xmlsoap.org/disco/'); +define('SCHEMA_DISCO_SCL', 'http://schemas.xmlsoap.org/disco/scl/'); + define('SCHEMA_SOAP', 'http://schemas.xmlsoap.org/wsdl/soap/'); define('SCHEMA_HTTP', 'http://schemas.xmlsoap.org/wsdl/http/'); define('SCHEMA_MIME', 'http://schemas.xmlsoap.org/wsdl/mime/'); @@ -108,16 +109,121 @@ } } +class SOAP_Base_Object extends PEAR +{ + /** + * Store debugging information in $debug_data? + * + * @var boolean if true debugging informations will be store in $debug_data + * @see $debug_data, SOAP_Base + */ + var $_debug_flag = false; + + /** + * String containing debugging informations if $debug_flag is set to true + * + * @var string debugging informations - mostyl error messages + * @see $debug_flag, SOAP_Base + * @access public + */ + var $_debug_data = ''; + + # supported encodings, limited by XML extension + var $_encodings = array('ISO-8859-1','US-ASCII','UTF-8'); + /** + * Fault code + * + * @var string + */ + var $_myfaultcode = ''; + + /** + * Recent PEAR error object + * + * @var object PEAR Error + */ + var $fault = NULL; + + /** + * Constructor + * + * @param string error code + * @see $debug_data, _debug() + */ + function SOAP_Base_Object($faultcode = 'Client') + { + $this->_myfaultcode = $faultcode; + $this->_debug_flag = $GLOBALS['SOAP_DEBUG']; + parent::PEAR('SOAP_Fault'); + } + + /** + * Raise a soap error + * + * Please referr to the SOAP definition for an impression of what a certain parameter + * stands for. + * + * Use $debug_flag to store errors to the member variable $debug_data + * + * @param string error message + * @param string detailed error message. + * @param string actor + * @param mixed + * @param mixed + * @param mixed + * @param boolean + * @see $debug_flag, $debug_data + */ + function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, $mode = null, $options = null, $skipmsg = false) + { + # pass through previous faults + if (is_object($str)) { + $this->fault = $str; + } else { + if (!$code) $code = $this->_myfaultcode; + $this->fault = new SOAP_Fault($str, + $code, + $actorURI, + $detail, + $mode, + $options); + } + return $this->fault; + } + + function __isfault() + { + return $this->fault != NULL; + } + + function &__getfault() + { + return $this->fault; + } + + /** + * maintains a string of debug data + * + * @param debugging message - sometimes an error message + */ + function _debug($string) + { + if ($this->_debug_flag) { + $this->_debug_data .= get_class($this) . ': ' . preg_replace("/>/", ">\r\n", $string) . "\n"; + } + } +} + /** * SOAP_Base * Common base class of all Soap lclasses * * @access public -* @version $Id: Base.php,v 1.29 2003/01/04 11:56:16 mj Exp $ +* @version $Id: Base.php,v 1.30 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates */ -class SOAP_Base extends PEAR +class SOAP_Base extends SOAP_Base_Object { var $_XMLSchema = array('http://www.w3.org/2001/XMLSchema', 'http://www.w3.org/1999/XMLSchema'); var $_XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; @@ -190,8 +296,6 @@ // load namespace uris into an array of uri => prefix var $_namespaces; var $_ns_count = 0; - # supported encodings, limited by XML extension - var $_encodings = array('ISO-8859-1','US-ASCII','UTF-8'); var $_xmlEntities = array ( '&' => '&', '<' => '<', '>' => '>', "'" => ''', '"' => '"' ); @@ -199,37 +303,6 @@ var $__attachments = array(); - /** - * Store debugging information in $debug_data? - * - * @var boolean if true debugging informations will be store in $debug_data - * @see $debug_data, SOAP_Base - */ - var $_debug_flag = false; - - /** - * String containing debugging informations if $debug_flag is set to true - * - * @var string debugging informations - mostyl error messages - * @see $debug_flag, SOAP_Base - * @access public - */ - var $_debug_data = ''; - - /** - * Fault code - * - * @var string - */ - var $_myfaultcode = ''; - - /** - * Recent PEAR error object - * - * @var object PEAR Error - */ - var $fault = NULL; - var $_wsdl = NULL; /** @@ -252,10 +325,8 @@ */ function SOAP_Base($faultcode = 'Client') { - $this->_myfaultcode = $faultcode; + parent::SOAP_Base_Object($faultcode); $this->_resetNamespaces(); - $this->_debug_flag = $GLOBALS['SOAP_DEBUG']; - parent::PEAR('SOAPfault'); } function _resetNamespaces() @@ -288,62 +359,6 @@ $this->_namespaces = array_flip($tmpNS); } - /** - * Raise a soap error - * - * Please referr to the SOAP definition for an impression of what a certain parameter - * stands for. - * - * Use $debug_flag to store errors to the member variable $debug_data - * - * @param string error message - * @param string detailed error message. - * @param string actor - * @param mixed - * @param mixed - * @param mixed - * @param boolean - * @see $debug_flag, $debug_data - */ - function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, $mode = null, $options = null, $skipmsg = false) - { - # pass through previous faults - if (is_object($str)) { - $this->fault = $str; - } else { - if (!$code) $code = $this->_myfaultcode; - $this->fault = new SOAP_Fault($str, - $code, - $actorURI, - $detail, - $mode, - $options); - } - return $this->fault; - } - - function __isfault() - { - return $this->fault != NULL; - } - - function &__getfault() - { - return $this->fault; - } - - /** - * maintains a string of debug data - * - * @param debugging message - sometimes an error message - */ - function _debug($string) - { - if ($this->_debug_flag) { - $this->_debug_data .= get_class($this) . ': ' . preg_replace("/>/", ">\r\n", $string) . "\n"; - } - } - function _getNamespacePrefix($ns) { if (array_key_exists($ns,$this->_namespaces)) { @@ -986,7 +1001,7 @@ * class used to handle QNAME values in XML * * @access public -* @version $Id: Base.php,v 1.29 2003/01/04 11:56:16 mj Exp $ +* @version $Id: Base.php,v 1.30 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates */ Index: pear/SOAP/Client.php diff -u pear/SOAP/Client.php:1.49 pear/SOAP/Client.php:1.50 --- pear/SOAP/Client.php:1.49 Mon Mar 24 17:12:40 2003 +++ pear/SOAP/Client.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Client.php,v 1.49 2003/03/24 22:12:40 arnaud Exp $ +// $Id: Client.php,v 1.50 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Value.php'; @@ -38,7 +38,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public - * @version $Id: Client.php,v 1.49 2003/03/24 22:12:40 arnaud Exp $ + * @version $Id: Client.php,v 1.50 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Stig Bakken <ssb@fast.no> Conversion to PEAR @@ -228,6 +228,8 @@ */ function call($method, $params = array(), $namespace = false, $soapAction = false) { + $this->__last_request = null; + $this->__last_response = null; $soap_data = $this->__generate($method, $params, $namespace, $soapAction); if (PEAR::isError($soap_data)) { return $this->_raiseSoapFault($soap_data); @@ -394,7 +396,7 @@ $part = $this->_wsdl->elements[$part['namespace']][$part['type']]; $name = $part['name']; } - if (isset($params[$name])) { + if (array_key_exists($name,$params)) { $nparams[$name] = $params[$name]; } else { # we now force an associative array for parameters if using wsdl @@ -555,7 +557,7 @@ function __get_wire() { - if ($this->__options['trace'] > 0) { + if ($this->__options['trace'] > 0 && ($this->__last_request || $this->__last_response)) { return "OUTGOING:\n\n". $this->__last_request. "\n\nINCOMING\n\n". Index: pear/SOAP/Parser.php diff -u pear/SOAP/Parser.php:1.28 pear/SOAP/Parser.php:1.29 --- pear/SOAP/Parser.php:1.28 Sat Jan 4 06:56:16 2003 +++ pear/SOAP/Parser.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Parser.php,v 1.28 2003/01/04 11:56:16 mj Exp $ +// $Id: Parser.php,v 1.29 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Base.php'; @@ -30,7 +30,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Parser.php,v 1.28 2003/01/04 11:56:16 mj Exp $ +* @version $Id: Parser.php,v 1.29 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Parser * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -81,10 +81,6 @@ if (preg_match('/<\?xml[^>]+encoding\s*?=\s*?(\'([^\']*)\'|"([^"]*)")[^>]*?[\?]>/',$xml,$m)) { $this->xml_encoding = strtoupper($m[2]?$m[2]:$m[3]); } - - # XXX need to do this better, remove newlines after > or before < - $this->xml = preg_replace("/>[\r\n]+/", '>', $this->xml); - $this->xml = preg_replace("/[\r\n]+</", '<', $this->xml); // determines where in the message we are (envelope,header,body,method) // Check whether content has been read. Index: pear/SOAP/Server.php diff -u pear/SOAP/Server.php:1.29 pear/SOAP/Server.php:1.30 --- pear/SOAP/Server.php:1.29 Sat Jan 4 06:56:18 2003 +++ pear/SOAP/Server.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Server.php,v 1.29 2003/01/04 11:56:18 mj Exp $ +// $Id: Server.php,v 1.30 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Base.php'; @@ -41,7 +41,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Server.php,v 1.29 2003/01/04 11:56:18 mj Exp $ +* @version $Id: Server.php,v 1.30 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -144,7 +144,7 @@ $useEncoding = 'Mime'; } if (!isset($headers['content-type'])) { - $headers['content-type'] = $_SERVER['CONTENT_TYPE']; + $headers['content-type'] = stripslashes($_SERVER['CONTENT_TYPE']); } if (!$this->fault && !$this->_getContentEncoding($headers['content-type'])) { @@ -158,7 +158,7 @@ if (!$this->fault && !$test && ($_SERVER['REQUEST_METHOD'] != 'POST' || strncmp($headers['content-type'],'text/xml',8) != 0)) { // this is not possibly a valid soap request, try to return a WSDL file - $this->_raiseSoapFault("Invalid SOAP request, must be POST with content-type: text/xml, got: {$headers['content-type']}",'','','Server'); + $this->_raiseSoapFault("Invalid SOAP request, must be POST with content-type: text/xml, got: ".(isset($headers['content-type'])?$headers['content-type']:'Nothing!'),'','','Server'); } if (!$this->fault) { Index: pear/SOAP/Transport.php diff -u pear/SOAP/Transport.php:1.18 pear/SOAP/Transport.php:1.19 --- pear/SOAP/Transport.php:1.18 Sat Jan 4 06:56:18 2003 +++ pear/SOAP/Transport.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Transport.php,v 1.18 2003/01/04 11:56:18 mj Exp $ +// $Id: Transport.php,v 1.19 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Base.php'; @@ -30,11 +30,11 @@ * no knowlege of the transport protocols is available at this level * * @access public -* @version $Id: Transport.php,v 1.18 2003/01/04 11:56:18 mj Exp $ +* @version $Id: Transport.php,v 1.19 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Transport * @author Shane Caraveo <shane@php.net> */ -class SOAP_Transport extends SOAP_Base +class SOAP_Transport extends SOAP_Base_Object { /** @@ -55,11 +55,16 @@ */ function SOAP_Transport($url, $encoding = SOAP_DEFAULT_ENCODING) { - parent::SOAP_Base('TRANSPORT'); + parent::SOAP_Base_Object('TRANSPORT'); $urlparts = @parse_url($url); $this->encoding = $encoding; + if (!$urlparts['scheme']) { + $this->_raiseSoapFault("Invalid transport URI: $url"); + return; + } + if (strcasecmp($urlparts['scheme'], 'http') == 0 || strcasecmp($urlparts['scheme'], 'https') == 0) { include_once('SOAP/Transport/HTTP.php'); $this->transport = new SOAP_Transport_HTTP($url, $encoding); @@ -69,7 +74,11 @@ $this->transport = new SOAP_Transport_SMTP($url, $encoding); return; } - $this->_raiseSoapFault("No Transport for {$urlparts['scheme']}"); + /* handle other transport types */ + $res = @include_once('SOAP/Transport/'.strtoupper($urlparts['scheme']).'.php'); + if(!res && !in_array('path/file.inc', get_included_files())) { + $this->_raiseSoapFault("No Transport for {$urlparts['scheme']}"); + } } /** Index: pear/SOAP/WSDL.php diff -u pear/SOAP/WSDL.php:1.31 pear/SOAP/WSDL.php:1.32 --- pear/SOAP/WSDL.php:1.31 Sat Jan 4 06:56:18 2003 +++ pear/SOAP/WSDL.php Fri Apr 4 03:29:16 2003 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: WSDL.php,v 1.31 2003/01/04 11:56:18 mj Exp $ +// $Id: WSDL.php,v 1.32 2003/04/04 08:29:16 shane Exp $ // require_once 'SOAP/Base.php'; require_once 'SOAP/Fault.php'; @@ -39,7 +39,7 @@ * implement IDL type syntax declaration so we can generate WSDL * * @access public -* @version $Id: WSDL.php,v 1.31 2003/01/04 11:56:18 mj Exp $ +* @version $Id: WSDL.php,v 1.32 2003/04/04 08:29:16 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -591,29 +591,30 @@ * add to cache, and return from cache */ function get($wsdl_fname, $proxy_params=array(), $cache=0) { - $cachename = SOAP_WSDL_Cache::_cacheDir() . "/" . md5($wsdl_fname); - $cacheinfo = $cachename.".info"; - $cachename .= ".wsdl"; - $md5_wsdl = ""; + $cachename = ''; + $md5_wsdl = ''; $file_data = ''; - if (WSDL_CACHE_USE && file_exists($cachename)) { - $wf = fopen($cachename,"rb"); - if ($wf) { - $file_data = fread($wf, filesize($cachename)); - $md5_wsdl = md5($file_data); - fclose($wf); - } - if ($cache) { - if ($cache != $md5_wsdl) { - return $this->_raiseSoapFault("WSDL Checksum error!", $wsdl_fname); + if (WSDL_CACHE_USE) { + $cachename = SOAP_WSDL_Cache::_cacheDir() . '/' . md5($wsdl_fname). '.wsdl'; + if (file_exists($cachename)) { + $wf = fopen($cachename,'rb'); + if ($wf) { + $file_data = fread($wf, filesize($cachename)); + $md5_wsdl = md5($file_data); + fclose($wf); } - } else { - $fi = stat($cachename); - $cache_mtime = $fi[8]; - #print cache_mtime, time() - if ($cache_mtime + WSDL_CACHE_MAX_AGE < time()) { - # expired - $md5_wsdl = ""; # refetch + if ($cache) { + if ($cache != $md5_wsdl) { + return $this->_raiseSoapFault("WSDL Checksum error!", $wsdl_fname); + } + } else { + $fi = stat($cachename); + $cache_mtime = $fi[8]; + #print cache_mtime, time() + if ($cache_mtime + WSDL_CACHE_MAX_AGE < time()) { + # expired + $md5_wsdl = ""; # refetch + } } } } Index: pear/SOAP/package.xml diff -u pear/SOAP/package.xml:1.21 pear/SOAP/package.xml:1.22 --- pear/SOAP/package.xml:1.21 Sun Dec 1 19:33:50 2002 +++ pear/SOAP/package.xml Fri Apr 4 03:29:17 2003 @@ -19,12 +19,10 @@ <license>PHP License</license> <release> <state>beta</state> - <version>0.7.1</version> - <date>2002-12-01</date> + <version>0.7.2</version> + <date>2003-04-01</date> <notes> - Minor bug fixes over the 0.7.0 release. - Support for the overload extension is currently - dissabled until futher work can be done. + Minor bug fixes over the 0.7.1 release. </notes> <filelist> <dir name="/" baseinstalldir="SOAP"> @@ -67,11 +65,21 @@ <dep type="ext" rel="has">pcre</dep> <dep type="pkg" rel="has">Mail_Mime</dep> <dep type="pkg" rel="has">HTTP_Request</dep> - <dep type="pkg" rel="ge" version="1.0.4">Net_URL</dep> + <dep type="pkg" rel="has">Net_URL</dep> <dep type="pkg" rel="has">Net_DIME</dep> </deps> </release> <changelog> + <release> + <state>beta</state> + <version>0.7.1</version> + <date>2002-12-01</date> + <notes> + Minor bug fixes over the 0.7.0 release. + Support for the overload extension is currently + dissabled until futher work can be done. + </notes> + </release> <release> <state>beta</state> <version>0.7.0</version> Index: pear/SOAP/Server/Email.php diff -u pear/SOAP/Server/Email.php:1.7 pear/SOAP/Server/Email.php:1.8 --- pear/SOAP/Server/Email.php:1.7 Sat Jan 4 06:56:18 2003 +++ pear/SOAP/Server/Email.php Fri Apr 4 03:29:17 2003 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more | // +----------------------------------------------------------------------+ // -// $Id: Email.php,v 1.7 2003/01/04 11:56:18 mj Exp $ +// $Id: Email.php,v 1.8 2003/04/04 08:29:17 shane Exp $ // require_once 'SOAP/Server.php'; @@ -37,7 +37,7 @@ * function call * * @access public -* @version $Id: Email.php,v 1.7 2003/01/04 11:56:18 mj Exp $ +* @version $Id: Email.php,v 1.8 2003/04/04 08:29:17 shane Exp $ * @package SOAP::Server * @author Shane Caraveo <shane@php.net> */ @@ -125,7 +125,7 @@ return $this->soapfault->getFault(); } $client = new SOAP_Client(NULL); - return $client->parseResponse($data, $this->xml_encoding, $this->attachments); + return $client->__parse($data, $this->xml_encoding, $this->attachments); } function service(&$data, $endpoint = '', $send_response = TRUE, $dump = FALSE) @@ -136,12 +136,12 @@ # if neither matches, we'll just try it anyway if (stristr($data,'Content-Type: application/dime')) { - $this->decodeDIMEMessage($data,$this->headers,$attachments); + $this->_decodeDIMEMessage($data,$this->headers,$attachments); $useEncoding = 'DIME'; } else if (stristr($data,'MIME-Version:')) { // this is a mime message, lets decode it. #$data = 'Content-Type: '.stripslashes($_SERVER['CONTENT_TYPE'])."\r\n\r\n".$data; - $this->decodeMimeMessage($data,$this->headers,$attachments); + $this->_decodeMimeMessage($data,$this->headers,$attachments); $useEncoding = 'Mime'; } else { // the old fallback, but decodeMimeMessage handles things fine. Index: pear/SOAP/Transport/HTTP.php diff -u pear/SOAP/Transport/HTTP.php:1.25 pear/SOAP/Transport/HTTP.php:1.26 --- pear/SOAP/Transport/HTTP.php:1.25 Mon Mar 24 17:12:40 2003 +++ pear/SOAP/Transport/HTTP.php Fri Apr 4 03:29:17 2003 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: HTTP.php,v 1.25 2003/03/24 22:12:40 arnaud Exp $ +// $Id: HTTP.php,v 1.26 2003/04/04 08:29:17 shane Exp $ // /** @@ -36,11 +36,11 @@ * HTTP Transport for SOAP * * @access public - * @version $Id: HTTP.php,v 1.25 2003/03/24 22:12:40 arnaud Exp $ + * @version $Id: HTTP.php,v 1.26 2003/04/04 08:29:17 shane Exp $ * @package SOAP::Transport::HTTP * @author Shane Caraveo <shane@php.net> */ -class SOAP_Transport_HTTP extends SOAP_Base +class SOAP_Transport_HTTP extends SOAP_Base_Object { /** * Basic Auth string @@ -114,7 +114,7 @@ */ function SOAP_Transport_HTTP($URL, $encoding = SOAP_DEFAULT_ENCODING) { - parent::SOAP_Base('HTTP'); + parent::SOAP_Base_Object('HTTP'); $this->urlparts = @parse_url($URL); $this->url = $URL; $this->encoding = $encoding; @@ -190,7 +190,8 @@ } if (isset($this->urlparts['user'])) { - $this->setCredentials($this->urlparts['user'], $this->urlparts['pass']); + $this->setCredentials(urldecode($this->urlparts['user']), + urldecode($this->urlparts['pass'])); } if (!isset($this->urlparts['path']) || !$this->urlparts['path']) $this->urlparts['path'] = '/'; @@ -319,9 +320,9 @@ } // send if ($this->timeout > 0) { - $fp = fsockopen($host, $port, $this->errno, $this->errmsg, $this->timeout); + $fp = @fsockopen($host, $port, $this->errno, $this->errmsg, $this->timeout); } else { - $fp = fsockopen($host, $port, $this->errno, $this->errmsg); + $fp = @fsockopen($host, $port, $this->errno, $this->errmsg); } if (!$fp) { return $this->_raiseSoapFault("Connect Error to $host:$port"); Index: pear/SOAP/example/client.php diff -u pear/SOAP/example/client.php:1.5 pear/SOAP/example/client.php:1.6 --- pear/SOAP/example/client.php:1.5 Sat Jan 4 06:56:20 2003 +++ pear/SOAP/example/client.php Fri Apr 4 03:29:17 2003 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: client.php,v 1.5 2003/01/04 11:56:20 mj Exp $ +// $Id: client.php,v 1.6 2003/04/04 08:29:17 shane Exp $ // include("SOAP/Client.php"); /** @@ -33,6 +33,19 @@ $ret = $soapclient->call("echoString",array("inputString"=>"this is a test string"),$options); print_r($ret);echo "<br>\n"; + +$ret = $soapclient->call("divide",array("dividend"=>22,"divisor"=>7),$options); +if (PEAR::isError($ret)) + print("Error: " . $ret->getMessage() . "<br>\n"); +else + print("Quotient is " . $ret . "<br>\n"); + +$ret = $soapclient->call("divide",array("dividend"=>22,"divisor"=>0),$options); +if (PEAR::isError($ret)) + print("Error: " . $ret->getMessage() . "<br>\n"); +else + print("Quotient is " . $ret . "<br>\n"); + class SOAPStruct { var $varString; Index: pear/SOAP/example/server.php diff -u pear/SOAP/example/server.php:1.5 pear/SOAP/example/server.php:1.6 --- pear/SOAP/example/server.php:1.5 Sat Jan 4 06:56:20 2003 +++ pear/SOAP/example/server.php Fri Apr 4 03:29:17 2003 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: server.php,v 1.5 2003/01/04 11:56:20 mj Exp $ +// $Id: server.php,v 1.6 2003/04/04 08:29:17 shane Exp $ // // first, include the SOAP/Server class @@ -75,6 +75,15 @@ function echoString($inputString) { return new SOAP_Value('outputString','string',$inputString); + } + + // a method that might return a fault + function divide($dividend, $divisor) + { + if ($divisor == 0) + return new SOAP_Fault('You cannot divide by zero', 'Client'); + else + return $dividend / $divisor; } function echoStruct($inputStruct) Index: pear/SOAP/Disco.php +++ pear/SOAP/Disco.php <? // // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.02 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Author: Dmitri Vinogradov <dimitri@vinogradov.de> | // +----------------------------------------------------------------------+ // // $Id: Disco.php,v 1.1 2003/04/04 08:29:16 shane Exp $ require_once 'SOAP/Base.php'; class SOAP_DISCO_Server extends SOAP_Base_Object { var $namespaces = array(SCHEMA_WSDL => 'wsdl', SCHEMA_SOAP => 'soap'); var $import_ns = array(); var $wsdl = ''; var $disco = ''; var $_wsdl = array(); var $_disco = array(); var $_service_name = ''; var $_service_desc = ''; var $_portname = ''; var $_bindingname = ''; function SOAP_DISCO_Server($soap_server, $service_name = '', $service_desc = '', $import_ns = null) { parent::SOAP_Base_Object('Server'); if ( !is_object($soap_server) || !get_class($soap_server) == 'soap_server') return; $host = isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:'localhost'; # DISCO $this->_disco['disco:discovery']['attr']['xmlns:disco'] = SCHEMA_DISCO; $this->_disco['disco:discovery']['attr']['xmlns:scl'] = SCHEMA_DISCO_SCL; $this->_disco['disco:discovery']['scl:contractRef']['attr']['ref'] = array_key_exists('HTTPS',$_SERVER) ? 'https://' . $host . $_SERVER['PHP_SELF'] . '?wsdl' : 'http://' . $host . $_SERVER['PHP_SELF'] . '?wsdl'; # generate disco xml $this->_generate_DISCO_XML($this->_disco); # WSDL if (is_array($soap_server->_namespaces)) { # need to get: typens, xsd & soapenc $this->namespaces = array_merge($this->namespaces, array($soap_server->method_namespace => 'typens')); $this->namespaces = array_merge($this->namespaces, array(array_search('xsd',$soap_server->_namespaces) => 'xsd')); $this->namespaces = array_merge($this->namespaces, array(array_search('SOAP-ENC',$soap_server->_namespaces) => 'soapenc')); } # DEFINITIONS $this->_service_name = $service_name !='' ? $service_name : ereg_replace('urn:','',$soap_server->method_namespace); $this->_service_desc = $service_desc; $this->_wsdl['definitions']['attr']['name'] = $this->_service_name; $this->_wsdl['definitions']['attr']['targetNamespace'] = $soap_server->method_namespace; foreach ($this->namespaces as $ns => $prefix) { $this->_wsdl['definitions']['attr']['xmlns:' . $prefix] = $ns; } $this->_wsdl['definitions']['attr']['xmlns'] = SCHEMA_WSDL; # import namespaces # seems to not work yet: wsdl.exe fom .NET cant handle imported complete wsdl-definitions # /* $this->import_ns = isset($import_ns) ? $import_ns : $this->import_ns; if (count($this->import_ns)>0) { $i = 0; foreach ($this->import_ns as $_ns => $_location) { $this->_wsdl['definitions']['import'][$i]['attr']['location'] = $_location; $this->_wsdl['definitions']['import'][$i]['attr']['namespace'] = $_ns; $i++; } } */ # SCHEMA $this->_wsdl['definitions']['types']['attr'] = ''; $this->_wsdl['definitions']['types']['xsd:schema']['attr']['xmlns'] = array_search('xsd',$this->namespaces); $this->_wsdl['definitions']['types']['xsd:schema']['attr']['targetNamespace'] = array_search('typens',$this->namespaces); $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'] = array(); $cTypes = 0; # foreach ($soap_server->dispatch_objects as $namespace => $namespace_objects) { if (is_array($namespace_objects)) { $_m = 0; foreach ($namespace_objects as $object) { # types definitions foreach ($object->__typedef as $_type_name => $_type_def) { if (!$this->_ifComplexTypeExists($this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'], $_type_name)) { $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['attr']['name'] = $_type_name; $z=0; foreach ($_type_def as $_varname => $_vartype) { if (!is_int($_varname)) { list($_vartypens,$_vartype) = $this->_getTypeNs($_vartype); $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:all']['attr'] = ''; $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:all']['xsd:element'][$z]['attr']['name'] = $_varname; $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:all']['xsd:element'][$z]['attr']['type'] = $_vartypens . ':' . $_vartype; } else { $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:complexContent']['attr'] = ''; $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:complexContent']['xsd:restriction']['attr']['base'] = 'soapenc:Array'; foreach ($_vartype as $array_var => $array_type) { list($_vartypens,$_vartype) = $this->_getTypeNs($array_type); $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:complexContent']['xsd:restriction']['xsd:attribute']['attr']['ref'] = 'soapenc:arrayType'; $this->_wsdl['definitions']['types']['xsd:schema']['xsd:complexType'][$cTypes]['xsd:complexContent']['xsd:restriction']['xsd:attribute']['attr']['wsdl:arrayType'] = $_vartypens . ':' . $_vartype . '[]'; } } $z++; } } $cTypes++; } # MESSAGES $i = $_m > 0 ? $i : 0; foreach ($object->__dispatch_map as $method_name => $method_types) { # INPUT $this->_wsdl['definitions']['message'][$i]['attr']['name'] = $method_name . 'Request'; $part_i = 0; foreach ($method_types['in'] as $name => $type) { list($typens,$type) = $this->_getTypeNs($type); $this->_wsdl['definitions']['message'][$i]['part'][$part_i]['attr']['name'] = $name; $this->_wsdl['definitions']['message'][$i]['part'][$part_i]['attr']['type'] = $typens . ':' . $type; $part_i++; } # OUTPUT $y = $i + 1; $this->_wsdl['definitions']['message'][$y]['attr']['name'] = $method_name . 'Response'; $part_i = 0; foreach ($method_types['out'] as $name => $type) { list($typens,$type) = $this->_getTypeNs($type); $this->_wsdl['definitions']['message'][$y]['part'][$part_i]['attr']['name'] = $name; $this->_wsdl['definitions']['message'][$y]['part'][$part_i]['attr']['type'] = $typens . ':' . $type; $part_i++; } # PORTTYPES $this->_wsdl['definitions']['portType']['operation'][$i]['attr']['name'] = $method_name; # INPUT $this->_wsdl['definitions']['portType']['operation'][$i]['input']['attr']['message'] = 'typens:' . $this->_wsdl['definitions']['message'][$i]['attr']['name']; # OUTPUT $this->_wsdl['definitions']['portType']['operation'][$i]['output']['attr']['message'] = 'typens:' . $this->_wsdl['definitions']['message'][$y]['attr']['name']; # BINDING $this->_wsdl['definitions']['binding']['operation'][$i]['attr']['name'] = $method_name; $this->_wsdl['definitions']['binding']['operation'][$i]['soap:operation']['attr']['soapAction'] = $soap_server->method_namespace . '#' . get_class($object) . '#' . $method_name; # INPUT $this->_wsdl['definitions']['binding']['operation'][$i]['input']['attr'] = ''; $this->_wsdl['definitions']['binding']['operation'][$i]['input']['soap:body']['attr']['use'] = 'encoded'; $this->_wsdl['definitions']['binding']['operation'][$i]['input']['soap:body']['attr']['namespace'] = $soap_server->method_namespace; $this->_wsdl['definitions']['binding']['operation'][$i]['input']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING; # OUTPUT $this->_wsdl['definitions']['binding']['operation'][$i]['output']['attr'] = ''; $this->_wsdl['definitions']['binding']['operation'][$i]['output']['soap:body']['attr']['use'] = 'encoded'; $this->_wsdl['definitions']['binding']['operation'][$i]['output']['soap:body']['attr']['namespace'] = $soap_server->method_namespace; $this->_wsdl['definitions']['binding']['operation'][$i]['output']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING; $i = $i + 2; } $_m++; } } } # PORTTYPE-NAME $this->_portname = $this->_service_name . 'Port'; $this->_wsdl['definitions']['portType']['attr']['name'] = $this->_portname; # BINDING-NAME $this->_bindingname = $this->_service_name . 'Binding'; $this->_wsdl['definitions']['binding']['attr']['name'] = $this->_bindingname; $this->_wsdl['definitions']['binding']['attr']['type'] = 'typens:' . $this->_portname; $this->_wsdl['definitions']['binding']['soap:binding']['attr']['style'] = 'rpc'; $this->_wsdl['definitions']['binding']['soap:binding']['attr']['transport'] = SCHEMA_HTTP; # SERVICE $this->_wsdl['definitions']['service']['attr']['name'] = $this->_service_name . 'Service'; $this->_wsdl['definitions']['service']['documentation']['attr'] = ''; $this->_wsdl['definitions']['service']['documentation'] = htmlentities($this->_service_desc); $this->_wsdl['definitions']['service']['port']['attr']['name'] = $this->_portname; $this->_wsdl['definitions']['service']['port']['attr']['binding'] = 'typens:' . $this->_bindingname; $this->_wsdl['definitions']['service']['port']['soap:address']['attr']['location'] = array_key_exists('HTTPS',$_SERVER) ? 'https://' . $host . $_SERVER['PHP_SELF'] : 'http://' . $host . $_SERVER['PHP_SELF']; # generate wsdl $this->_generate_WSDL_XML($this->_wsdl); } function _generate_DISCO_XML($disco_array) { $disco = '<?xml version="1.0"?>'; foreach ($disco_array as $key => $val) { $disco .= $this->_arrayToNode($key,$val); } $this->disco = $disco; } function _generate_WSDL_XML($wsdl_array) { $wsdl = '<?xml version="1.0"?>'; foreach ($wsdl_array as $key => $val) { $wsdl .= $this->_arrayToNode($key,$val); } $this->wsdl = $wsdl; } function _arrayToNode($node_name = '', $array) { $return = ''; if (is_array($array)) { # we have a node if there's key 'attr' if (array_key_exists('attr',$array)) { $return .= "<$node_name"; if (is_array($array['attr'])) { foreach ($array['attr'] as $attr_name => $attr_value) { $return .= " $attr_name=\"$attr_value\""; } } # unset 'attr' and proceed other childs... unset($array['attr']); if (count($array) > 0) { $i = 0; foreach ($array as $child_node_name => $child_node_value) { $return .= $i == 0 ? ">\n" : ''; $return .= $this->_arrayToNode($child_node_name,$child_node_value); $i++; } $return .= "</$node_name>\n"; } else { $return .= " />\n"; } } else { # we have no 'attr' key in array - so it's list of nodes with the same name ... foreach ($array as $child_node_name => $child_node_value) { $return .= $this->_arrayToNode($node_name,$child_node_value); } } } else { # $array is not an array if ($array !='') { # and its not empty $return .= "<$node_name>$array</$node_name>\n"; } else { # and its empty... $return .= "<$node_name />\n"; } } return $return; } function _getTypeNs($type) { preg_match_all("'\{(.*)\}'sm",$type,$m); if (isset($m[1][0]) && $m[1][0] != '') { if (!array_key_exists($m[1][0],$this->namespaces)) { $ns_pref = 'ns' . count($this->namespaces); $this->namespaces[$m[1][0]] = $ns_pref; $this->_wsdl['definitions']['attr']['xmlns:' . $ns_pref] = $m[1][0]; } $typens = $this->namespaces[$m[1][0]]; $type = ereg_replace($m[0][0],'',$type); } else { $typens = 'xsd'; } return array($typens,$type); } function _ifComplexTypeExists($typesArray, $type_name) { if (is_array($typesArray)) { foreach ($typesArray as $index => $type_data) { if ($typesArray[$index]['attr']['name'] == $type_name) { return true; } } } return false; } } ?> Index: pear/SOAP/example/disco_server.php +++ pear/SOAP/example/disco_server.php <? // // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.02 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Author: Dmitri Vinogradov <dimitri@vinogradov.de> | // +----------------------------------------------------------------------+ // // $Id: disco_server.php,v 1.1 2003/04/04 08:29:17 shane Exp $ /* This example shows how to mark up a server object so that wsdl files may be dynamicaly generated by the soap server. This also provides access to a generated DISCO document. The fact that this example has an MP3 class is in no way related to DISCO. ;) DISCO: http://msdn.microsoft.com/msdnmag/issues/02/02/xml/default.aspx A url accessing this server would look like: http://localhost/disco_server.php?wsdl (generate WSDL file) http://localhost/disco_server.php (GET request generates DISCO) http://localhost/disco_server.php (POST for normal soap requests) */ error_reporting(E_ALL); require_once 'SOAP/Server.php'; class MP3DB_Class { var $__dispatch_map = array(); var $__typedef = array(); function MP3DB_Class () { /** * the only way to describe all methods in WSDL (messages, * PortType-operations and bindings) is to use __dispatch_map * to describe every method (even methods using simple data * types in 'in' and 'out' parameters...) */ $this->__dispatch_map['SayHallo'] = array( 'in' => array('input' => 'string'), 'out' => array('return' => 'string') ); $this->__dispatch_map['SayThisNTimes'] = array( 'in' => array('SayThis'=>'string','NTimes' => 'int'), 'out' => array('return' => '{urn:MP3DB}ArrayOfStrings') ); $this->__dispatch_map['GetMP3Tracks'] = array( 'in' => array('query' => 'string'), 'out' => array('return' => '{urn:MP3DB}GetMP3TracksResult') ); $this->__dispatch_map['AddMP3Track'] = array( 'in' => array('MP3Track' => '{urn:MP3DB}MP3Track'), 'out' => array('return' => '{urn:MP3DB}AddMP3TrackResult') ); /** * I use __typedef to describe userdefined Types in WSDL. * Structs and one-dimensional arrays are supported: * Struct example: $this->__typedef['TypeName'] = array('VarName' => 'xsdType', ... ); * or $this->__typedef['TypeName'] = array('VarName' => '{namespace}SomeOtherType'); * Array example: $this->__typedef['TypeName'] = array(array('item' => 'xsdType')); * or $this->__typedef['TypeName'] = array(array('item' => '{namespace}SomeOtherType')); */ /** * Struct 'MP3Track' */ $this->__typedef['MP3Track'] = array( 'Title' => 'string', 'Artist' => 'string', 'Album' => 'string', 'Year' => 'int', 'Genre' => 'int', 'Comment' => 'string', 'Composer' => 'string', 'Orig_Artist' => 'string', 'URL' => 'string', 'Encoded_by' => 'string' ); /** * MP3TracksArray - array of 'MP3Track' structs */ $this->__typedef['MP3TracksArray'] = array( array( 'item' => '{urn:MP3DB}MP3Track' ) ); /** * Struct 'MethodDebug' */ $this->__typedef['MethodDebug'] = array( 'rc' => 'boolean', 'ErrNo' => 'int', 'Error' => 'string' ); /** * return Struct of method GetMP3Tracks */ $this->__typedef['GetMP3TracksResult'] = array( 'MethodDebug' => '{urn:MP3DB}MethodDebug', 'MP3Tracks' => '{urn:MP3DB}MP3TracksArray' ); /** * return Struct of method AddMP3Track */ $this->__typedef['AddMP3TrackResult'] = array( 'MethodDebug' => '{urn:MP3DB}MethodDebug' ); /** * Array of strings */ $this->__typedef['ArrayOfStrings'] = array( array('item'=>'string') ); } function SayHallo($name) { return "Hallo, " . $name; } function SayThisNTimes($SayThis,$NTimes) { for ($i = 0; $i < $NTimes; $i++) { $return[$i] = $SayThis . " $i"; } return new SOAP_Value('return','{urn:MP3DB}ArrayOfStrings',$return); } function GetMP3Tracks($query = "") { for($i = 0; $i < 5; $i++) { $this->MP3Tracks[$i] = new SOAP_Value( 'item', '{urn:MP3DB}MP3Track', array( "Title" => new SOAP_Value("Title","string","some track $i"), "Artist" => new SOAP_Value("Artist","string","some artist $i"), "Album" => new SOAP_Value("Album","string","some album $i"), "Year" => new SOAP_Value("Year","int",(integer)1999), "Genre" => new SOAP_Value("Genre","int",(integer)100), "Comment" => new SOAP_Value("Comment","string","blabla $i"), "Composer" => new SOAP_Value("Composer","string",""), "Orig_Artist" => new SOAP_Value("Orig_Artist","string",""), "URL" => new SOAP_Value("URL","string",""), "Encoded_by" => new SOAP_Value("Encoded_by","string","") ) ); } $MethodDebug["rc"] = new SOAP_Value("rc","boolean",true); $MethodDebug["ErrNo"] = new SOAP_Value("ErrNo","int",(integer)0); $MethodDebug["Error"] = new SOAP_Value("Error","string",""); return new SOAP_Value('return','{urn:MP3DB}GetMP3TracksResult',array( "MethodDebug" => new SOAP_Value('MethodDebug','{urn:MP3DB}MethodDebug',$MethodDebug), "MP3Tracks" => new SOAP_Value('MP3Tracks','{urn:MP3DB}MP3TracksArray',$this->MP3Tracks) ) ); } function AddMP3Track($MP3Track) { # well, lets imagine here some code for adding given mp3track to db or whatever... $MethodDebug["rc"] = new SOAP_Value("rc","boolean",true); $MethodDebug["ErrNo"] = new SOAP_Value("ErrNo","int",(integer)0); $MethodDebug["Error"] = new SOAP_Value("Error","string",""); return new SOAP_Value('return','{urn:MP3DB}AddMP3TrackResult',array( "MethodDebug" => new SOAP_Value('MethodDebug','{urn:MP3DB}MethodDebug',$MethodDebug) ) ); } function __dispatch($methodname) { if (isset($this->__dispatch_map[$methodname])) return $this->__dispatch_map[$methodname]; return NULL; } } $server = new SOAP_Server; $server->_auto_translation = true; $server->method_namespace = "urn:MP3DB"; $MP3DB_Class = new MP3DB_Class(); $server->addObjectMap($MP3DB_Class,$server->method_namespace); if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD']=='POST') { $server->service($HTTP_RAW_POST_DATA); } else { require_once 'SOAP/Disco.php'; $disco = new SOAP_DISCO_Server($server,"MP3DB"); header("Content-type: text/xml"); if (isset($_SERVER['QUERY_STRING']) && strcasecmp($_SERVER['QUERY_STRING'],'wsdl')==0) { echo $disco->wsdl; } else { echo $disco->disco; } exit; } ?>