Page MenuHomePhabricator

No OneTemporary

diff --git a/library/SOAP/Base.php b/library/SOAP/Base.php
index 984ec45..5762351 100644
--- a/library/SOAP/Base.php
+++ b/library/SOAP/Base.php
@@ -1,1116 +1,1115 @@
<?php
/**
* This file loads all required libraries, defines constants used across the
* SOAP package, and defines the base classes that most other classes of this
* package extend.
*
* PHP versions 4 and 5
*
* LICENSE: 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.
*
* @category Web Services
* @package SOAP
* @author Dietrich Ayala <dietrich@ganx4.com> Original Author
* @author Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more
* @author Chuck Hagenbuch <chuck@horde.org> Maintenance
* @author Jan Schneider <jan@horde.org> Maintenance
* @copyright 2003-2007 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP License 2.02
* @link http://pear.php.net/package/SOAP
*/
define('MAIL_MIMEPART_CRLF', "\r\n");
require_once 'PEAR.php';
if (!defined('INF')) {
define('INF', 1.8e307);
}
if (!defined('NAN')) {
define('NAN', 0.0);
}
define('SOAP_LIBRARY_VERSION', '0.11.0');
define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.11.0-beta');
// 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');
define('SOAP_XML_SCHEMA_1999', 'http://www.w3.org/1999/XMLSchema');
define('SOAP_SCHEMA', 'http://schemas.xmlsoap.org/wsdl/soap/');
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_SOAP12', 'http://schemas.xmlsoap.org/wsdl/soap12/');
define('SCHEMA_SOAP_HTTP', 'http://schemas.xmlsoap.org/soap/http');
define('SCHEMA_WSDL_HTTP', 'http://schemas.xmlsoap.org/wsdl/http/');
define('SCHEMA_MIME', 'http://schemas.xmlsoap.org/wsdl/mime/');
define('SCHEMA_WSDL', 'http://schemas.xmlsoap.org/wsdl/');
define('SCHEMA_DIME', 'http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/');
define('SCHEMA_CONTENT', 'http://schemas.xmlsoap.org/ws/2002/04/content-type/');
define('SCHEMA_REF', 'http://schemas.xmlsoap.org/ws/2002/04/reference/');
define('SOAP_DEFAULT_ENCODING', 'UTF-8');
class SOAP_Base_Object extends PEAR
{
/**
* Supported encodings, limited by XML extension.
*
* @var array $_encodings
*/
var $_encodings = array('ISO-8859-1', 'US-ASCII', 'UTF-8');
/**
* Fault code.
*
* @var string $_myfaultcode
*/
var $_myfaultcode = '';
/**
* Recent PEAR_Error object.
*
* @var PEAR_Error $fault
*/
var $fault = null;
/**
* Constructor.
*
* @param string $faultcode Error code.
*/
function SOAP_Base_Object($faultcode = 'Client')
{
$this->_myfaultcode = $faultcode;
parent::PEAR('SOAP_Fault');
}
/**
* Raises a SOAP error.
*
* Please refer to the SOAP definition for an impression of what a certain
* parameter stands for.
*
* @param string|object $str Error message or object.
* @param string $detail Detailed error message.
* @param string $actorURI
* @param mixed $code
* @param mixed $mode
* @param mixed $options
* @param boolean $skipmsg
*/
function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null,
$mode = null, $options = null, $skipmsg = false)
{
// Pass through previous faults.
$is_instance = isset($this) && is_a($this, 'SOAP_Base_Object');
if (is_object($str)) {
$fault =& $str;
} else {
if (!$code) {
$code = $is_instance ? $this->_myfaultcode : 'Client';
}
require_once 'SOAP/Fault.php';
$fault =new SOAP_Fault($str,
$code,
$actorURI,
$detail,
$mode,
$options);
}
if ($is_instance) {
$this->fault =& $fault;
}
return $fault;
}
function _isfault()
{
return $this->fault != null;
}
function &_getfault()
{
return $this->fault;
}
}
/**
* Common base class of all SOAP classes.
*
* @access public
* @package SOAP
* @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates
*/
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';
// load types into typemap array
var $_typemap = array(
'http://www.w3.org/2001/XMLSchema' => array(
'string' => 'string',
'boolean' => 'boolean',
'float' => 'float',
'double' => 'float',
'decimal' => 'float',
'duration' => 'integer',
'dateTime' => 'string',
'time' => 'string',
'date' => 'string',
'gYearMonth' => 'integer',
'gYear' => 'integer',
'gMonthDay' => 'integer',
'gDay' => 'integer',
'gMonth' => 'integer',
'hexBinary' => 'string',
'base64Binary' => 'string',
// derived datatypes
'normalizedString' => 'string',
'token' => 'string',
'language' => 'string',
'NMTOKEN' => 'string',
'NMTOKENS' => 'string',
'Name' => 'string',
'NCName' => 'string',
'ID' => 'string',
'IDREF' => 'string',
'IDREFS' => 'string',
'ENTITY' => 'string',
'ENTITIES' => 'string',
'integer' => 'integer',
'nonPositiveInteger' => 'integer',
'negativeInteger' => 'integer',
// longs (64bit ints) are not supported cross-platform.
'long' => 'string',
'int' => 'integer',
'short' => 'integer',
'byte' => 'string',
'nonNegativeInteger' => 'integer',
'unsignedLong' => 'integer',
'unsignedInt' => 'integer',
'unsignedShort' => 'integer',
'unsignedByte' => 'integer',
'positiveInteger' => 'integer',
'anyType' => 'string',
'anyURI' => 'string',
'QName' => 'string'
),
'http://www.w3.org/1999/XMLSchema' => array(
'i4' => 'integer',
'int' => 'integer',
'boolean' => 'boolean',
'string' => 'string',
'double' => 'float',
'float' => 'float',
'dateTime' => 'string',
'timeInstant' => 'string',
'base64Binary' => 'string',
'base64' => 'string',
'ur-type' => 'string'
),
'http://schemas.xmlsoap.org/soap/encoding/' => array(
'base64' => 'string',
'array' => 'array',
'Array' => 'array',
'Struct' => 'array')
);
/**
* Default class name to use for decoded response objects.
*
* @var string $_defaultObjectClassname
*/
var $_defaultObjectClassname = 'stdClass';
/**
* Hash with used namespaces.
*
* @array
*/
var $_namespaces;
/**
* The default namespace.
*
* @string
*/
var $_namespace;
var $_xmlEntities = array('&' => '&amp;',
'<' => '&lt;',
'>' => '&gt;',
"'" => '&apos;',
'"' => '&quot;');
var $_doconversion = false;
var $_attachments = array();
var $_wsdl = null;
/**
* True if we use section 5 encoding, or false if this is literal.
*
* @var boolean $_section5
*/
var $_section5 = true;
// Handle type to class mapping.
var $_auto_translation = false;
var $_type_translation = array();
/**
* Constructor.
*
* @param string $faultcode Error code.
*/
function SOAP_Base($faultcode = 'Client')
{
parent::SOAP_Base_Object($faultcode);
$this->_resetNamespaces();
}
/**
* Sets the default namespace.
*
* @param string $namespace The default namespace.
*/
function setDefaultNamespace($namespace)
{
$this->_namespace = $namespace;
}
function _resetNamespaces()
{
$this->_namespaces = array(
'http://schemas.xmlsoap.org/soap/envelope/' => 'SOAP-ENV',
'http://www.w3.org/2001/XMLSchema' => 'xsd',
'http://www.w3.org/2001/XMLSchema-instance' => 'xsi',
'http://schemas.xmlsoap.org/soap/encoding/' => 'SOAP-ENC');
}
/**
* Sets the schema version used in the SOAP message.
*
* @access private
* @see $_XMLSchema
*
* @param string $schemaVersion The schema version.
*/
function _setSchemaVersion($schemaVersion)
{
if (!in_array($schemaVersion, $this->_XMLSchema)) {
return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion");
}
$this->_XMLSchemaVersion = $schemaVersion;
- $tmpNS = array_flip($this->_namespaces);
+ $tmpNS = is_array($this->_namespaces) ? array_flip($this->_namespaces) : array();
$tmpNS['xsd'] = $this->_XMLSchemaVersion;
$tmpNS['xsi'] = $this->_XMLSchemaVersion . '-instance';
$this->_namespaces = array_flip($tmpNS);
}
function _getNamespacePrefix($ns)
{
if ($this->_namespace && $ns == $this->_namespace) {
return '';
}
if (isset($this->_namespaces[$ns])) {
return $this->_namespaces[$ns];
}
$prefix = 'ns' . count($this->_namespaces);
$this->_namespaces[$ns] = $prefix;
return $prefix;
}
function _getNamespaceForPrefix($prefix)
{
$flipped = array_flip($this->_namespaces);
if (isset($flipped[$prefix])) {
return $flipped[$prefix];
}
return null;
}
function _isSoapValue(&$value)
{
return is_a($value, 'SOAP_Value');
}
function _serializeValue(&$value, $name = '', $type = false,
$elNamespace = null, $typeNamespace = null,
$options = array(), $attributes = array(),
$artype = '')
{
$namespaces = array();
$arrayType = $array_depth = $xmlout_value = null;
$typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = '';
$xmlout_type = $xmlns = $ptype = $array_type_ns = '';
if (!$name || is_numeric($name)) {
$name = 'item';
}
if ($this->_wsdl) {
list($ptype, $arrayType, $array_type_ns, $array_depth)
= $this->_wsdl->getSchemaType($type, $name, $typeNamespace);
}
if (!$arrayType) {
$arrayType = $artype;
}
if (!$ptype) {
$ptype = $this->_getType($value);
}
if (!$type) {
$type = $ptype;
}
if (strcasecmp($ptype, 'Struct') == 0 ||
strcasecmp($type, 'Struct') == 0) {
// Struct
$vars = null;
if (is_object($value)) {
$vars = get_object_vars($value);
} else {
$vars = &$value;
}
if (is_array($vars)) {
foreach (array_keys($vars) as $k) {
// Hide private vars.
if ($k[0] == '_') {
continue;
}
if (is_object($vars[$k])) {
if (is_a($vars[$k], 'SOAP_Value')) {
$xmlout_value .= $vars[$k]->serialize($this);
} else {
// XXX get the members and serialize them instead
// converting to an array is more overhead than we
// should really do.
$xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5 ? null : $elNamespace);
}
} else {
$xmlout_value .= $this->_serializeValue($vars[$k], $k, false, $this->_section5 ? null : $elNamespace);
}
}
}
} elseif (strcasecmp($ptype, 'Array') == 0 ||
strcasecmp($type, 'Array') == 0) {
// Array.
$typeNamespace = SOAP_SCHEMA_ENCODING;
$orig_type = $type;
$type = 'Array';
$numtypes = 0;
$value = (array)$value;
// XXX this will be slow on larger arrays. Basically, it flattens
// arrays to allow us to serialize multi-dimensional arrays. We
// only do this if arrayType is set, which will typically only
// happen if we are using WSDL
if (isset($options['flatten']) ||
($arrayType &&
(strchr($arrayType, ',') || strstr($arrayType, '][')))) {
$numtypes = $this->_multiArrayType($value, $arrayType,
$ar_size, $xmlout_value);
}
$array_type = $array_type_prefix = '';
if ($numtypes != 1) {
$arrayTypeQName = new QName($arrayType);
$arrayType = $arrayTypeQName->name;
$array_types = array();
$array_val = null;
// Serialize each array element.
$ar_size = count($value);
foreach ($value as $array_val) {
if ($this->_isSoapValue($array_val)) {
$array_type = $array_val->type;
$array_types[$array_type] = 1;
$array_type_ns = $array_val->type_namespace;
$xmlout_value .= $array_val->serialize($this);
} else {
$array_type = $this->_getType($array_val);
$array_types[$array_type] = 1;
$xmlout_value .= $this->_serializeValue($array_val, 'item', $array_type, $this->_section5 ? null : $elNamespace);
}
}
$xmlout_offset = ' SOAP-ENC:offset="[0]"';
if (!$arrayType) {
$numtypes = count($array_types);
if ($numtypes == 1) {
$arrayType = $array_type;
}
// Using anyType is more interoperable.
if ($array_type == 'Struct') {
$array_type = '';
} elseif ($array_type == 'Array') {
$arrayType = 'anyType';
$array_type_prefix = 'xsd';
} else {
if (!$arrayType) {
$arrayType = $array_type;
}
}
}
}
if (!$arrayType || $numtypes > 1) {
// Should reference what schema we're using.
$arrayType = 'xsd:anyType';
} else {
if ($array_type_ns) {
$array_type_prefix = $this->_getNamespacePrefix($array_type_ns);
} elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) {
$array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion];
}
if ($array_type_prefix) {
$arrayType = $array_type_prefix . ':' . $arrayType;
}
}
$xmlout_arrayType = ' SOAP-ENC:arrayType="' . $arrayType;
if ($array_depth != null) {
for ($i = 0; $i < $array_depth; $i++) {
$xmlout_arrayType .= '[]';
}
}
$xmlout_arrayType .= "[$ar_size]\"";
} elseif ($this->_isSoapValue($value)) {
$xmlout_value = $value->serialize($this);
} elseif ($type == 'string') {
$xmlout_value = htmlspecialchars($value);
} elseif ($type == 'rawstring') {
$xmlout_value =& $value;
} elseif ($type == 'boolean') {
$xmlout_value = $value ? 'true' : 'false';
} else {
$xmlout_value =& $value;
}
// Add namespaces.
if ($elNamespace) {
$elPrefix = $this->_getNamespacePrefix($elNamespace);
if ($elPrefix) {
$xmlout_name = "$elPrefix:$name";
} else {
$xmlout_name = $name;
}
} else {
$xmlout_name = $name;
}
if ($typeNamespace) {
$typePrefix = $this->_getNamespacePrefix($typeNamespace);
if ($typePrefix) {
$xmlout_type = "$typePrefix:$type";
} else {
$xmlout_type = $type;
}
} elseif ($type &&
isset($this->_typemap[$this->_XMLSchemaVersion][$type])) {
$typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];
if ($typePrefix) {
$xmlout_type = "$typePrefix:$type";
} else {
$xmlout_type = $type;
}
}
// Handle additional attributes.
$xml_attr = '';
if (count($attributes)) {
foreach ($attributes as $k => $v) {
$kqn = new QName($k);
$vqn = new QName($v);
$xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"';
}
}
// Store the attachment for mime encoding.
if (isset($options['attachment']) &&
!PEAR::isError($options['attachment'])) {
$this->_attachments[] = $options['attachment'];
}
if ($this->_section5) {
if ($xmlout_type) {
$xmlout_type = " xsi:type=\"$xmlout_type\"";
}
if (is_null($xmlout_value)) {
$xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" .
"$xml_attr xsi:nil=\"true\"/>";
} else {
$xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" .
"$xmlout_offset$xml_attr>$xmlout_value</$xmlout_name>";
}
} else {
if (is_null($xmlout_value)) {
$xml = "\r\n<$xmlout_name$xmlns$xml_attr/>";
} else {
$xml = "\r\n<$xmlout_name$xmlns$xml_attr>" .
$xmlout_value . "</$xmlout_name>";
}
}
return $xml;
}
/**
* Converts a PHP type to a SOAP type.
*
* @access private
*
* @param string $value The value to inspect.
*
* @return string The value's SOAP type.
*/
function _getType(&$value)
{
$type = gettype($value);
switch ($type) {
case 'object':
if (is_a($value, 'soap_value')) {
$type = $value->type;
} else {
$type = 'Struct';
}
break;
case 'array':
// Hashes are always handled as structs.
if ($this->_isHash($value)) {
$type = 'Struct';
} else {
$ar_size = count($value);
reset($value);
$key1 = key($value);
if ($ar_size > 0 && is_a($key1, 'SOAP_Value')) {
// FIXME: for non-wsdl structs that are all the same type
$key2 = key($value);
if ($ar_size > 1 &&
$this->_isSoapValue($key1) &&
$this->_isSoapValue($key2) &&
$key1->name != $key2->name) {
// This is a struct, not an array.
$type = 'Struct';
} else {
$type = 'Array';
}
} else {
$type = 'Array';
}
}
break;
case 'integer':
case 'long':
$type = 'int';
break;
case 'boolean':
break;
case 'double':
// double is deprecated in PHP 4.2 and later.
$type = 'float';
break;
case 'null':
$type = '';
break;
case 'string':
default:
break;
}
return $type;
}
function _multiArrayType($value, &$type, &$size, &$xml)
{
if (is_array($value)) {
// Seems we have a multi dimensional array, figure it out if we
// do.
for ($i = 0, $c = count($value); $i < $c; ++$i) {
$this->_multiArrayType($value[$i], $type, $size, $xml);
}
$sz = count($value);
if ($size) {
$size = $sz . ',' . $size;
} else {
$size = $sz;
}
return 1;
} elseif (is_object($value)) {
$type = $value->type;
$xml .= $value->serialize($this);
} else {
$type = $this->_getType($value);
$xml .= $this->_serializeValue($value, 'item', $type);
}
$size = null;
return 1;
}
/**
* Returns whether a type is a base64 type.
*
* @param string $type A type name.
*
* @return boolean True if the type name is a base64 type.
*/
function _isBase64Type($type)
{
return $type == 'base64' || $type == 'base64Binary';
}
/**
* Returns whether an array is a hash.
*
* @param array $a An array to check.
*
* @return boolean True if the specified array is a hash.
*/
function _isHash(&$a)
{
// I really dislike having to loop through this in PHP code, really
// large arrays will be slow. We need a C function to do this.
$it = 0;
foreach ($a as $k => $v) {
// Checking the type is faster than regexp.
if (!is_int($k)) {
return true;
}
// If someone has a large hash they should really be defining the
// type.
if ($it++ > 10) {
$this->_raiseSoapFault('Large associative array passed where a SOAP_Value was expected');
return false;
}
}
return false;
}
function _un_htmlentities($string)
{
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
$trans_tbl = array_flip($trans_tbl);
return strtr($string, $trans_tbl);
}
/**
* Converts a SOAP_Value object into a StdClass PHP object
*/
function &_decode(&$soapval)
{
if (!$this->_isSoapValue($soapval)) {
return $soapval;
} elseif (is_array($soapval->value)) {
if ($soapval->type != 'Array') {
$classname = $this->_defaultObjectClassname;
if (isset($this->_type_translation[$soapval->tqn->fqn()])) {
// This will force an error in PHP if the class does not
// exist.
$classname = $this->_type_translation[$soapval->tqn->fqn()];
} elseif (isset($this->_type_translation[$soapval->type])) {
// This will force an error in PHP if the class does not
// exist.
$classname = $this->_type_translation[$soapval->type];
} elseif ($this->_auto_translation) {
if (class_exists($soapval->type)) {
$classname = $soapval->type;
} elseif ($this->_wsdl) {
$t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace);
if ($t && class_exists($t)) {
$classname = $t;
}
}
}
$return =new $classname;
} else {
$return = array();
}
$counter = 1;
$isstruct = !is_array($return);
foreach ($soapval->value as $item) {
if (is_object($return)) {
if ($this->_wsdl) {
// Get this child's WSDL information.
// /$soapval->ns/$soapval->type/$item->ns/$item->name
$child_type = $this->_wsdl->getComplexTypeChildType(
$soapval->namespace,
$soapval->name,
$item->namespace,
$item->name);
if ($child_type) {
$item->type = $child_type;
}
}
if (!$isstruct || $item->type == 'Array') {
if (isset($return->{$item->name}) &&
is_object($return->{$item->name})) {
$return->{$item->name} =& $this->_decode($item);
} elseif (isset($return->{$item->name}) &&
is_array($return->{$item->name})) {
$return->{$item->name}[] = $this->_decode($item);
} elseif (isset($return->{$item->name})) {
$return->{$item->name} = array(
$return->{$item->name},
$this->_decode($item)
);
} elseif (is_array($return)) {
$return[] =& $this->_decode($item);
} else {
$return->{$item->name} =& $this->_decode($item);
}
} elseif (isset($return->{$item->name})) {
//$isstruct = false;
if (count(get_object_vars($return)) == 1) {
$d =& $this->_decode($item);
$return = array($return->{$item->name}, $d);
} else {
$d =& $this->_decode($item);
$return->{$item->name} = array($return->{$item->name}, $d);
}
} else {
$return->{$item->name} =& $this->_decode($item);
}
// Set the attributes as members in the class.
if (method_exists($return, '__set_attribute')) {
foreach ($soapval->attributes as $key => $value) {
call_user_func_array(array(&$return,
'__set_attribute'),
array($key, $value));
}
}
} else {
if ($soapval->arrayType && $this->_isSoapValue($item)) {
if ($this->_isBase64Type($item->type) &&
!$this->_isBase64Type($soapval->arrayType)) {
// Decode the value if we're losing the base64
// type information.
$item->value = base64_decode($item->value);
}
$item->type = $soapval->arrayType;
}
if (!$isstruct) {
$return[] = $this->_decode($item);
} elseif (isset($return[$item->name])) {
$isstruct = false;
$d =& $this->_decode($item);
$return = array($return[$item->name], $d);
} else {
$return[$item->name] = $this->_decode($item);
}
}
}
return $return;
}
if ($soapval->type == 'boolean') {
if ($soapval->value != '0' &&
strcasecmp($soapval->value, 'false') != 0) {
$soapval->value = true;
} else {
$soapval->value = false;
}
} elseif ($soapval->type &&
isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type])) {
// If we can, set variable type.
settype($soapval->value,
$this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]);
}
return $soapval->value;
}
/**
* Creates the SOAP envelope with the SOAP envelop data.
*
* @param mixed $method
* @param array $headers
* @param string $encoding
* @param array $options
*
* @return string
*/
function makeEnvelope(&$method, &$headers,
$encoding = SOAP_DEFAULT_ENCODING,
$options = array())
{
$smsg = $header_xml = $ns_string = '';
if ($headers) {
$c = count($headers);
for ($i = 0; $i < $c; $i++) {
$header_xml .= $headers[$i]->serialize($this);
}
$header_xml = "<SOAP-ENV:Header>\r\n$header_xml\r\n</SOAP-ENV:Header>\r\n";
}
if (!isset($options['input']) || $options['input'] == 'parse') {
if (is_array($method)) {
$c = count($method);
for ($i = 0; $i < $c; $i++) {
$smsg .= $method[$i]->serialize($this);
}
} else {
$smsg = $method->serialize($this);
}
} else {
$smsg = $method;
}
- $body = "<SOAP-ENV:Body>\r\n" . $smsg . "\r\n</SOAP-ENV:Body>\r\n";
+ $body = "<SOAP-ENV:Body>\r\n" . $smsg . "\r\n</SOAP-ENV:Body>\r\n";
- foreach ($this->_namespaces as $k => $v) {
+ foreach ($this->_namespaces as $k => $v) {
$ns_string .= " xmlns:$v=\"$k\"\r\n";
}
if ($this->_namespace) {
$ns_string .= " xmlns=\"{$this->_namespace}\"\r\n";
}
/* If 'use' == 'literal', we do not put in the encodingStyle. This is
* denoted by $this->_section5 being false. 'use' can be defined at a
* more granular level than we are dealing with here, so this does not
* work for all services. */
$xml = "<?xml version=\"1.0\" encoding=\"$encoding\"?>\r\n\r\n".
"<SOAP-ENV:Envelope $ns_string".
($this->_section5 ? ' SOAP-ENV:encodingStyle="' . SOAP_SCHEMA_ENCODING . '"' : '').
">\r\n".
"$header_xml$body</SOAP-ENV:Envelope>\r\n";
-
return $xml;
}
function _makeMimeMessage($xml, $encoding = SOAP_DEFAULT_ENCODING)
{
if (!@include_once 'Mail/mimePart.php') {
return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed');
}
// Encode any attachments. See http://www.w3.org/TR/SOAP-attachments
// Now we have to mime encode the message.
$params = array('content_type' => 'multipart/related; type="text/xml"');
$msg = new Mail_mimePart('', $params);
// Add the xml part.
$params['content_type'] = 'text/xml';
$params['charset'] = $encoding;
$params['encoding'] = 'base64';
$msg->addSubPart($xml, $params);
// Add the attachements
for ($i = 0, $c = count($this->_attachments); $i < $c; ++$i) {
$msg->addSubPart($this->_attachments[$i]['body'],
$this->_attachments[$i]);
}
return $msg->encode();
}
// TODO: this needs to be used from the Transport system.
function _makeDIMEMessage($xml)
{
if (!@include_once 'Net/DIME.php') {
return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed');
}
// Encode any attachments. See
// http://search.ietf.org/internet-drafts/draft-nielsen-dime-soap-00.txt
// Now we have to DIME encode the message
$dime = new Net_DIME_Message();
$msg = $dime->encodeData($xml, SOAP_ENVELOP, null, NET_DIME_TYPE_URI);
// Add the attachments.
$c = count($this->_attachments);
for ($i = 0; $i < $c; $i++) {
$msg .= $dime->encodeData($this->_attachments[$i]['body'],
$this->_attachments[$i]['content_type'],
$this->_attachments[$i]['cid'],
NET_DIME_TYPE_MEDIA);
}
$msg .= $dime->endMessage();
return $msg;
}
function _decodeMimeMessage(&$data, &$headers, &$attachments)
{
if (!@include_once 'Mail/mimeDecode.php') {
return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed');
}
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
// Lame thing to have to do for decoding.
$decoder =new Mail_mimeDecode($data);
$structure = $decoder->decode($params);
if (isset($structure->body)) {
$data = $structure->body;
$headers = $structure->headers;
return;
} elseif (isset($structure->parts)) {
$data = $structure->parts[0]->body;
$headers = array_merge($structure->headers,
$structure->parts[0]->headers);
if (count($structure->parts) > 1) {
$mime_parts = array_splice($structure->parts,1);
// Prepare the parts for the SOAP parser.
$c = count($mime_parts);
for ($i = 0; $i < $c; $i++) {
$p =& $mime_parts[$i];
if (isset($p->headers['content-location'])) {
// TODO: modify location per SwA note section 3
// http://www.w3.org/TR/SOAP-attachments
$attachments[$p->headers['content-location']] = $p->body;
} else {
$cid = 'cid:' . substr($p->headers['content-id'], 1, -1);
$attachments[$cid] = $p->body;
}
}
}
return;
}
$this->_raiseSoapFault('Mime parsing error', '', '', 'Server');
}
function _decodeDIMEMessage(&$data, &$headers, &$attachments)
{
if (!@include_once 'Net/DIME.php') {
return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed');
}
// This SHOULD be moved to the transport layer, e.g. PHP itself should
// handle parsing DIME ;)
$dime =new Net_DIME_Message();
$err = $dime->decodeData($data);
if (PEAR::isError($err)) {
$this->_raiseSoapFault('Failed to decode the DIME message!', '', '', 'Server');
return;
}
if (strcasecmp($dime->parts[0]['type'], SOAP_ENVELOP) != 0) {
$this->_raiseSoapFault('DIME record 1 is not a SOAP envelop!', '', '', 'Server');
return;
}
$data = $dime->parts[0]['data'];
// Fake it for now.
$headers['content-type'] = 'text/xml';
$c = count($dime->parts);
for ($i = 0; $i < $c; $i++) {
$part =& $dime->parts[$i];
// We need to handle URI's better.
$id = strncmp($part['id'], 'cid:', 4)
? 'cid:' . $part['id']
: $part['id'];
$attachments[$id] = $part['data'];
}
}
/**
* @deprecated Use setTypeTranslation().
*/
function __set_type_translation($type, $class = null)
{
$this->setTypeTranslation($type, $class);
}
/**
* Explicitly sets the translation for a specific class.
*
* Auto translation works for all cases, but opens ANY class in the script
* to be used as a data type, and may not be desireable.
*
* @param string $type A SOAP type.
* @param string $class A PHP class name.
*/
function setTypeTranslation($type, $class = null)
{
$tq = new QName($type);
if (!$class) {
$class = $tq->name;
}
$this->_type_translation[$type]=$class;
}
}
/**
* Class used to handle QNAME values in XML.
*
* @access public
* @package SOAP
* @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates
*/
class QName
{
var $name = '';
var $ns = '';
var $namespace='';
function __construct($name, $namespace = '')
{
if ($name && $name[0] == '{') {
preg_match('/\{(.*?)\}(.*)/', $name, $m);
$this->name = $m[2];
$this->namespace = $m[1];
} elseif (substr_count($name, ':') == 1) {
$s = explode(':', $name);
$s = array_reverse($s);
$this->name = $s[0];
$this->ns = $s[1];
$this->namespace = $namespace;
} else {
$this->name = $name;
$this->namespace = $namespace;
}
// A little more magic than should be in a qname.
$p = strpos($this->name, '[');
if ($p) {
// TODO: Need to re-examine this logic later.
// Chop off [].
$this->arraySize = explode(',', substr($this->name, $p + 1, -$p - 2));
$this->arrayInfo = substr($this->name, $p);
$this->name = substr($this->name, 0, $p);
}
}
function fqn()
{
if ($this->namespace) {
return '{' . $this->namespace . '}' . $this->name;
} elseif ($this->ns) {
return $this->ns . ':' . $this->name;
}
return $this->name;
}
}
diff --git a/library/SOAP/Client.php b/library/SOAP/Client.php
index 9a4f3e0..3535772 100644
--- a/library/SOAP/Client.php
+++ b/library/SOAP/Client.php
@@ -1,855 +1,855 @@
<?php
/**
* This file contains the code for the SOAP client.
*
* PHP versions 4 and 5
*
* LICENSE: 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.
*
* @category Web Services
* @package SOAP
* @author Dietrich Ayala <dietrich@ganx4.com> Original Author
* @author Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more
* @author Chuck Hagenbuch <chuck@horde.org> Maintenance
* @author Jan Schneider <jan@horde.org> Maintenance
* @copyright 2003-2005 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP License 2.02
* @link http://pear.php.net/package/SOAP
*/
require_once 'SOAP/Value.php';
require_once 'SOAP/Base.php';
require_once 'SOAP/Transport.php';
require_once 'SOAP/WSDL.php';
require_once 'SOAP/Fault.php';
require_once 'SOAP/Parser.php';
// Arnaud: the following code was taken from DataObject and adapted to suit
// this will be horrifically slow!!!!
// NOTE: Overload SEGFAULTS ON PHP4 + Zend Optimizer
// these two are BC/FC handlers for call in PHP4/5
if (!class_exists('SOAP_Client_Overload')) {
if (substr(zend_version(), 0, 1) > 1) {
class SOAP_Client_Overload extends SOAP_Base {
function __call($method, $args)
{
$return = null;
$this->_call($method, $args, $return);
return $return;
}
}
} else {
if (!function_exists('clone')) {
eval('function clone($t) { return $t; }');
}
eval('
class SOAP_Client_Overload extends SOAP_Base {
function __call($method, $args, &$return)
{
return $this->_call($method, $args, $return);
}
}');
}
}
/**
* SOAP Client Class
*
* This class is the main interface for making soap requests.
*
* basic usage:<code>
* $soapclient = new SOAP_Client( string path [ , boolean wsdl] );
* echo $soapclient->call( string methodname [ , array parameters] );
* </code>
* or, if using PHP 5+ or the overload extension:<code>
* $soapclient = new SOAP_Client( string path [ , boolean wsdl] );
* echo $soapclient->methodname( [ array parameters] );
* </code>
*
* Originally based on SOAPx4 by Dietrich Ayala
* http://dietrich.ganx4.com/soapx4
*
* @access public
* @package SOAP
* @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates
* @author Stig Bakken <ssb@fast.no> Conversion to PEAR
* @author Dietrich Ayala <dietrich@ganx4.com> Original Author
*/
class SOAP_Client extends SOAP_Client_Overload
{
/**
* Communication endpoint.
*
* Currently the following transport formats are supported:
* - HTTP
* - SMTP
*
* Example endpoints:
* http://www.example.com/soap/server.php
* https://www.example.com/soap/server.php
* mailto:soap@example.com
*
* @see SOAP_Client()
* @var string
*/
var $_endpoint = '';
/**
* The SOAP PORT name that is used by the client.
*
* @var string
*/
var $_portName = '';
/**
* Endpoint type e.g. 'wdsl'.
*
* @var string
*/
var $_endpointType = '';
/**
* The received xml.
*
* @var string
*/
var $xml;
/**
* The outgoing and incoming data stream for debugging.
*
* @var string
*/
var $wire;
/**
* The outgoing data stream for debugging.
*
* @var string
*/
var $_last_request = null;
/**
* The incoming data stream for debugging.
*
* @var string
*/
var $_last_response = null;
/**
* Options.
*
* @var array
*/
var $_options = array('trace' => false);
/**
* The character encoding used for XML parser, etc.
*
* @var string
*/
var $_encoding = SOAP_DEFAULT_ENCODING;
/**
* The array of SOAP_Headers that we are sending.
*
* @var array
*/
var $headersOut = null;
/**
* The headers we recieved back in the response.
*
* @var array
*/
var $headersIn = null;
/**
* Options for the HTTP_Request class (see HTTP/Request.php).
*
* @var array
*/
var $_proxy_params = array();
/**
* The SOAP_Transport instance.
*
* @var SOAP_Transport
*/
var $_soap_transport = null;
/**
* Constructor.
*
* @access public
*
* @param string $endpoint An URL.
* @param boolean $wsdl Whether the endpoint is a WSDL file.
* @param string $portName The service's port name to use.
* @param array $proxy_params Options for the HTTP_Request class
* @see HTTP_Request
* @param boolean|string $cache Use WSDL caching? The cache directory if
* a string.
*/
function __construct($endpoint, $wsdl = false, $portName = false,
$proxy_params = array(), $cache = false)
{
- parent::SOAP_Base('Client');
+ parent::SOAP_Base('Client');
$this->_endpoint = $endpoint;
$this->_portName = $portName;
$this->_proxy_params = $proxy_params;
// This hack should perhaps be removed as it might cause unexpected
// behaviour.
$wsdl = $wsdl
? $wsdl
: strtolower(substr($endpoint, -4)) == 'wsdl';
// make values
if ($wsdl) {
$this->_endpointType = 'wsdl';
// instantiate wsdl class
$this->_wsdl = new SOAP_WSDL($this->_endpoint,
$this->_proxy_params,
$cache);
if ($this->_wsdl->fault) {
$this->_raiseSoapFault($this->_wsdl->fault);
}
}
}
function _reset()
{
$this->xml = null;
$this->wire = null;
$this->_last_request = null;
$this->_last_response = null;
$this->headersIn = null;
$this->headersOut = null;
}
/**
* Sets the character encoding.
*
* Limited to 'UTF-8', 'US_ASCII' and 'ISO-8859-1'.
*
* @access public
*
* @param string encoding
*
* @return mixed SOAP_Fault on error.
*/
function setEncoding($encoding)
{
if (in_array($encoding, $this->_encodings)) {
$this->_encoding = $encoding;
return;
}
return $this->_raiseSoapFault('Invalid Encoding');
}
/**
* Adds a header to the envelope.
*
* @access public
*
* @param SOAP_Header $soap_value A SOAP_Header or an array with the
* elements 'name', 'namespace',
* 'mustunderstand', and 'actor' to send
* as a header.
*/
function addHeader($soap_value)
{
// Add a new header to the message.
if (is_a($soap_value, 'SOAP_Header')) {
$this->headersOut[] = $soap_value;
} elseif (is_array($soap_value)) {
// name, value, namespace, mustunderstand, actor
$this->headersOut[] = new SOAP_Header($soap_value[0],
null,
$soap_value[1],
$soap_value[2],
$soap_value[3]);
} else {
$this->_raiseSoapFault('Invalid parameter provided to addHeader(). Must be an array or a SOAP_Header.');
}
}
/**
* Calls a method on the SOAP endpoint.
*
* The namespace parameter is overloaded to accept an array of options
* that can contain data necessary for various transports if it is used as
* an array, it MAY contain a namespace value and a soapaction value. If
* it is overloaded, the soapaction parameter is ignored and MUST be
* placed in the options array. This is done to provide backwards
* compatibility with current clients, but may be removed in the future.
* The currently supported values are:<pre>
* namespace
* soapaction
* timeout (HTTP socket timeout)
* transfer-encoding (SMTP, Content-Transfer-Encoding: header)
* from (SMTP, From: header)
* subject (SMTP, Subject: header)
* headers (SMTP, hash of extra SMTP headers)
* </pre>
*
* @access public
*
* @param string $method The method to call.
* @param array $params The method parameters.
* @param string|array $namespace Namespace or hash with options.
* @param string $soapAction
*
* @return mixed The method result or a SOAP_Fault on error.
*/
function &call($method, $params, $namespace = false, $soapAction = false)
- {
+ {
$this->headersIn = null;
$this->_last_request = null;
$this->_last_response = null;
$this->wire = null;
$this->xml = null;
- $soap_data = $this->_generate($method, $params, $namespace, $soapAction);
+ $soap_data = $this->_generate($method, $params, $namespace, $soapAction);
+
if ((new PEAR)->isError($soap_data)) {
$fault = $this->_raiseSoapFault($soap_data);
return $fault;
}
// _generate() may have changed the endpoint if the WSDL has more
// than one service, so we need to see if we need to generate a new
// transport to hook to a different URI. Since the transport protocol
// can also change, we need to get an entirely new object. This could
// probably be optimized.
if (!$this->_soap_transport ||
$this->_endpoint != $this->_soap_transport->url) {
$this->_soap_transport =& SOAP_Transport::getTransport($this->_endpoint);
if ((new PEAR)->isError($this->_soap_transport)) {
$fault =& $this->_soap_transport;
$this->_soap_transport = null;
$fault = $this->_raiseSoapFault($fault);
return $fault;
}
}
$this->_soap_transport->encoding = $this->_encoding;
// Send the message.
$transport_options = array_merge_recursive($this->_proxy_params,
$this->_options);
$this->xml = $this->_soap_transport->send($soap_data, $transport_options);
// Save the wire information for debugging.
if ($this->_options['trace']) {
$this->_last_request = $this->_soap_transport->outgoing_payload;
$this->_last_response = $this->_soap_transport->incoming_payload;
$this->wire = $this->getWire();
}
if ($this->_soap_transport->fault) {
$fault = $this->_raiseSoapFault($this->xml);
return $fault;
}
if (isset($this->_options['result']) &&
$this->_options['result'] != 'parse') {
return $this->xml;
}
- $this->__result_encoding = $this->_soap_transport->result_encoding;
+ $this->__result_encoding = $this->_soap_transport->result_encoding;
$result = &$this->parseResponse($this->xml, $this->__result_encoding,
$this->_soap_transport->attachments);
return $result;
}
/**
* Sets an option to use with the transport layers.
*
* For example:
* <code>
* $soapclient->setOpt('curl', CURLOPT_VERBOSE, 1)
* </code>
* to pass a specific option to curl if using an SSL connection.
*
* @access public
*
* @param string $category Category to which the option applies or option
* name.
* @param string $option An option name if $category is a category name,
* an option value if $category is an option name.
* @param string $value An option value if $category is a category
* name.
*/
function setOpt($category, $option, $value = null)
{
if (!is_null($value)) {
if (!isset($this->_options[$category])) {
$this->_options[$category] = array();
}
$this->_options[$category][$option] = $value;
} else {
$this->_options[$category] = $option;
}
}
/**
* Call method supporting the overload extension.
*
* If the overload extension is loaded, you can call the client class with
* a soap method name:
* <code>
* $soap = new SOAP_Client(....);
* $value = $soap->getStockQuote('MSFT');
* </code>
*
* @access public
*
* @param string $method The method to call.
* @param array $params The method parameters.
* @param mixed $return_value Will get the method's return value
* assigned.
*
* @return boolean Always true.
*/
function _call($method, $params, &$return_value)
{
// Overloading lowercases the method name, we need to look into the
// WSDL and try to find the correct method name to get the correct
// case for the call.
if ($this->_wsdl) {
$this->_wsdl->matchMethod($method);
}
$return_value =& $this->call($method, $params);
return true;
}
/**
* @deprecated Use getLastRequest().
*/
function &__getlastrequest()
{
$request = $this->getLastRequest();
return $request;
}
/**
* Returns the XML content of the last SOAP request.
*
* @return string The last request.
*/
function getLastRequest()
{
return $this->_last_request;
}
/**
* @deprecated Use getLastResponse().
*/
function &__getlastresponse()
{
$response =& $this->getLastResponse;
return $response;
}
/**
* Returns the XML content of the last SOAP response.
*
* @return string The last response.
*/
function getLastResponse()
{
return $this->_last_response;
}
/**
* @deprecated Use setUse().
*/
function __use($use)
{
$this->setUse($use);
}
/**
* Sets the SOAP encoding.
*
* @param string $use Either 'literal' or 'encoded' (section 5).
*/
function setUse($use)
{
$this->_options['use'] = $use;
}
/**
* @deprecated Use setStyle().
*/
function __style($style)
{
$this->setStyle($style);
}
/**
* Sets the SOAP encoding style.
*
* @param string $style Either 'document' or 'rpc'.
*/
function setStyle($style)
{
$this->_options['style'] = $style;
}
/**
* @deprecated Use setTrace().
*/
function __trace($level)
{
$this->setTrace($level);
}
/**
* Sets whether to trace the traffic on the transport level.
*
* @see getWire()
*
* @param boolean $trace
*/
function setTrace($trace)
{
$this->_options['trace'] = $trace;
}
function _generate($method, &$params, $namespace = false,
$soapAction = false)
{
$this->fault = null;
$this->_options['input'] = 'parse';
$this->_options['result'] = 'parse';
$this->_options['parameters'] = false;
if ($params && gettype($params) != 'array') {
$params = array($params);
- }
+ }
if (gettype($namespace) == 'array') {
foreach ($namespace as $optname => $opt) {
$this->_options[strtolower($optname)] = $opt;
}
if (isset($this->_options['namespace'])) {
$namespace = $this->_options['namespace'];
} else {
$namespace = false;
}
} else {
// We'll place $soapAction into our array for usage in the
// transport.
$this->_options['soapaction'] = $soapAction;
$this->_options['namespace'] = $namespace;
}
if ($this->_endpointType == 'wsdl') {
$this->_setSchemaVersion($this->_wsdl->xsd);
// Get port name.
if (!$this->_portName) {
$this->_portName = $this->_wsdl->getPortName($method);
}
if ((new PEAR)->isError($this->_portName)) {
return $this->_raiseSoapFault($this->_portName);
}
// Get endpoint.
$this->_endpoint = $this->_wsdl->getEndpoint($this->_portName);
if ((new PEAR)->isError($this->_endpoint)) {
return $this->_raiseSoapFault($this->_endpoint);
}
// Get operation data.
$opData = $this->_wsdl->getOperationData($this->_portName, $method);
if ((new PEAR)->isError($opData)) {
return $this->_raiseSoapFault($opData);
}
$namespace = $opData['namespace'];
$this->_options['style'] = $opData['style'];
$this->_options['use'] = $opData['input']['use'];
$this->_options['soapaction'] = $opData['soapAction'];
// Set input parameters.
if ($this->_options['input'] == 'parse') {
$this->_options['parameters'] = $opData['parameters'];
$nparams = array();
if (isset($opData['input']['parts']) &&
count($opData['input']['parts'])) {
foreach ($opData['input']['parts'] as $name => $part) {
$xmlns = '';
$attrs = array();
// Is the name a complex type?
if (isset($part['element'])) {
$xmlns = $this->_wsdl->namespaces[$part['namespace']];
$part = $this->_wsdl->elements[$part['namespace']][$part['type']];
$name = $part['name'];
}
if (isset($params[$name]) ||
$this->_wsdl->getDataHandler($name, $part['namespace'])) {
$nparams[$name] =& $params[$name];
} else {
// We now force an associative array for
// parameters if using WSDL.
return $this->_raiseSoapFault("The named parameter $name is not in the call parameters.");
}
if (gettype($nparams[$name]) != 'object' ||
!is_a($nparams[$name], 'SOAP_Value')) {
// Type is likely a qname, split it apart, and get
// the type namespace from WSDL.
$qname = new QName($part['type']);
if ($qname->ns) {
$type_namespace = $this->_wsdl->namespaces[$qname->ns];
} elseif (isset($part['namespace'])) {
$type_namespace = $this->_wsdl->namespaces[$part['namespace']];
} else {
$type_namespace = null;
}
$qname->namespace = $type_namespace;
$pqname = $name;
if ($xmlns) {
$pqname = '{' . $xmlns . '}' . $name;
}
$nparams[$name] = new SOAP_Value($pqname,
$qname->fqn(),
$nparams[$name],
$attrs);
} else {
// WSDL fixups to the SOAP value.
}
}
}
$params =& $nparams;
unset($nparams);
}
} else {
$this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION);
}
// Serialize the message.
$this->_section5 = (!isset($this->_options['use']) ||
$this->_options['use'] != 'literal');
if (!isset($this->_options['style']) ||
$this->_options['style'] == 'rpc') {
$this->_options['style'] = 'rpc';
$this->docparams = true;
$mqname = new QName($method, $namespace);
$methodValue = new SOAP_Value($mqname->fqn(), 'Struct', $params);
$soap_msg = $this->makeEnvelope($methodValue,
$this->headersOut,
$this->_encoding,
$this->_options);
} else {
if (!$params) {
$mqname = new QName($method, $namespace);
$mynull = null;
$params = new SOAP_Value($mqname->fqn(), 'Struct', $mynull);
} elseif ($this->_options['input'] == 'parse') {
if (is_array($params)) {
$nparams = array();
$keys = array_keys($params);
foreach ($keys as $k) {
if (gettype($params[$k]) != 'object') {
$nparams[] = new SOAP_Value($k,
false,
$params[$k]);
} else {
$nparams[] =& $params[$k];
}
}
$params =& $nparams;
}
if ($this->_options['parameters']) {
$mqname = new QName($method, $namespace);
$params = new SOAP_Value($mqname->fqn(),
'Struct',
$params);
}
}
$soap_msg = $this->makeEnvelope($params,
$this->headersOut,
$this->_encoding,
$this->_options);
}
unset($this->headersOut);
if ((new PEAR)->isError($soap_msg)) {
return $this->_raiseSoapFault($soap_msg);
}
// Handle MIME or DIME encoding.
// TODO: DIME encoding should move to the transport, do it here for
// now and for ease of getting it done.
if (count($this->_attachments)) {
if ((isset($this->_options['attachments']) &&
$this->_options['attachments'] == 'Mime') ||
isset($this->_options['Mime'])) {
$soap_msg = $this->_makeMimeMessage($soap_msg, $this->_encoding);
} else {
// default is dime
$soap_msg = $this->_makeDIMEMessage($soap_msg, $this->_encoding);
$this->_options['headers']['Content-Type'] = 'application/dime';
}
if ((new PEAR)->isError($soap_msg)) {
return $this->_raiseSoapFault($soap_msg);
}
}
// Instantiate client.
if (is_array($soap_msg)) {
$soap_data = $soap_msg['body'];
if (count($soap_msg['headers'])) {
if (isset($this->_options['headers'])) {
$this->_options['headers'] = array_merge($this->_options['headers'], $soap_msg['headers']);
} else {
$this->_options['headers'] = $soap_msg['headers'];
}
}
} else {
$soap_data = $soap_msg;
- }
-
+ }
return $soap_data;
}
/**
* @deprecated Use parseResponse().
*/
function &__parse(&$response, $encoding, &$attachments)
{
return $this->parseResponse($response, $encoding, $attachments);
}
/**
* Parses a SOAP response.
*
* @see SOAP_Parser::
*
* @param string $response XML content of SOAP response.
* @param string $encoding Character set encoding, defaults to 'UTF-8'.
* @param array $attachments List of attachments.
*/
function &parseResponse($response, $encoding, &$attachments)
{
// Parse the response.
$response =new SOAP_Parser($response, $encoding, $attachments);
if ($response->fault) {
$fault = $this->_raiseSoapFault($response->fault);
return $fault;
}
-
// Return array of parameters.
$return = $response->getResponse();
$headers = $response->getHeaders();
if ($headers) {
$this->headersIn = $this->_decodeResponse($headers, false);
}
- $decoded = $this->_decodeResponse($return);
+ $decoded = $this->_decodeResponse($return);
+
return $decoded;
}
/**
* Converts a complex SOAP_Value into a PHP Array
*
* @param SOAP_Value $response value object
* @param boolean $shift FIXME
* @return Array
*/
function &_decodeResponse($response, $shift = true)
{
if (!$response) {
$decoded = null;
return $decoded;
}
// Check for valid response.
if ((new PEAR)->isError($response)) {
$fault =& $this->_raiseSoapFault($response);
return $fault;
} elseif (!is_a($response, 'soap_value')) {
$fault =& $this->_raiseSoapFault("Didn't get SOAP_Value object back from client");
return $fault;
}
// Decode to native php datatype.
$returnArray =& $this->_decode($response);
// Fault?
if ((new PEAR)->isError($returnArray)) {
$fault =& $this->_raiseSoapFault($returnArray);
return $fault;
}
if (is_object($returnArray) &&
strcasecmp(get_class($returnArray), 'stdClass') == 0) {
$returnArray = get_object_vars($returnArray);
}
if (is_array($returnArray)) {
if (isset($returnArray['faultcode']) ||
isset($returnArray['SOAP-ENV:faultcode'])) {
$faultcode = $faultstring = $faultdetail = $faultactor = '';
foreach ($returnArray as $k => $v) {
if (stristr($k, 'faultcode')) $faultcode = $v;
if (stristr($k, 'faultstring')) $faultstring = $v;
if (stristr($k, 'detail')) $faultdetail = $v;
if (stristr($k, 'faultactor')) $faultactor = $v;
}
$fault =& $this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode);
return $fault;
}
// Return array of return values.
if ($shift && count($returnArray) == 1) {
$decoded = array_shift($returnArray);
return $decoded;
}
return $returnArray;
}
return $returnArray;
}
/**
* @deprecated Use getWire().
*/
function __get_wire()
{
return $this->getWire();
}
/**
* Returns the outgoing and incoming traffic on the transport level.
*
* Tracing has to be enabled.
*
* @see setTrace()
*
* @return string The complete traffic between the client and the server.
*/
function getWire()
{
if ($this->_options['trace'] &&
($this->_last_request || $this->_last_response)) {
return "OUTGOING:\n\n" .
$this->_last_request .
"\n\nINCOMING\n\n" .
preg_replace("/></",">\r\n<", $this->_last_response);
}
return null;
}
}
diff --git a/library/SOAP/Transport.php b/library/SOAP/Transport.php
index c94d36c..5a79140 100644
--- a/library/SOAP/Transport.php
+++ b/library/SOAP/Transport.php
@@ -1,151 +1,152 @@
<?php
/**
* This file contains the code for an abstract transport layer.
*
* PHP versions 4 and 5
*
* LICENSE: 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.
*
* @category Web Services
* @package SOAP
* @author Dietrich Ayala <dietrich@ganx4.com>
* @author Shane Caraveo <Shane@Caraveo.com>
* @author Jan Schneider <jan@horde.org>
* @copyright 2003-2006 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP License 2.02
* @link http://pear.php.net/package/SOAP
*/
require_once 'SOAP/Base.php';
/**
* SOAP Transport Layer
*
* This layer can use different protocols dependant on the endpoint url
* provided.
*
* No knowlege of the SOAP protocol is available at this level.
* No knowlege of the transport protocols is available at this level.
*
* @access public
* @package SOAP
* @author Shane Caraveo <shane@php.net>
* @author Jan Schneider <jan@horde.org>
*/
class SOAP_Transport extends SOAP_Base
{
/**
* Connection endpoint URL.
*
* @var string
*/
var $url = '';
/**
* Array containing urlparts.
*
* @see parse_url()
*
* @var mixed
*/
var $urlparts = null;
/**
* Incoming payload.
*
* @var string
*/
var $incoming_payload = '';
/**
* Outgoing payload.
*
* @var string
*/
var $outgoing_payload = '';
/**
* Request encoding.
*
* @var string
*/
var $encoding = SOAP_DEFAULT_ENCODING;
/**
* Response encoding.
*
* We assume UTF-8 if no encoding is set.
*
* @var string
*/
var $result_encoding = 'UTF-8';
/**
* Decoded attachments from the reponse.
*
* @var array
*/
var $attachments;
/**
* Request User-Agent.
*
* @var string
*/
var $_userAgent = SOAP_LIBRARY_NAME;
/**
* Sends and receives SOAP data.
*
* @access public
* @abstract
*
* @param string Outgoing SOAP data.
* @param array Options.
*
* @return string|SOAP_Fault
*/
function send($msg, $options = null)
{
return $this->_raiseSoapFault('SOAP_Transport::send() not implemented.');
}
static function &getTransport($url, $encoding = SOAP_DEFAULT_ENCODING)
{
$urlparts = @parse_url($url);
if (!$urlparts['scheme']) {
- $fault = SOAP_Base_Object::_raiseSoapFault("Invalid transport URI: $url");
+ $soap_base = new SOAP_Base_Object();
+ $fault = $soap_base->_raiseSoapFault("Invalid transport URI: $url");
return $fault;
}
if (strcasecmp($urlparts['scheme'], 'mailto') == 0) {
$transport_type = 'SMTP';
} elseif (strcasecmp($urlparts['scheme'], 'https') == 0) {
$transport_type = 'HTTP';
} else {
/* Handle other transport types */
$transport_type = strtoupper($urlparts['scheme']);
}
$transport_include = 'SOAP/Transport/' . basename($transport_type) . '.php';
$res = @include_once($transport_include);
if (!$res) {
$fault = SOAP_Base_Object::_raiseSoapFault("No Transport for {$urlparts['scheme']}");
return $fault;
}
$transport_class = "SOAP_Transport_$transport_type";
if (!class_exists($transport_class)) {
$fault = SOAP_Base_Object::_raiseSoapFault("No Transport class $transport_class");
return $fault;
}
$t =new $transport_class($url, $encoding);
return $t;
}
}
diff --git a/library/SOAP/Transport/HTTP.php b/library/SOAP/Transport/HTTP.php
index b47ccea..0e1924c 100644
--- a/library/SOAP/Transport/HTTP.php
+++ b/library/SOAP/Transport/HTTP.php
@@ -1,620 +1,621 @@
<?php
/**
* This file contains the code for a HTTP transport layer.
*
* PHP versions 4 and 5
*
* LICENSE: 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.
*
* @category Web Services
* @package SOAP
* @author Shane Caraveo <Shane@Caraveo.com>
* @author Jan Schneider <jan@horde.org>
* @copyright 2003-2006 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP License 2.02
* @link http://pear.php.net/package/SOAP
*/
/**
* HTTP Transport class
*
* @package SOAP
* @category Web_Services
*/
/**
* Needed Classes
*/
require_once 'SOAP/Transport.php';
/**
* HTTP Transport for SOAP
*
* @access public
* @package SOAP
* @author Shane Caraveo <shane@php.net>
* @author Jan Schneider <jan@horde.org>
*/
class SOAP_Transport_HTTP extends SOAP_Transport
{
/**
* Basic Auth string.
*
* @var array
*/
var $headers = array();
/**
* Cookies.
*
* @var array
*/
var $cookies;
/**
* Connection timeout in seconds. 0 = none.
*
* @var integer
*/
var $timeout = 4;
/**
* HTTP-Response Content-Type.
*/
var $result_content_type;
var $result_headers = array();
var $result_cookies = array();
/**
* SOAP_Transport_HTTP Constructor
*
* @access public
*
* @param string $url HTTP url to SOAP endpoint.
* @param string $encoding Encoding to use.
*/
function __construct($url, $encoding = SOAP_DEFAULT_ENCODING)
{
parent::SOAP_Base('HTTP');
$this->urlparts = @parse_url($url);
$this->url = $url;
$this->encoding = $encoding;
}
/**
* Sends and receives SOAP data.
*
* @access public
*
* @param string Outgoing SOAP data.
* @param array Options.
*
* @return string|SOAP_Fault
*/
function send($msg, $options = array())
{
$this->fault = null;
if (!$this->_validateUrl()) {
return $this->fault;
}
if (isset($options['timeout'])) {
$this->timeout = (int)$options['timeout'];
}
- if (strcasecmp($this->urlparts['scheme'], 'HTTP') == 0) {
+ if (strcasecmp($this->urlparts['scheme'], 'HTTP') == 0) {
return $this->_sendHTTP($msg, $options);
} elseif (strcasecmp($this->urlparts['scheme'], 'HTTPS') == 0) {
return $this->_sendHTTPS($msg, $options);
}
return $this->_raiseSoapFault('Invalid url scheme ' . $this->url);
}
/**
* Sets data for HTTP authentication, creates authorization header.
*
* @param string $username Username.
* @param string $password Response data, minus HTTP headers.
*
* @access public
*/
function setCredentials($username, $password)
{
$this->headers['Authorization'] = 'Basic ' . base64_encode($username . ':' . $password);
}
/**
* Adds a cookie.
*
* @access public
* @param string $name Cookie name.
* @param mixed $value Cookie value.
*/
function addCookie($name, $value)
{
$this->cookies[$name] = $value;
}
/**
* Generates the correct headers for the cookies.
*
* @access private
*
* @param array $options Cookie options. If 'nocookies' is set and true
* the cookies from the last response are added
* automatically. 'cookies' is name-value-hash with
* a list of cookies to add.
*
* @return string The cookie header value.
*/
function _generateCookieHeader($options)
{
$this->cookies = array();
if (empty($options['nocookies']) &&
isset($this->result_cookies)) {
// Add the cookies we got from the last request.
foreach ($this->result_cookies as $cookie) {
if ($cookie['domain'] == $this->urlparts['host']) {
$this->cookies[$cookie['name']] = $cookie['value'];
}
}
}
// Add cookies the user wants to set.
if (isset($options['cookies'])) {
foreach ($options['cookies'] as $cookie) {
if ($cookie['domain'] == $this->urlparts['host']) {
$this->cookies[$cookie['name']] = $cookie['value'];
}
}
}
$cookies = '';
foreach ($this->cookies as $name => $value) {
if (!empty($cookies)) {
$cookies .= '; ';
}
$cookies .= urlencode($name) . '=' . urlencode($value);
}
return $cookies;
}
/**
* Validate url data passed to constructor.
*
* @access private
* @return boolean
*/
function _validateUrl()
{
if (!is_array($this->urlparts) ) {
$this->_raiseSoapFault('Unable to parse URL ' . $this->url);
return false;
}
if (!isset($this->urlparts['host'])) {
$this->_raiseSoapFault('No host in URL ' . $this->url);
return false;
}
if (!isset($this->urlparts['port'])) {
if (strcasecmp($this->urlparts['scheme'], 'HTTP') == 0) {
$this->urlparts['port'] = 80;
} elseif (strcasecmp($this->urlparts['scheme'], 'HTTPS') == 0) {
$this->urlparts['port'] = 443;
}
}
if (isset($this->urlparts['user'])) {
$this->setCredentials(urldecode($this->urlparts['user']),
urldecode($this->urlparts['pass']));
}
if (!isset($this->urlparts['path']) || !$this->urlparts['path']) {
$this->urlparts['path'] = '/';
}
return true;
}
/**
* Finds out what the encoding is.
* Sets the object property accordingly.
*
* @access private
* @param array $headers Headers.
*/
function _parseEncoding($headers)
{
$h = stristr($headers, 'Content-Type');
preg_match_all('/^Content-Type:\s*(.*)$/im', $h, $ct, PREG_SET_ORDER);
$n = count($ct);
$ct = $ct[$n - 1];
// Strip the string of \r.
$this->result_content_type = str_replace("\r", '', $ct[1]);
if (preg_match('/(.*?)(?:;\s?charset=)(.*)/i',
$this->result_content_type,
$m)) {
$this->result_content_type = $m[1];
if (count($m) > 2) {
$enc = strtoupper(str_replace('"', '', $m[2]));
if (in_array($enc, $this->_encodings)) {
$this->result_encoding = $enc;
}
}
}
// Deal with broken servers that don't set content type on faults.
if (!$this->result_content_type) {
$this->result_content_type = 'text/xml';
}
}
/**
* Parses the headers.
*
* @param array $headers The headers.
*/
function _parseHeaders($headers)
{
/* Largely borrowed from HTTP_Request. */
$this->result_headers = array();
$headers = preg_split("/\r?\n/", $headers);
foreach ($headers as $value) {
if (strpos($value,':') === false) {
$this->result_headers[0] = $value;
continue;
}
list($name, $value) = preg_split('/:/', $value);
$headername = strtolower($name);
$headervalue = trim($value);
$this->result_headers[$headername] = $headervalue;
if ($headername == 'set-cookie') {
// Parse a SetCookie header to fill _cookies array.
$cookie = array('expires' => null,
'domain' => $this->urlparts['host'],
'path' => null,
'secure' => false);
if (!strpos($headervalue, ';')) {
// Only a name=value pair.
list($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $headervalue));
$cookie['name'] = urldecode($cookie['name']);
$cookie['value'] = urldecode($cookie['value']);
} else {
// Some optional parameters are supplied.
$elements = explode(';', $headervalue);
list($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $elements[0]));
$cookie['name'] = urldecode($cookie['name']);
$cookie['value'] = urldecode($cookie['value']);
for ($i = 1; $i < count($elements);$i++) {
list($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));
if ('secure' == $elName) {
$cookie['secure'] = true;
} elseif ('expires' == $elName) {
$cookie['expires'] = str_replace('"', '', $elValue);
} elseif ('path' == $elName OR 'domain' == $elName) {
$cookie[$elName] = urldecode($elValue);
} else {
$cookie[$elName] = $elValue;
}
}
}
$this->result_cookies[] = $cookie;
}
}
}
/**
* Removes HTTP headers from response.
*
* @return boolean
* @access private
*/
function _parseResponse()
{
if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s",
$this->incoming_payload,
$match)) {
- $this->response = $match[2];
+ $this->response = $match[2];
// Find the response error, some servers response with 500 for
// SOAP faults.
- $this->_parseHeaders($match[1]);
+ $this->_parseHeaders($match[1]);
list(, $code, $msg) = sscanf($this->result_headers[0], '%s %s %s');
- unset($this->result_headers[0]);
+ unset($this->result_headers[0]);
switch($code) {
case 100: // Continue
$this->incoming_payload = $match[2];
return $this->_parseResponse();
case 400:
$this->_raiseSoapFault("HTTP Response $code Bad Request");
return false;
break;
case 401:
$this->_raiseSoapFault("HTTP Response $code Authentication Failed");
return false;
break;
case 403:
$this->_raiseSoapFault("HTTP Response $code Forbidden");
return false;
break;
case 404:
$this->_raiseSoapFault("HTTP Response $code Not Found");
return false;
break;
case 407:
$this->_raiseSoapFault("HTTP Response $code Proxy Authentication Required");
return false;
break;
case 408:
$this->_raiseSoapFault("HTTP Response $code Request Timeout");
return false;
break;
case 410:
$this->_raiseSoapFault("HTTP Response $code Gone");
return false;
break;
default:
if ($code >= 400 && $code < 500) {
$this->_raiseSoapFault("HTTP Response $code Not Found, Server message: $msg");
return false;
}
}
$this->_parseEncoding($match[1]);
if ($this->result_content_type == 'application/dime') {
// XXX quick hack insertion of DIME
if (PEAR::isError($this->_decodeDIMEMessage($this->response, $this->headers, $this->attachments))) {
// _decodeDIMEMessage already raised $this->fault
return false;
}
$this->result_content_type = $this->headers['content-type'];
} elseif (stristr($this->result_content_type, 'multipart/related')) {
$this->response = $this->incoming_payload;
if (PEAR::isError($this->_decodeMimeMessage($this->response, $this->headers, $this->attachments))) {
// _decodeMimeMessage already raised $this->fault
return false;
}
} elseif ($this->result_content_type != 'text/xml') {
$this->_raiseSoapFault($this->response);
return false;
}
// if no content, return false
return strlen($this->response) > 0;
}
$this->_raiseSoapFault('Invalid HTTP Response');
return false;
}
/**
* Creates an HTTP request, including headers, for the outgoing request.
*
* @access private
*
* @param string $msg Outgoing SOAP package.
* @param array $options Options.
*
* @return string Outgoing payload.
*/
function _getRequest($msg, $options)
{
$this->headers = array();
$action = isset($options['soapaction']) ? $options['soapaction'] : '';
$fullpath = $this->urlparts['path'];
if (isset($this->urlparts['query'])) {
$fullpath .= '?' . $this->urlparts['query'];
}
if (isset($this->urlparts['fragment'])) {
$fullpath .= '#' . $this->urlparts['fragment'];
}
if (isset($options['proxy_host'])) {
$fullpath = 'http://' . $this->urlparts['host'] . ':' .
$this->urlparts['port'] . $fullpath;
}
if (isset($options['proxy_user'])) {
$this->headers['Proxy-Authorization'] = 'Basic ' .
base64_encode($options['proxy_user'] . ':' .
$options['proxy_pass']);
}
if (isset($options['user'])) {
$this->setCredentials($options['user'], $options['pass']);
}
$this->headers['User-Agent'] = $this->_userAgent;
$this->headers['Host'] = $this->urlparts['host'];
$this->headers['Content-Type'] = "text/xml; charset=$this->encoding";
$this->headers['Content-Length'] = strlen($msg);
$this->headers['SOAPAction'] = '"' . $action . '"';
$this->headers['Connection'] = 'close';
if (isset($options['headers'])) {
$this->headers = array_merge($this->headers, $options['headers']);
}
$cookies = $this->_generateCookieHeader($options);
if ($cookies) {
$this->headers['Cookie'] = $cookies;
}
$headers = '';
foreach ($this->headers as $k => $v) {
$headers .= "$k: $v\r\n";
}
$this->outgoing_payload = "POST $fullpath HTTP/1.0\r\n" . $headers .
"\r\n" . $msg;
return $this->outgoing_payload;
}
/**
* Sends the outgoing HTTP request and reads and parses the response.
*
* @access private
*
* @param string $msg Outgoing SOAP package.
* @param array $options Options.
*
* @return string Response data without HTTP headers.
*/
function _sendHTTP($msg, $options)
{
$this->incoming_payload = '';
$this->_getRequest($msg, $options);
$host = $this->urlparts['host'];
$port = $this->urlparts['port'];
if (isset($options['proxy_host'])) {
$host = $options['proxy_host'];
$port = isset($options['proxy_port']) ? $options['proxy_port'] : 8080;
- }
+ }
+
// Send.
if ($this->timeout > 0) {
$fp = @fsockopen($host, $port, $this->errno, $this->errmsg, $this->timeout);
} else {
$fp = @fsockopen($host, $port, $this->errno, $this->errmsg);
}
if (!$fp) {
return $this->_raiseSoapFault("Connect Error to $host:$port");
}
if ($this->timeout > 0) {
// some builds of PHP do not support this, silence the warning
@socket_set_timeout($fp, $this->timeout);
}
if (!fputs($fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
return $this->_raiseSoapFault("Error POSTing Data to $host");
- }
+ }
// get reponse
// XXX time consumer
do {
$data = fread($fp, 4096);
$_tmp_status = socket_get_status($fp);
- if ($_tmp_status['timed_out']) {
+ if ($_tmp_status['timed_out']) {
return $this->_raiseSoapFault("Timed out read from $host");
} else {
$this->incoming_payload .= $data;
}
} while (!$_tmp_status['eof']);
fclose($fp);
if (!$this->_parseResponse()) {
return $this->fault;
}
return $this->response;
}
/**
* Sends the outgoing HTTPS request and reads and parses the response.
*
* @access private
*
* @param string $msg Outgoing SOAP package.
* @param array $options Options.
*
* @return string Response data without HTTP headers.
*/
function _sendHTTPS($msg, $options)
{
/* Check if the required curl extension is installed. */
if (!extension_loaded('curl')) {
return $this->_raiseSoapFault('CURL Extension is required for HTTPS');
}
$ch = curl_init();
if (isset($options['proxy_host'])) {
$port = isset($options['proxy_port']) ? $options['proxy_port'] : 8080;
curl_setopt($ch, CURLOPT_PROXY,
$options['proxy_host'] . ':' . $port);
}
if (isset($options['proxy_user'])) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD,
$options['proxy_user'] . ':' . $options['proxy_pass']);
}
if (isset($options['user'])) {
curl_setopt($ch, CURLOPT_USERPWD,
$options['user'] . ':' . $options['pass']);
}
if (!isset($options['soapaction'])) {
$options['soapaction'] = '';
}
if (!isset($options['headers']['Content-Type'])) {
$options['headers']['Content-Type'] = 'text/xml';
}
curl_setopt($ch, CURLOPT_HTTPHEADER,
array('Content-Type: ' . $options['headers']['Content-Type']
. ';charset=' . $this->encoding,
'SOAPAction: "' . $options['soapaction'] . '"'));
curl_setopt($ch, CURLOPT_USERAGENT,
$this->_userAgent);
if ($this->timeout) {
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
if (defined('CURLOPT_HTTP_VERSION')) {
curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
}
if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
}
$cookies = $this->_generateCookieHeader($options);
if ($cookies) {
curl_setopt($ch, CURLOPT_COOKIE, $cookies);
}
if (isset($options['curl'])) {
foreach ($options['curl'] as $key => $val) {
curl_setopt($ch, $key, $val);
}
}
// Save the outgoing XML. This doesn't quite match _sendHTTP as CURL
// generates the headers, but having the XML is usually the most
// important part for tracing/debugging.
$this->outgoing_payload = $msg;
$this->incoming_payload = curl_exec($ch);
if (!$this->incoming_payload) {
$m = 'curl_exec error ' . curl_errno($ch) . ' ' . curl_error($ch);
curl_close($ch);
return $this->_raiseSoapFault($m);
}
curl_close($ch);
if (!$this->_parseResponse()) {
return $this->fault;
}
return $this->response;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 26, 4:45 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3414143
Default Alt Text
(93 KB)

Event Timeline