Skip to content

Instantly share code, notes, and snippets.

@isc30
Last active Jul 25, 2016
Embed
What would you like to do?
Install DnsUpdater for Arsys
#!/bin/bash
if [ "$(whoami)" != "root" ]; then
echo "Run script as ROOT please. (sudo !!)"
exit
fi
apt-get update -y
apt-get install -t stretch -y php7.0-soap
apt-get autoremove -y
mkdir -p /usr/share/dnsUpdater
cat > /usr/share/dnsUpdater/nusoap.php << "EOF"
<?php
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = 9;
class nusoap_base
{
var $title = 'NuSOAP';
var $version = '0.9.6';
var $revision = '$Revision: 1.124 $';
var $error_str = '';
var $debug_str = '';
var $charencoding = true;
var $debugLevel;
var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
var $soap_defencoding = 'ISO-8859-1';
var $namespaces = array('SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', 'xsd' => 'http://www.w3.org/2001/XMLSchema', 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/');
var $usedNamespaces = array();
var $typemap = array('http://www.w3.org/2001/XMLSchema' => array('string' => 'string', 'boolean' => 'boolean', 'float' => 'double', 'double' => 'double', 'decimal' => 'double', 'duration' => '', 'dateTime' => 'string', 'time' => 'string', 'date' => 'string', 'gYearMonth' => '', 'gYear' => '', 'gMonthDay' => '', 'gDay' => '', 'gMonth' => '', 'hexBinary' => 'string', 'base64Binary' => 'string', 'anyType' => 'string', 'anySimpleType' => 'string', 'normalizedString' => 'string', 'token' => 'string', 'language' => '', 'NMTOKEN' => '', 'NMTOKENS' => '', 'Name' => '', 'NCName' => '', 'ID' => '', 'IDREF' => '', 'IDREFS' => '', 'ENTITY' => '', 'ENTITIES' => '', 'integer' => 'integer', 'nonPositiveInteger' => 'integer', 'negativeInteger' => 'integer', 'long' => 'integer', 'int' => 'integer', 'short' => 'integer', 'byte' => 'integer', 'nonNegativeInteger' => 'integer', 'unsignedLong' => '', 'unsignedInt' => '', 'unsignedShort' => '', 'unsignedByte' => '', 'positiveInteger' => ''), 'http://www.w3.org/2000/10/XMLSchema' => array('i4' => '', 'int' => 'integer', 'boolean' => 'boolean', 'string' => 'string', 'double' => 'double', 'float' => 'double', 'dateTime' => 'string', 'timeInstant' => 'string', 'base64Binary' => 'string', 'base64' => 'string', 'ur-type' => 'array'), 'http://www.w3.org/1999/XMLSchema' => array('i4' => '', 'int' => 'integer', 'boolean' => 'boolean', 'string' => 'string', 'double' => 'double', 'float' => 'double', 'dateTime' => 'string', 'timeInstant' => 'string', 'base64Binary' => 'string', 'base64' => 'string', 'ur-type' => 'array'), 'http://soapinterop.org/xsd' => array('SOAPStruct' => 'struct'), 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64' => 'string', 'array' => 'array', 'Array' => 'array'), 'http://xml.apache.org/xml-soap' => array('Map'));
var $xmlEntities = array('quot' => '"', 'amp' => '&', 'lt' => '<', 'gt' => '>', 'apos' => "'");
function nusoap_base()
{
$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
}
function getGlobalDebugLevel()
{
return $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
}
function setGlobalDebugLevel($level)
{
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = $level;
}
function getDebugLevel()
{
return $this->debugLevel;
}
function setDebugLevel($level)
{
$this->debugLevel = $level;
}
function debug($string)
{
if($this->debugLevel > 0) {
$this->appendDebug($this->getmicrotime() . ' ' . get_class($this) . ": $string\n");
}
}
function appendDebug($string)
{
if($this->debugLevel > 0) {
$this->debug_str .= $string;
}
}
function clearDebug()
{
$this->debug_str = '';
}
function &getDebug()
{
return $this->debug_str;
}
function &getDebugAsXMLComment()
{
while(strpos($this->debug_str, '--')) {
$this->debug_str = str_replace('--', '- -', $this->debug_str);
}
$ret = "<!--\n" . $this->debug_str . "\n-->";
return $ret;
}
function expandEntities($val)
{
if($this->charencoding) {
$val = str_replace('&', '&amp;', $val);
$val = str_replace("'", '&apos;', $val);
$val = str_replace('"', '&quot;', $val);
$val = str_replace('<', '&lt;', $val);
$val = str_replace('>', '&gt;', $val);
}
return $val;
}
function getError()
{
if($this->error_str != '') {
return $this->error_str;
}
return false;
}
function setError($str)
{
$this->error_str = $str;
}
function isArraySimpleOrStruct($val)
{
$keyList = array_keys($val);
foreach($keyList as $keyListValue) {
if(!is_int($keyListValue)) {
return 'arrayStruct';
}
}
return 'arraySimple';
}
function serialize_val($val, $name = false, $type = false, $name_ns = false, $type_ns = false, $attributes = false, $use = 'encoded', $soapval = false)
{
$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
$this->appendDebug('value=' . $this->varDump($val));
$this->appendDebug('attributes=' . $this->varDump($attributes));
if(is_object($val) && get_class($val) == 'soapval' && (!$soapval)) {
$this->debug("serialize_val: serialize soapval");
$xml = $val->serialize($use);
$this->appendDebug($val->getDebug());
$val->clearDebug();
$this->debug("serialize_val of soapval returning $xml");
return $xml;
}
if(is_numeric($name)) {
$name = '__numeric_' . $name;
} elseif(!$name) {
$name = 'noname';
}
$xmlns = '';
if($name_ns) {
$prefix = 'nu' . rand(1000, 9999);
$name = $prefix . ':' . $name;
$xmlns .= " xmlns:$prefix=\"$name_ns\"";
}
if($type_ns != '' && $type_ns == $this->namespaces['xsd']) {
$type_prefix = 'xsd';
} elseif($type_ns) {
$type_prefix = 'ns' . rand(1000, 9999);
$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
}
$atts = '';
if($attributes) {
foreach($attributes as $k => $v) {
$atts .= " $k=\"" . $this->expandEntities($v) . '"';
}
}
if(is_null($val)) {
$this->debug("serialize_val: serialize null");
if($use == 'literal') {
$xml = "<$name$xmlns$atts/>";
$this->debug("serialize_val returning $xml");
return $xml;
} else {
if(isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
$xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
$this->debug("serialize_val returning $xml");
return $xml;
}
}
if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])) {
$this->debug("serialize_val: serialize xsd built-in primitive type");
if(is_bool($val)) {
if($type == 'boolean') {
$val = $val ? 'true' : 'false';
} elseif(!$val) {
$val = 0;
}
} else if(is_string($val)) {
$val = $this->expandEntities($val);
}
if($use == 'literal') {
$xml = "<$name$xmlns$atts>$val</$name>";
$this->debug("serialize_val returning $xml");
return $xml;
} else {
$xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
$this->debug("serialize_val returning $xml");
return $xml;
}
}
$xml = '';
switch(true) {
case (is_bool($val) || $type == 'boolean'):
$this->debug("serialize_val: serialize boolean");
if($type == 'boolean') {
$val = $val ? 'true' : 'false';
} elseif(!$val) {
$val = 0;
}
if($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
}
break;
case (is_int($val) || is_long($val) || $type == 'int'):
$this->debug("serialize_val: serialize int");
if($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
}
break;
case (is_float($val) || is_double($val) || $type == 'float'):
$this->debug("serialize_val: serialize float");
if($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
}
break;
case (is_string($val) || $type == 'string'):
$this->debug("serialize_val: serialize string");
$val = $this->expandEntities($val);
if($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
}
break;
case is_object($val):
$this->debug("serialize_val: serialize object");
if(get_class($val) == 'soapval') {
$this->debug("serialize_val: serialize soapval object");
$pXml = $val->serialize($use);
$this->appendDebug($val->getDebug());
$val->clearDebug();
} else {
if(!$name) {
$name = get_class($val);
$this->debug("In serialize_val, used class name $name as element name");
} else {
$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
}
foreach(get_object_vars($val) as $k => $v) {
$pXml = isset($pXml) ? $pXml . $this->serialize_val($v, $k, false, false, false, false, $use) : $this->serialize_val($v, $k, false, false, false, false, $use);
}
}
if(isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
if($use == 'literal') {
$xml .= "<$name$xmlns$atts>$pXml</$name>";
} else {
$xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
}
break;
break;
case (is_array($val) || $type):
$valueType = $this->isArraySimpleOrStruct($val);
if($valueType == 'arraySimple' || preg_match('/^ArrayOf/', $type)) {
$this->debug("serialize_val: serialize array");
$i = 0;
if(is_array($val) && count($val) > 0) {
foreach($val as $v) {
if(is_object($v) && get_class($v) == 'soapval') {
$tt_ns = $v->type_ns;
$tt = $v->type;
} elseif(is_array($v)) {
$tt = $this->isArraySimpleOrStruct($v);
} else {
$tt = gettype($v);
}
$array_types[$tt] = 1;
$xml .= $this->serialize_val($v, 'item', false, false, false, false, $use);
++$i;
}
if(count($array_types) > 1) {
$array_typename = 'xsd:anyType';
} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
if($tt == 'integer') {
$tt = 'int';
}
$array_typename = 'xsd:' . $tt;
} elseif(isset($tt) && $tt == 'arraySimple') {
$array_typename = 'SOAP-ENC:Array';
} elseif(isset($tt) && $tt == 'arrayStruct') {
$array_typename = 'unnamed_struct_use_soapval';
} else {
if($tt_ns != '' && $tt_ns == $this->namespaces['xsd']) {
$array_typename = 'xsd:' . $tt;
} elseif($tt_ns) {
$tt_prefix = 'ns' . rand(1000, 9999);
$array_typename = "$tt_prefix:$tt";
$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
} else {
$array_typename = $tt;
}
}
$array_type = $i;
if($use == 'literal') {
$type_str = '';
} else if(isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"" . $array_typename . "[$array_type]\"";
}
} else {
if($use == 'literal') {
$type_str = '';
} else if(isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
}
}
$xml = "<$name$xmlns$type_str$atts>" . $xml . "</$name>";
} else {
$this->debug("serialize_val: serialize struct");
if(isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
if($use == 'literal') {
$xml .= "<$name$xmlns$atts>";
} else {
$xml .= "<$name$xmlns$type_str$atts>";
}
foreach($val as $k => $v) {
if($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
$xml .= '<item>';
$xml .= $this->serialize_val($k, 'key', false, false, false, false, $use);
$xml .= $this->serialize_val($v, 'value', false, false, false, false, $use);
$xml .= '</item>';
} else {
$xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
}
}
$xml .= "</$name>";
}
break;
default:
$this->debug("serialize_val: serialize unknown");
$xml .= 'not detected, got ' . gettype($val) . ' for ' . $val;
break;
}
$this->debug("serialize_val returning $xml");
return $xml;
}
function serializeEnvelope($body, $headers = false, $namespaces = array(), $style = 'rpc', $use = 'encoded', $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/')
{
$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
$this->debug("headers:");
$this->appendDebug($this->varDump($headers));
$this->debug("namespaces:");
$this->appendDebug($this->varDump($namespaces));
$ns_string = '';
foreach(array_merge($this->namespaces, $namespaces) as $k => $v) {
$ns_string .= " xmlns:$k=\"$v\"";
}
if($encodingStyle) {
$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
}
if($headers) {
if(is_array($headers)) {
$xml = '';
foreach($headers as $k => $v) {
if(is_object($v) && get_class($v) == 'soapval') {
$xml .= $this->serialize_val($v, false, false, false, false, false, $use);
} else {
$xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
}
}
$headers = $xml;
$this->debug("In serializeEnvelope, serialized array of headers to $headers");
}
$headers = "<SOAP-ENV:Header>" . $headers . "</SOAP-ENV:Header>";
}
return '<?xml version="1.0" encoding="' . $this->soap_defencoding . '"?' . ">" . '<SOAP-ENV:Envelope' . $ns_string . ">" . $headers . "<SOAP-ENV:Body>" . $body . "</SOAP-ENV:Body>" . "</SOAP-ENV:Envelope>";
}
function formatDump($str)
{
$str = htmlspecialchars($str);
return nl2br($str);
}
function contractQname($qname)
{
if(strrpos($qname, ':')) {
$name = substr($qname, strrpos($qname, ':') + 1);
$ns = substr($qname, 0, strrpos($qname, ':'));
$p = $this->getPrefixFromNamespace($ns);
if($p) {
return $p . ':' . $name;
}
return $qname;
} else {
return $qname;
}
}
function expandQname($qname)
{
if(strpos($qname, ':') && !preg_match('/^http:\/\//', $qname)) {
$name = substr(strstr($qname, ':'), 1);
$prefix = substr($qname, 0, strpos($qname, ':'));
if(isset($this->namespaces[$prefix])) {
return $this->namespaces[$prefix] . ':' . $name;
} else {
return $qname;
}
} else {
return $qname;
}
}
function getLocalPart($str)
{
if($sstr = strrchr($str, ':')) {
return substr($sstr, 1);
} else {
return $str;
}
}
function getPrefix($str)
{
if($pos = strrpos($str, ':')) {
return substr($str, 0, $pos);
}
return false;
}
function getNamespaceFromPrefix($prefix)
{
if(isset($this->namespaces[$prefix])) {
return $this->namespaces[$prefix];
}
return false;
}
function getPrefixFromNamespace($ns)
{
foreach($this->namespaces as $p => $n) {
if($ns == $n || $ns == $p) {
$this->usedNamespaces[$p] = $n;
return $p;
}
}
return false;
}
function getmicrotime()
{
if(function_exists('gettimeofday')) {
$tod = gettimeofday();
$sec = $tod['sec'];
$usec = $tod['usec'];
} else {
$sec = time();
$usec = 0;
}
return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
}
function varDump($data)
{
ob_start();
var_dump($data);
$ret_val = ob_get_contents();
ob_end_clean();
return $ret_val;
}
function __toString()
{
return $this->varDump($this);
}
}
function timestamp_to_iso8601($timestamp, $utc = true)
{
$datestr = date('Y-m-d\TH:i:sO', $timestamp);
$pos = strrpos($datestr, "+");
if($pos === FALSE) {
$pos = strrpos($datestr, "-");
}
if($pos !== FALSE) {
if(strlen($datestr) == $pos + 5) {
$datestr = substr($datestr, 0, $pos + 3) . ':' . substr($datestr, -2);
}
}
if($utc) {
$pattern = '/' . '([0-9]{4})-' . '([0-9]{2})-' . '([0-9]{2})' . 'T' . '([0-9]{2}):' . '([0-9]{2}):' . '([0-9]{2})(\.[0-9]*)?' . '(Z|[+\-][0-9]{2}:?[0-9]{2})?' . '/';
if(preg_match($pattern, $datestr, $regs)) {
return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ', $regs[1], $regs[2], $regs[3], $regs[4], $regs[5], $regs[6]);
}
return false;
} else {
return $datestr;
}
}
function iso8601_to_timestamp($datestr)
{
$pattern = '/' . '([0-9]{4})-' . '([0-9]{2})-' . '([0-9]{2})' . 'T' . '([0-9]{2}):' . '([0-9]{2}):' . '([0-9]{2})(\.[0-9]+)?' . '(Z|[+\-][0-9]{2}:?[0-9]{2})?' . '/';
if(preg_match($pattern, $datestr, $regs)) {
if($regs[8] != 'Z') {
$op = substr($regs[8], 0, 1);
$h = substr($regs[8], 1, 2);
$m = substr($regs[8], strlen($regs[8]) - 2, 2);
if($op == '-') {
$regs[4] = $regs[4] + $h;
$regs[5] = $regs[5] + $m;
} elseif($op == '+') {
$regs[4] = $regs[4] - $h;
$regs[5] = $regs[5] - $m;
}
}
return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
} else {
return false;
}
}
function usleepWindows($usec)
{
$start = gettimeofday();
do {
$stop = gettimeofday();
$timePassed = 1000000 * ($stop['sec'] - $start['sec']) + $stop['usec'] - $start['usec'];
} while($timePassed < $usec);
}
?><?php
class nusoap_fault extends nusoap_base
{
var $faultcode;
var $faultactor;
var $faultstring;
var $faultdetail;
function nusoap_fault($faultcode, $faultactor = '', $faultstring = '', $faultdetail = '')
{
parent::nusoap_base();
$this->faultcode = $faultcode;
$this->faultactor = $faultactor;
$this->faultstring = $faultstring;
$this->faultdetail = $faultdetail;
}
function serialize()
{
$ns_string = '';
foreach($this->namespaces as $k => $v) {
$ns_string .= "\n xmlns:$k=\"$v\"";
}
$return_msg = '<?xml version="1.0" encoding="' . $this->soap_defencoding . '"?>' . '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"' . $ns_string . ">\n" . '<SOAP-ENV:Body>' . '<SOAP-ENV:Fault>' . $this->serialize_val($this->faultcode, 'faultcode') . $this->serialize_val($this->faultactor, 'faultactor') . $this->serialize_val($this->faultstring, 'faultstring') . $this->serialize_val($this->faultdetail, 'detail') . '</SOAP-ENV:Fault>' . '</SOAP-ENV:Body>' . '</SOAP-ENV:Envelope>';
return $return_msg;
}
}
class soap_fault extends nusoap_fault
{
}
?><?php
class nusoap_xmlschema extends nusoap_base
{
var $schema = '';
var $xml = '';
var $enclosingNamespaces;
var $schemaInfo = array();
var $schemaTargetNamespace = '';
var $attributes = array();
var $complexTypes = array();
var $complexTypeStack = array();
var $currentComplexType = null;
var $elements = array();
var $elementStack = array();
var $currentElement = null;
var $simpleTypes = array();
var $simpleTypeStack = array();
var $currentSimpleType = null;
var $imports = array();
var $parser;
var $position = 0;
var $depth = 0;
var $depth_array = array();
var $message = array();
var $defaultNamespace = array();
function nusoap_xmlschema($schema = '', $xml = '', $namespaces = array())
{
parent::nusoap_base();
$this->debug('nusoap_xmlschema class instantiated, inside constructor');
$this->schema = $schema;
$this->xml = $xml;
$this->enclosingNamespaces = $namespaces;
$this->namespaces = array_merge($this->namespaces, $namespaces);
if($schema != '') {
$this->debug('initial schema file: ' . $schema);
$this->parseFile($schema, 'schema');
}
if($xml != '') {
$this->debug('initial xml file: ' . $xml);
$this->parseFile($xml, 'xml');
}
}
function parseFile($xml, $type)
{
if($xml != "") {
$xmlStr = @join("", @file($xml));
if($xmlStr == "") {
$msg = 'Error reading XML from ' . $xml;
$this->setError($msg);
$this->debug($msg);
return false;
} else {
$this->debug("parsing $xml");
$this->parseString($xmlStr, $type);
$this->debug("done parsing $xml");
return true;
}
}
return false;
}
function parseString($xml, $type)
{
if($xml != "") {
$this->parser = xml_parser_create();
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
xml_set_object($this->parser, $this);
if($type == "schema") {
xml_set_element_handler($this->parser, 'schemaStartElement', 'schemaEndElement');
xml_set_character_data_handler($this->parser, 'schemaCharacterData');
} elseif($type == "xml") {
xml_set_element_handler($this->parser, 'xmlStartElement', 'xmlEndElement');
xml_set_character_data_handler($this->parser, 'xmlCharacterData');
}
if(!xml_parse($this->parser, $xml, true)) {
$errstr = sprintf('XML error parsing XML schema on line %d: %s', xml_get_current_line_number($this->parser), xml_error_string(xml_get_error_code($this->parser)));
$this->debug($errstr);
$this->debug("XML payload:\n" . $xml);
$this->setError($errstr);
}
xml_parser_free($this->parser);
} else {
$this->debug('no xml passed to parseString()!!');
$this->setError('no xml passed to parseString()!!');
}
}
function CreateTypeName($ename)
{
$scope = '';
for($i = 0; $i < count($this->complexTypeStack); $i++) {
$scope .= $this->complexTypeStack[$i] . '_';
}
return $scope . $ename . '_ContainedType';
}
function schemaStartElement($parser, $name, $attrs)
{
$pos = $this->position++;
$depth = $this->depth++;
$this->depth_array[$depth] = $pos;
$this->message[$pos] = array(
'cdata' => ''
);
if($depth > 0) {
$this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
} else {
$this->defaultNamespace[$pos] = false;
}
if($prefix = $this->getPrefix($name)) {
$name = $this->getLocalPart($name);
} else {
$prefix = '';
}
if(count($attrs) > 0) {
foreach($attrs as $k => $v) {
if(preg_match('/^xmlns/', $k)) {
if($ns_prefix = substr(strrchr($k, ':'), 1)) {
$this->namespaces[$ns_prefix] = $v;
} else {
$this->defaultNamespace[$pos] = $v;
if(!$this->getPrefixFromNamespace($v)) {
$this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
}
}
if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
$this->XMLSchemaVersion = $v;
$this->namespaces['xsi'] = $v . '-instance';
}
}
}
foreach($attrs as $k => $v) {
$k = strpos($k, ':') ? $this->expandQname($k) : $k;
$v = strpos($v, ':') ? $this->expandQname($v) : $v;
$eAttrs[$k] = $v;
}
$attrs = $eAttrs;
} else {
$attrs = array();
}
switch($name) {
case 'all':
case 'choice':
case 'group':
case 'sequence':
$this->complexTypes[$this->currentComplexType]['compositor'] = $name;
break;
case 'attribute':
$this->xdebug("parsing attribute:");
$this->appendDebug($this->varDump($attrs));
if(!isset($attrs['form'])) {
$attrs['form'] = $this->schemaInfo['attributeFormDefault'];
}
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
if(!strpos($v, ':')) {
if($this->defaultNamespace[$pos]) {
$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
}
}
}
if(isset($attrs['name'])) {
$this->attributes[$attrs['name']] = $attrs;
$aname = $attrs['name'];
} elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType') {
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
$aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
} else {
$aname = '';
}
} elseif(isset($attrs['ref'])) {
$aname = $attrs['ref'];
$this->attributes[$attrs['ref']] = $attrs;
}
if($this->currentComplexType) {
$this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
}
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType') {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
$prefix = $this->getPrefix($aname);
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
} else {
$v = '';
}
if(strpos($v, '[,]')) {
$this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
}
$v = substr($v, 0, strpos($v, '['));
if(!strpos($v, ':') && isset($this->typemap[$this->XMLSchemaVersion][$v])) {
$v = $this->XMLSchemaVersion . ':' . $v;
}
$this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
}
break;
case 'complexContent':
$this->xdebug("do nothing for element $name");
break;
case 'complexType':
array_push($this->complexTypeStack, $this->currentComplexType);
if(isset($attrs['name'])) {
$this->xdebug('processing named complexType ' . $attrs['name']);
$this->currentComplexType = $attrs['name'];
$this->complexTypes[$this->currentComplexType] = $attrs;
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
if(isset($attrs['base']) && preg_match('/:Array$/', $attrs['base'])) {
$this->xdebug('complexType is unusual array');
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
} else {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
}
} else {
$name = $this->CreateTypeName($this->currentElement);
$this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
$this->currentComplexType = $name;
$this->complexTypes[$this->currentComplexType] = $attrs;
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
if(isset($attrs['base']) && preg_match('/:Array$/', $attrs['base'])) {
$this->xdebug('complexType is unusual array');
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
} else {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
}
}
$this->complexTypes[$this->currentComplexType]['simpleContent'] = 'false';
break;
case 'element':
array_push($this->elementStack, $this->currentElement);
if(!isset($attrs['form'])) {
if($this->currentComplexType) {
$attrs['form'] = $this->schemaInfo['elementFormDefault'];
} else {
$attrs['form'] = 'qualified';
}
}
if(isset($attrs['type'])) {
$this->xdebug("processing typed element " . $attrs['name'] . " of type " . $attrs['type']);
if(!$this->getPrefix($attrs['type'])) {
if($this->defaultNamespace[$pos]) {
$attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
$this->xdebug('used default namespace to make type ' . $attrs['type']);
}
}
if($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
$this->xdebug('arrayType for unusual array is ' . $attrs['type']);
$this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
}
$this->currentElement = $attrs['name'];
$ename = $attrs['name'];
} elseif(isset($attrs['ref'])) {
$this->xdebug("processing element as ref to " . $attrs['ref']);
$this->currentElement = "ref to " . $attrs['ref'];
$ename = $this->getLocalPart($attrs['ref']);
} else {
$type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
$this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
$this->currentElement = $attrs['name'];
$attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
$ename = $attrs['name'];
}
if(isset($ename) && $this->currentComplexType) {
$this->xdebug("add element $ename to complexType $this->currentComplexType");
$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
} elseif(!isset($attrs['ref'])) {
$this->xdebug("add element $ename to elements array");
$this->elements[$attrs['name']] = $attrs;
$this->elements[$attrs['name']]['typeClass'] = 'element';
}
break;
case 'enumeration':
$this->xdebug('enumeration ' . $attrs['value']);
if($this->currentSimpleType) {
$this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
} elseif($this->currentComplexType) {
$this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
}
break;
case 'extension':
$this->xdebug('extension ' . $attrs['base']);
if($this->currentComplexType) {
$ns = $this->getPrefix($attrs['base']);
if($ns == '') {
$this->complexTypes[$this->currentComplexType]['extensionBase'] = $this->schemaTargetNamespace . ':' . $attrs['base'];
} else {
$this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
}
} else {
$this->xdebug('no current complexType to set extensionBase');
}
break;
case 'import':
if(isset($attrs['schemaLocation'])) {
$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
$this->imports[$attrs['namespace']][] = array(
'location' => $attrs['schemaLocation'],
'loaded' => false
);
} else {
$this->xdebug('import namespace ' . $attrs['namespace']);
$this->imports[$attrs['namespace']][] = array(
'location' => '',
'loaded' => true
);
if(!$this->getPrefixFromNamespace($attrs['namespace'])) {
$this->namespaces['ns' . (count($this->namespaces) + 1)] = $attrs['namespace'];
}
}
break;
case 'include':
if(isset($attrs['schemaLocation'])) {
$this->xdebug('include into namespace ' . $this->schemaTargetNamespace . ' from ' . $attrs['schemaLocation']);
$this->imports[$this->schemaTargetNamespace][] = array(
'location' => $attrs['schemaLocation'],
'loaded' => false
);
} else {
$this->xdebug('ignoring invalid XML Schema construct: include without schemaLocation attribute');
}
break;
case 'list':
$this->xdebug("do nothing for element $name");
break;
case 'restriction':
$this->xdebug('restriction ' . $attrs['base']);
if($this->currentSimpleType) {
$this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
} elseif($this->currentComplexType) {
$this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
if(strstr($attrs['base'], ':') == ':Array') {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
}
}
break;
case 'schema':
$this->schemaInfo = $attrs;
$this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
if(isset($attrs['targetNamespace'])) {
$this->schemaTargetNamespace = $attrs['targetNamespace'];
}
if(!isset($attrs['elementFormDefault'])) {
$this->schemaInfo['elementFormDefault'] = 'unqualified';
}
if(!isset($attrs['attributeFormDefault'])) {
$this->schemaInfo['attributeFormDefault'] = 'unqualified';
}
break;
case 'simpleContent':
if($this->currentComplexType) {
$this->complexTypes[$this->currentComplexType]['simpleContent'] = 'true';
} else {
$this->xdebug("do nothing for element $name because there is no current complexType");
}
break;
case 'simpleType':
array_push($this->simpleTypeStack, $this->currentSimpleType);
if(isset($attrs['name'])) {
$this->xdebug("processing simpleType for name " . $attrs['name']);
$this->currentSimpleType = $attrs['name'];
$this->simpleTypes[$attrs['name']] = $attrs;
$this->simpleTypes[$attrs['name']]['typeClass'] = 'simpleType';
$this->simpleTypes[$attrs['name']]['phpType'] = 'scalar';
} else {
$name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
$this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
$this->currentSimpleType = $name;
$this->simpleTypes[$this->currentSimpleType] = $attrs;
$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
}
break;
case 'union':
$this->xdebug("do nothing for element $name");
break;
default:
$this->xdebug("do not have any logic to process element $name");
}
}
function schemaEndElement($parser, $name)
{
$this->depth--;
if(isset($this->depth_array[$this->depth])) {
$pos = $this->depth_array[$this->depth];
}
if($prefix = $this->getPrefix($name)) {
$name = $this->getLocalPart($name);
} else {
$prefix = '';
}
if($name == 'complexType') {
$this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
$this->xdebug($this->varDump($this->complexTypes[$this->currentComplexType]));
$this->currentComplexType = array_pop($this->complexTypeStack);
}
if($name == 'element') {
$this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
$this->currentElement = array_pop($this->elementStack);
}
if($name == 'simpleType') {
$this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
$this->xdebug($this->varDump($this->simpleTypes[$this->currentSimpleType]));
$this->currentSimpleType = array_pop($this->simpleTypeStack);
}
}
function schemaCharacterData($parser, $data)
{
$pos = $this->depth_array[$this->depth - 1];
$this->message[$pos]['cdata'] .= $data;
}
function serializeSchema()
{
$schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
$xml = '';
if(sizeof($this->imports) > 0) {
foreach($this->imports as $ns => $list) {
foreach($list as $ii) {
if($ii['location'] != '') {
$xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
} else {
$xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
}
}
}
}
foreach($this->complexTypes as $typeName => $attrs) {
$contentStr = '';
if(isset($attrs['elements']) && (count($attrs['elements']) > 0)) {
foreach($attrs['elements'] as $element => $eParts) {
if(isset($eParts['ref'])) {
$contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
} else {
$contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
foreach($eParts as $aName => $aValue) {
if($aName != 'name' && $aName != 'type') {
$contentStr .= " $aName=\"$aValue\"";
}
}
$contentStr .= "/>\n";
}
}
if(isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
$contentStr = " <$schemaPrefix:$attrs[compositor]>\n" . $contentStr . " </$schemaPrefix:$attrs[compositor]>\n";
}
}
if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)) {
foreach($attrs['attrs'] as $attr => $aParts) {
$contentStr .= " <$schemaPrefix:attribute";
foreach($aParts as $a => $v) {
if($a == 'ref' || $a == 'type') {
$contentStr .= " $a=\"" . $this->contractQName($v) . '"';
} elseif($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
$this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
$contentStr .= ' wsdl:arrayType="' . $this->contractQName($v) . '"';
} else {
$contentStr .= " $a=\"$v\"";
}
}
$contentStr .= "/>\n";
}
}
if(isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != '') {
$contentStr = " <$schemaPrefix:restriction base=\"" . $this->contractQName($attrs['restrictionBase']) . "\">\n" . $contentStr . " </$schemaPrefix:restriction>\n";
if((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)) {
$contentStr = " <$schemaPrefix:complexContent>\n" . $contentStr . " </$schemaPrefix:complexContent>\n";
}
}
if($contentStr != '') {
$contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n" . $contentStr . " </$schemaPrefix:complexType>\n";
} else {
$contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
}
$xml .= $contentStr;
}
if(isset($this->simpleTypes) && count($this->simpleTypes) > 0) {
foreach($this->simpleTypes as $typeName => $eParts) {
$xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"" . $this->contractQName($eParts['type']) . "\">\n";
if(isset($eParts['enumeration'])) {
foreach($eParts['enumeration'] as $e) {
$xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
}
}
$xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
}
}
if(isset($this->elements) && count($this->elements) > 0) {
foreach($this->elements as $element => $eParts) {
$xml .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"/>\n";
}
}
if(isset($this->attributes) && count($this->attributes) > 0) {
foreach($this->attributes as $attr => $aParts) {
$xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"" . $this->contractQName($aParts['type']) . "\"\n/>";
}
}
$attr = '';
foreach($this->schemaInfo as $k => $v) {
if($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
$attr .= " $k=\"$v\"";
}
}
$el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
foreach(array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
$el .= " xmlns:$nsp=\"$ns\"";
}
$xml = $el . ">\n" . $xml . "</$schemaPrefix:schema>\n";
return $xml;
}
function xdebug($string)
{
$this->debug('<' . $this->schemaTargetNamespace . '> ' . $string);
}
function getPHPType($type, $ns)
{
if(isset($this->typemap[$ns][$type])) {
return $this->typemap[$ns][$type];
} elseif(isset($this->complexTypes[$type])) {
return $this->complexTypes[$type]['phpType'];
}
return false;
}
function getTypeDef($type)
{
if(substr($type, -1) == '^') {
$is_element = 1;
$type = substr($type, 0, -1);
} else {
$is_element = 0;
}
if((!$is_element) && isset($this->complexTypes[$type])) {
$this->xdebug("in getTypeDef, found complexType $type");
return $this->complexTypes[$type];
} elseif((!$is_element) && isset($this->simpleTypes[$type])) {
$this->xdebug("in getTypeDef, found simpleType $type");
if(!isset($this->simpleTypes[$type]['phpType'])) {
$uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
$ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
$etype = $this->getTypeDef($uqType);
if($etype) {
$this->xdebug("in getTypeDef, found type for simpleType $type:");
$this->xdebug($this->varDump($etype));
if(isset($etype['phpType'])) {
$this->simpleTypes[$type]['phpType'] = $etype['phpType'];
}
if(isset($etype['elements'])) {
$this->simpleTypes[$type]['elements'] = $etype['elements'];
}
}
}
return $this->simpleTypes[$type];
} elseif(isset($this->elements[$type])) {
$this->xdebug("in getTypeDef, found element $type");
if(!isset($this->elements[$type]['phpType'])) {
$uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
$ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
$etype = $this->getTypeDef($uqType);
if($etype) {
$this->xdebug("in getTypeDef, found type for element $type:");
$this->xdebug($this->varDump($etype));
if(isset($etype['phpType'])) {
$this->elements[$type]['phpType'] = $etype['phpType'];
}
if(isset($etype['elements'])) {
$this->elements[$type]['elements'] = $etype['elements'];
}
if(isset($etype['extensionBase'])) {
$this->elements[$type]['extensionBase'] = $etype['extensionBase'];
}
} elseif($ns == 'http://www.w3.org/2001/XMLSchema') {
$this->xdebug("in getTypeDef, element $type is an XSD type");
$this->elements[$type]['phpType'] = 'scalar';
}
}
return $this->elements[$type];
} elseif(isset($this->attributes[$type])) {
$this->xdebug("in getTypeDef, found attribute $type");
return $this->attributes[$type];
} elseif(preg_match('/_ContainedType$/', $type)) {
$this->xdebug("in getTypeDef, have an untyped element $type");
$typeDef['typeClass'] = 'simpleType';
$typeDef['phpType'] = 'scalar';
$typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
return $typeDef;
}
$this->xdebug("in getTypeDef, did not find $type");
return false;
}
function serializeTypeDef($type)
{
$str = "";
if($typeDef = $this->getTypeDef($type)) {
$str .= '<' . $type;
if(is_array($typeDef['attrs'])) {
foreach($typeDef['attrs'] as $attName => $data) {
$str .= " $attName=\"{type = " . $data['type'] . "}\"";
}
}
$str .= " xmlns=\"" . $this->schema['targetNamespace'] . "\"";
if(count($typeDef['elements']) > 0) {
$str .= ">";
foreach($typeDef['elements'] as $element => $eData) {
$str .= $this->serializeTypeDef($element);
}
$str .= "</$type>";
} elseif($typeDef['typeClass'] == 'element') {
$str .= "></$type>";
} else {
$str .= "/>";
}
return $str;
}
return false;
}
function typeToForm($name, $type)
{
$buffer = "";
if($typeDef = $this->getTypeDef($type)) {
if($typeDef['phpType'] == 'struct') {
$buffer .= '<table>';
foreach($typeDef['elements'] as $child => $childDef) {
$buffer .= "
<tr><td align='right'>$childDef[name] (type: " . $this->getLocalPart($childDef['type']) . "):</td>
<td><input type='text' name='parameters[" . $name . "][$childDef[name]]'></td></tr>";
}
$buffer .= '</table>';
} elseif($typeDef['phpType'] == 'array') {
$buffer .= '<table>';
for($i = 0; $i < 3; $i++) {
$buffer .= "
<tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
<td><input type='text' name='parameters[" . $name . "][]'></td></tr>";
}
$buffer .= '</table>';
} else {
$buffer .= "<input type='text' name='parameters[$name]'>";
}
} else {
$buffer .= "<input type='text' name='parameters[$name]'>";
}
return $buffer;
}
function addComplexType($name, $typeClass = 'complexType', $phpType = 'array', $compositor = '', $restrictionBase = '', $elements = array(), $attrs = array(), $arrayType = '')
{
$this->complexTypes[$name] = array(
'name' => $name,
'typeClass' => $typeClass,
'phpType' => $phpType,
'compositor' => $compositor,
'restrictionBase' => $restrictionBase,
'elements' => $elements,
'attrs' => $attrs,
'arrayType' => $arrayType
);
$this->xdebug("addComplexType $name:");
$this->appendDebug($this->varDump($this->complexTypes[$name]));
}
function addSimpleType($name, $restrictionBase = '', $typeClass = 'simpleType', $phpType = 'scalar', $enumeration = array())
{
$this->simpleTypes[$name] = array(
'name' => $name,
'typeClass' => $typeClass,
'phpType' => $phpType,
'type' => $restrictionBase,
'enumeration' => $enumeration
);
$this->xdebug("addSimpleType $name:");
$this->appendDebug($this->varDump($this->simpleTypes[$name]));
}
function addElement($attrs)
{
if(!$this->getPrefix($attrs['type'])) {
$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
}
$this->elements[$attrs['name']] = $attrs;
$this->elements[$attrs['name']]['typeClass'] = 'element';
$this->xdebug("addElement " . $attrs['name']);
$this->appendDebug($this->varDump($this->elements[$attrs['name']]));
}
}
class XMLSchema extends nusoap_xmlschema
{
}
?><?php
class soapval extends nusoap_base
{
var $name;
var $type;
var $value;
var $element_ns;
var $type_ns;
var $attributes;
function soapval($name = 'soapval', $type = false, $value = -1, $element_ns = false, $type_ns = false, $attributes = false)
{
parent::nusoap_base();
$this->name = $name;
$this->type = $type;
$this->value = $value;
$this->element_ns = $element_ns;
$this->type_ns = $type_ns;
$this->attributes = $attributes;
}
function serialize($use = 'encoded')
{
return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
}
function decode()
{
return $this->value;
}
}
?><?php
class soap_transport_http extends nusoap_base
{
var $url = '';
var $uri = '';
var $digest_uri = '';
var $scheme = '';
var $host = '';
var $port = '';
var $path = '';
var $request_method = 'POST';
var $protocol_version = '1.0';
var $encoding = '';
var $outgoing_headers = array();
var $incoming_headers = array();
var $incoming_cookies = array();
var $outgoing_payload = '';
var $incoming_payload = '';
var $response_status_line;
var $useSOAPAction = true;
var $persistentConnection = false;
var $ch = false;
var $ch_options = array();
var $use_curl = false;
var $proxy = null;
var $username = '';
var $password = '';
var $authtype = '';
var $digestRequest = array();
var $certRequest = array();
function soap_transport_http($url, $curl_options = NULL, $use_curl = false)
{
parent::nusoap_base();
$this->debug("ctor url=$url use_curl=$use_curl curl_options:");
$this->appendDebug($this->varDump($curl_options));
$this->setURL($url);
if(is_array($curl_options)) {
$this->ch_options = $curl_options;
}
$this->use_curl = $use_curl;
preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
$this->setHeader('User-Agent', $this->title . '/' . $this->version . ' (' . $rev[1] . ')');
}
function setCurlOption($option, $value)
{
$this->debug("setCurlOption option=$option, value=");
$this->appendDebug($this->varDump($value));
curl_setopt($this->ch, $option, $value);
}
function setHeader($name, $value)
{
$this->outgoing_headers[$name] = $value;
$this->debug("set header $name: $value");
}
function unsetHeader($name)
{
if(isset($this->outgoing_headers[$name])) {
$this->debug("unset header $name");
unset($this->outgoing_headers[$name]);
}
}
function setURL($url)
{
$this->url = $url;
$u = parse_url($url);
foreach($u as $k => $v) {
$this->debug("parsed URL $k = $v");
$this->$k = $v;
}
if(isset($u['query']) && $u['query'] != '') {
$this->path .= '?' . $u['query'];
}
if(!isset($u['port'])) {
if($u['scheme'] == 'https') {
$this->port = 443;
} else {
$this->port = 80;
}
}
$this->uri = $this->path;
$this->digest_uri = $this->uri;
if(!isset($u['port'])) {
$this->setHeader('Host', $this->host);
} else {
$this->setHeader('Host', $this->host . ':' . $this->port);
}
if(isset($u['user']) && $u['user'] != '') {
$this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
}
}
function io_method()
{
if($this->use_curl || ($this->scheme == 'https') || ($this->scheme == 'http' && $this->authtype == 'ntlm') || ($this->scheme == 'http' && is_array($this->proxy) && $this->proxy['authtype'] == 'ntlm'))
return 'curl';
if(($this->scheme == 'http' || $this->scheme == 'ssl') && $this->authtype != 'ntlm' && (!is_array($this->proxy) || $this->proxy['authtype'] != 'ntlm'))
return 'socket';
return 'unknown';
}
function connect($connection_timeout = 0, $response_timeout = 30)
{
$this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
if($this->io_method() == 'socket') {
if(!is_array($this->proxy)) {
$host = $this->host;
$port = $this->port;
} else {
$host = $this->proxy['host'];
$port = $this->proxy['port'];
}
if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)) {
if(!feof($this->fp)) {
$this->debug('Re-use persistent connection');
return true;
}
fclose($this->fp);
$this->debug('Closed persistent connection at EOF');
}
if($this->scheme == 'ssl') {
$host = 'ssl://' . $host;
}
$this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
if($connection_timeout > 0) {
$this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str, $connection_timeout);
} else {
$this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str);
}
if(!$this->fp) {
$msg = 'Couldn\'t open socket connection to server ' . $this->url;
if($this->errno) {
$msg .= ', Error (' . $this->errno . '): ' . $this->error_str;
} else {
$msg .= ' prior to connect(). This is often a problem looking up the host name.';
}
$this->debug($msg);
$this->setError($msg);
return false;
}
$this->debug('set response timeout to ' . $response_timeout);
socket_set_timeout($this->fp, $response_timeout);
$this->debug('socket connected');
return true;
} else if($this->io_method() == 'curl') {
if(!extension_loaded('curl')) {
$this->setError('The PHP cURL Extension is required for HTTPS or NLTM. You will need to re-build or update your PHP to include cURL or change php.ini to load the PHP cURL extension.');
return false;
}
if(defined('CURLOPT_CONNECTIONTIMEOUT'))
$CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
else
$CURLOPT_CONNECTIONTIMEOUT = 78;
if(defined('CURLOPT_HTTPAUTH'))
$CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
else
$CURLOPT_HTTPAUTH = 107;
if(defined('CURLOPT_PROXYAUTH'))
$CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
else
$CURLOPT_PROXYAUTH = 111;
if(defined('CURLAUTH_BASIC'))
$CURLAUTH_BASIC = CURLAUTH_BASIC;
else
$CURLAUTH_BASIC = 1;
if(defined('CURLAUTH_DIGEST'))
$CURLAUTH_DIGEST = CURLAUTH_DIGEST;
else
$CURLAUTH_DIGEST = 2;
if(defined('CURLAUTH_NTLM'))
$CURLAUTH_NTLM = CURLAUTH_NTLM;
else
$CURLAUTH_NTLM = 8;
$this->debug('connect using cURL');
$this->ch = curl_init();
$hostURL = ($this->port != '') ? "$this->scheme://$this->host:$this->port" : "$this->scheme://$this->host";
$hostURL .= $this->path;
$this->setCurlOption(CURLOPT_URL, $hostURL);
if(ini_get('safe_mode') || ini_get('open_basedir')) {
$this->debug('safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
$this->debug('safe_mode = ');
$this->appendDebug($this->varDump(ini_get('safe_mode')));
$this->debug('open_basedir = ');
$this->appendDebug($this->varDump(ini_get('open_basedir')));
} else {
$this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
}
$this->setCurlOption(CURLOPT_HEADER, 1);
$this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
if($this->persistentConnection) {
$this->persistentConnection = false;
$this->setHeader('Connection', 'close');
}
if($connection_timeout != 0) {
$this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
}
if($response_timeout != 0) {
$this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
}
if($this->scheme == 'https') {
$this->debug('set cURL SSL verify options');
$this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
$this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
if($this->authtype == 'certificate') {
$this->debug('set cURL certificate options');
if(isset($this->certRequest['cainfofile'])) {
$this->setCurlOption(CURLOPT_CAINFO, $this->certRequest['cainfofile']);
}
if(isset($this->certRequest['verifypeer'])) {
$this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
} else {
$this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
}
if(isset($this->certRequest['verifyhost'])) {
$this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
} else {
$this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 2);
}
if(isset($this->certRequest['sslcertfile'])) {
$this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
}
if(isset($this->certRequest['sslkeyfile'])) {
$this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
}
if(isset($this->certRequest['passphrase'])) {
$this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest['passphrase']);
}
if(isset($this->certRequest['certpassword'])) {
$this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest['certpassword']);
}
}
}
if($this->authtype && ($this->authtype != 'certificate')) {
if($this->username) {
$this->debug('set cURL username/password');
$this->setCurlOption(CURLOPT_USERPWD, "$this->username:$this->password");
}
if($this->authtype == 'basic') {
$this->debug('set cURL for Basic authentication');
$this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
}
if($this->authtype == 'digest') {
$this->debug('set cURL for digest authentication');
$this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
}
if($this->authtype == 'ntlm') {
$this->debug('set cURL for NTLM authentication');
$this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
}
}
if(is_array($this->proxy)) {
$this->debug('set cURL proxy options');
if($this->proxy['port'] != '') {
$this->setCurlOption(CURLOPT_PROXY, $this->proxy['host'] . ':' . $this->proxy['port']);
} else {
$this->setCurlOption(CURLOPT_PROXY, $this->proxy['host']);
}
if($this->proxy['username'] || $this->proxy['password']) {
$this->debug('set cURL proxy authentication options');
$this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy['username'] . ':' . $this->proxy['password']);
if($this->proxy['authtype'] == 'basic') {
$this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
}
if($this->proxy['authtype'] == 'ntlm') {
$this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
}
}
}
$this->debug('cURL connection set up');
return true;
} else {
$this->setError('Unknown scheme ' . $this->scheme);
$this->debug('Unknown scheme ' . $this->scheme);
return false;
}
}
function send($data, $timeout = 0, $response_timeout = 30, $cookies = NULL)
{
$this->debug('entered send() with data of length: ' . strlen($data));
$this->tryagain = true;
$tries = 0;
while($this->tryagain) {
$this->tryagain = false;
if($tries++ < 2) {
if(!$this->connect($timeout, $response_timeout)) {
return false;
}
if(!$this->sendRequest($data, $cookies)) {
return false;
}
$respdata = $this->getResponse();
} else {
$this->setError("Too many tries to get an OK response ($this->response_status_line)");
}
}
$this->debug('end of send()');
return $respdata;
}
function sendHTTPS($data, $timeout = 0, $response_timeout = 30, $cookies)
{
return $this->send($data, $timeout, $response_timeout, $cookies);
}
function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array())
{
$this->debug("setCredentials username=$username authtype=$authtype digestRequest=");
$this->appendDebug($this->varDump($digestRequest));
$this->debug("certRequest=");
$this->appendDebug($this->varDump($certRequest));
if($authtype == 'basic') {
$this->setHeader('Authorization', 'Basic ' . base64_encode(str_replace(':', '', $username) . ':' . $password));
} elseif($authtype == 'digest') {
if(isset($digestRequest['nonce'])) {
$digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
$A1 = $username . ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
$HA1 = md5($A1);
$A2 = $this->request_method . ':' . $this->digest_uri;
$HA2 = md5($A2);
$unhashedDigest = '';
$nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
$cnonce = $nonce;
if($digestRequest['qop'] != '') {
$unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
} else {
$unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
}
$hashedDigest = md5($unhashedDigest);
$opaque = '';
if(isset($digestRequest['opaque'])) {
$opaque = ', opaque="' . $digestRequest['opaque'] . '"';
}
$this->setHeader('Authorization', 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . $opaque . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"');
}
} elseif($authtype == 'certificate') {
$this->certRequest = $certRequest;
$this->debug('Authorization header not set for certificate');
} elseif($authtype == 'ntlm') {
$this->debug('Authorization header not set for ntlm');
}
$this->username = $username;
$this->password = $password;
$this->authtype = $authtype;
$this->digestRequest = $digestRequest;
}
function setSOAPAction($soapaction)
{
$this->setHeader('SOAPAction', '"' . $soapaction . '"');
}
function setEncoding($enc = 'gzip, deflate')
{
if(function_exists('gzdeflate')) {
$this->protocol_version = '1.1';
$this->setHeader('Accept-Encoding', $enc);
if(!isset($this->outgoing_headers['Connection'])) {
$this->setHeader('Connection', 'close');
$this->persistentConnection = false;
}
$this->encoding = $enc;
}
}
function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '', $proxyauthtype = 'basic')
{
if($proxyhost) {
$this->proxy = array(
'host' => $proxyhost,
'port' => $proxyport,
'username' => $proxyusername,
'password' => $proxypassword,
'authtype' => $proxyauthtype
);
if($proxyusername != '' && $proxypassword != '' && $proxyauthtype = 'basic') {
$this->setHeader('Proxy-Authorization', ' Basic ' . base64_encode($proxyusername . ':' . $proxypassword));
}
} else {
$this->debug('remove proxy');
$proxy = null;
unsetHeader('Proxy-Authorization');
}
}
function isSkippableCurlHeader(&$data)
{
$skipHeaders = array(
'HTTP/1.1 100',
'HTTP/1.0 301',
'HTTP/1.1 301',
'HTTP/1.0 302',
'HTTP/1.1 302',
'HTTP/1.0 401',
'HTTP/1.1 401',
'HTTP/1.0 200 Connection established'
);
foreach($skipHeaders as $hd) {
$prefix = substr($data, 0, strlen($hd));
if($prefix == $hd)
return true;
}
return false;
}
function decodeChunked($buffer, $lb)
{
$length = 0;
$new = '';
$chunkend = strpos($buffer, $lb);
if($chunkend == FALSE) {
$this->debug('no linebreak found in decodeChunked');
return $new;
}
$temp = substr($buffer, 0, $chunkend);
$chunk_size = hexdec(trim($temp));
$chunkstart = $chunkend + strlen($lb);
while($chunk_size > 0) {
$this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
$chunkend = strpos($buffer, $lb, $chunkstart + $chunk_size);
if($chunkend == FALSE) {
$chunk = substr($buffer, $chunkstart);
$new .= $chunk;
$length += strlen($chunk);
break;
}
$chunk = substr($buffer, $chunkstart, $chunkend - $chunkstart);
$new .= $chunk;
$length += strlen($chunk);
$chunkstart = $chunkend + strlen($lb);
$chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
if($chunkend == FALSE) {
break;
}
$temp = substr($buffer, $chunkstart, $chunkend - $chunkstart);
$chunk_size = hexdec(trim($temp));
$chunkstart = $chunkend;
}
return $new;
}
function buildPayload($data, $cookie_str = '')
{
if($this->request_method != 'GET') {
$this->setHeader('Content-Length', strlen($data));
}
if($this->proxy) {
$uri = $this->url;
} else {
$uri = $this->uri;
}
$req = "$this->request_method $uri HTTP/$this->protocol_version";
$this->debug("HTTP request: $req");
$this->outgoing_payload = "$req\r\n";
foreach($this->outgoing_headers as $k => $v) {
$hdr = $k . ': ' . $v;
$this->debug("HTTP header: $hdr");
$this->outgoing_payload .= "$hdr\r\n";
}
if($cookie_str != '') {
$hdr = 'Cookie: ' . $cookie_str;
$this->debug("HTTP header: $hdr");
$this->outgoing_payload .= "$hdr\r\n";
}
$this->outgoing_payload .= "\r\n";
$this->outgoing_payload .= $data;
}
function sendRequest($data, $cookies = NULL)
{
$cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
$this->buildPayload($data, $cookie_str);
if($this->io_method() == 'socket') {
if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
$this->setError('couldn\'t write message data to socket');
$this->debug('couldn\'t write message data to socket');
return false;
}
$this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
return true;
} else if($this->io_method() == 'curl') {
$curl_headers = array();
foreach($this->outgoing_headers as $k => $v) {
if($k == 'Connection' || $k == 'Content-Length' || $k == 'Host' || $k == 'Authorization' || $k == 'Proxy-Authorization') {
$this->debug("Skip cURL header $k: $v");
} else {
$curl_headers[] = "$k: $v";
}
}
if($cookie_str != '') {
$curl_headers[] = 'Cookie: ' . $cookie_str;
}
$this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
$this->debug('set cURL HTTP headers');
if($this->request_method == "POST") {
$this->setCurlOption(CURLOPT_POST, 1);
$this->setCurlOption(CURLOPT_POSTFIELDS, $data);
$this->debug('set cURL POST data');
} else {
}
foreach($this->ch_options as $key => $val) {
$this->setCurlOption($key, $val);
}
$this->debug('set cURL payload');
return true;
}
}
function getResponse()
{
$this->incoming_payload = '';
if($this->io_method() == 'socket') {
$data = '';
while(!isset($lb)) {
if(feof($this->fp)) {
$this->incoming_payload = $data;
$this->debug('found no headers before EOF after length ' . strlen($data));
$this->debug("received before EOF:\n" . $data);
$this->setError('server failed to send headers');
return false;
}
$tmp = fgets($this->fp, 256);
$tmplen = strlen($tmp);
$this->debug("read line of $tmplen bytes: " . trim($tmp));
if($tmplen == 0) {
$this->incoming_payload = $data;
$this->debug('socket read of headers timed out after length ' . strlen($data));
$this->debug("read before timeout: " . $data);
$this->setError('socket read of headers timed out');
return false;
}
$data .= $tmp;
$pos = strpos($data, "\r\n\r\n");
if($pos > 1) {
$lb = "\r\n";
} else {
$pos = strpos($data, "\n\n");
if($pos > 1) {
$lb = "\n";
}
}
if(isset($lb) && preg_match('/^HTTP\/1.1 100/', $data)) {
unset($lb);
$data = '';
}
}
$this->incoming_payload .= $data;
$this->debug('found end of headers after length ' . strlen($data));
$header_data = trim(substr($data, 0, $pos));
$header_array = explode($lb, $header_data);
$this->incoming_headers = array();
$this->incoming_cookies = array();
foreach($header_array as $header_line) {
$arr = explode(':', $header_line, 2);
if(count($arr) > 1) {
$header_name = strtolower(trim($arr[0]));
$this->incoming_headers[$header_name] = trim($arr[1]);
if($header_name == 'set-cookie') {
$cookie = $this->parseCookie(trim($arr[1]));
if($cookie) {
$this->incoming_cookies[] = $cookie;
$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
} else {
$this->debug('did not find cookie in ' . trim($arr[1]));
}
}
} else if(isset($header_name)) {
$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
}
}
if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
$content_length = 2147483647;
$chunked = true;
$this->debug("want to read chunked content");
} elseif(isset($this->incoming_headers['content-length'])) {
$content_length = $this->incoming_headers['content-length'];
$chunked = false;
$this->debug("want to read content of length $content_length");
} else {
$content_length = 2147483647;
$chunked = false;
$this->debug("want to read content to EOF");
}
$data = '';
do {
if($chunked) {
$tmp = fgets($this->fp, 256);
$tmplen = strlen($tmp);
$this->debug("read chunk line of $tmplen bytes");
if($tmplen == 0) {
$this->incoming_payload = $data;
$this->debug('socket read of chunk length timed out after length ' . strlen($data));
$this->debug("read before timeout:\n" . $data);
$this->setError('socket read of chunk length timed out');
return false;
}
$content_length = hexdec(trim($tmp));
$this->debug("chunk length $content_length");
}
$strlen = 0;
while(($strlen < $content_length) && (!feof($this->fp))) {
$readlen = min(8192, $content_length - $strlen);
$tmp = fread($this->fp, $readlen);
$tmplen = strlen($tmp);
$this->debug("read buffer of $tmplen bytes");
if(($tmplen == 0) && (!feof($this->fp))) {
$this->incoming_payload = $data;
$this->debug('socket read of body timed out after length ' . strlen($data));
$this->debug("read before timeout:\n" . $data);
$this->setError('socket read of body timed out');
return false;
}
$strlen += $tmplen;
$data .= $tmp;
}
if($chunked && ($content_length > 0)) {
$tmp = fgets($this->fp, 256);
$tmplen = strlen($tmp);
$this->debug("read chunk terminator of $tmplen bytes");
if($tmplen == 0) {
$this->incoming_payload = $data;
$this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
$this->debug("read before timeout:\n" . $data);
$this->setError('socket read of chunk terminator timed out');
return false;
}
}
} while($chunked && ($content_length > 0) && (!feof($this->fp)));
if(feof($this->fp)) {
$this->debug('read to EOF');
}
$this->debug('read body of length ' . strlen($data));
$this->incoming_payload .= $data;
$this->debug('received a total of ' . strlen($this->incoming_payload) . ' bytes of data from server');
if((isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || (!$this->persistentConnection) || feof($this->fp)) {
fclose($this->fp);
$this->fp = false;
$this->debug('closed socket');
}
if($this->incoming_payload == '') {
$this->setError('no response from server');
return false;
}
} else if($this->io_method() == 'curl') {
$this->debug('send and receive with cURL');
$this->incoming_payload = curl_exec($this->ch);
$data = $this->incoming_payload;
$cErr = curl_error($this->ch);
if($cErr != '') {
$err = 'cURL ERROR: ' . curl_errno($this->ch) . ': ' . $cErr . '<br>';
foreach(curl_getinfo($this->ch) as $k => $v) {
$err .= "$k: $v<br>";
}
$this->debug($err);
$this->setError($err);
curl_close($this->ch);
return false;
} else {
}
$this->debug('No cURL error, closing cURL');
curl_close($this->ch);
$savedata = $data;
while($this->isSkippableCurlHeader($data)) {
$this->debug("Found HTTP header to skip");
if($pos = strpos($data, "\r\n\r\n")) {
$data = ltrim(substr($data, $pos));
} elseif($pos = strpos($data, "\n\n")) {
$data = ltrim(substr($data, $pos));
}
}
if($data == '') {
$data = $savedata;
while(preg_match('/^HTTP\/1.1 100/', $data)) {
if($pos = strpos($data, "\r\n\r\n")) {
$data = ltrim(substr($data, $pos));
} elseif($pos = strpos($data, "\n\n")) {
$data = ltrim(substr($data, $pos));
}
}
}
if($pos = strpos($data, "\r\n\r\n")) {
$lb = "\r\n";
} elseif($pos = strpos($data, "\n\n")) {
$lb = "\n";
} else {
$this->debug('no proper separation of headers and document');
$this->setError('no proper separation of headers and document');
return false;
}
$header_data = trim(substr($data, 0, $pos));
$header_array = explode($lb, $header_data);
$data = ltrim(substr($data, $pos));
$this->debug('found proper separation of headers and document');
$this->debug('cleaned data, stringlen: ' . strlen($data));
foreach($header_array as $header_line) {
$arr = explode(':', $header_line, 2);
if(count($arr) > 1) {
$header_name = strtolower(trim($arr[0]));
$this->incoming_headers[$header_name] = trim($arr[1]);
if($header_name == 'set-cookie') {
$cookie = $this->parseCookie(trim($arr[1]));
if($cookie) {
$this->incoming_cookies[] = $cookie;
$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
} else {
$this->debug('did not find cookie in ' . trim($arr[1]));
}
}
} else if(isset($header_name)) {
$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
}
}
}
$this->response_status_line = $header_array[0];
$arr = explode(' ', $this->response_status_line, 3);
$http_version = $arr[0];
$http_status = intval($arr[1]);
$http_reason = count($arr) > 2 ? $arr[2] : '';
if(isset($this->incoming_headers['location']) && ($http_status == 301 || $http_status == 302)) {
$this->debug("Got $http_status $http_reason with Location: " . $this->incoming_headers['location']);
$this->setURL($this->incoming_headers['location']);
$this->tryagain = true;
return false;
}
if(isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
$this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
if(strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
$this->debug('Server wants digest authentication');
$digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
$digestElements = explode(',', $digestString);
foreach($digestElements as $val) {
$tempElement = explode('=', trim($val), 2);
$digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
}
if(isset($digestRequest['nonce'])) {
$this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
$this->tryagain = true;
return false;
}
}
$this->debug('HTTP authentication failed');
$this->setError('HTTP authentication failed');
return false;
}
if(($http_status >= 300 && $http_status <= 307) || ($http_status >= 400 && $http_status <= 417) || ($http_status >= 501 && $http_status <= 505)) {
$this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
return false;
}
if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != '') {
if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip') {
if(function_exists('gzinflate')) {
$this->debug('The gzinflate function exists');
$datalen = strlen($data);
if($this->incoming_headers['content-encoding'] == 'deflate') {
if($degzdata = @gzinflate($data)) {
$data = $degzdata;
$this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
if(strlen($data) < $datalen) {
$this->debug('The inflated payload is smaller than the gzipped one; try again');
if($degzdata = @gzinflate($data)) {
$data = $degzdata;
$this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
}
}
} else {
$this->debug('Error using gzinflate to inflate the payload');
$this->setError('Error using gzinflate to inflate the payload');
}
} elseif($this->incoming_headers['content-encoding'] == 'gzip') {
if($degzdata = @gzinflate(substr($data, 10))) {
$data = $degzdata;
$this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
if(strlen($data) < $datalen) {
$this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
if($degzdata = @gzinflate(substr($data, 10))) {
$data = $degzdata;
$this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
}
}
} else {
$this->debug('Error using gzinflate to un-gzip the payload');
$this->setError('Error using gzinflate to un-gzip the payload');
}
}
$this->incoming_payload = $header_data . $lb . $lb . $data;
} else {
$this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
$this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
}
} else {
$this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
$this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
}
} else {
$this->debug('No Content-Encoding header');
}
if(strlen($data) == 0) {
$this->debug('no data after headers!');
$this->setError('no data present after HTTP headers');
return false;
}
return $data;
}
function setContentType($type, $charset = false)
{
$this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
}
function usePersistentConnection()
{
if(isset($this->outgoing_headers['Accept-Encoding'])) {
return false;
}
$this->protocol_version = '1.1';
$this->persistentConnection = true;
$this->setHeader('Connection', 'Keep-Alive');
return true;
}
function parseCookie($cookie_str)
{
$cookie_str = str_replace('; ', ';', $cookie_str) . ';';
$data = preg_split('/;/', $cookie_str);
$value_str = $data[0];
$cookie_param = 'domain=';
$start = strpos($cookie_str, $cookie_param);
if($start > 0) {
$domain = substr($cookie_str, $start + strlen($cookie_param));
$domain = substr($domain, 0, strpos($domain, ';'));
} else {
$domain = '';
}
$cookie_param = 'expires=';
$start = strpos($cookie_str, $cookie_param);
if($start > 0) {
$expires = substr($cookie_str, $start + strlen($cookie_param));
$expires = substr($expires, 0, strpos($expires, ';'));
} else {
$expires = '';
}
$cookie_param = 'path=';
$start = strpos($cookie_str, $cookie_param);
if($start > 0) {
$path = substr($cookie_str, $start + strlen($cookie_param));
$path = substr($path, 0, strpos($path, ';'));
} else {
$path = '/';
}
$cookie_param = ';secure;';
if(strpos($cookie_str, $cookie_param) !== FALSE) {
$secure = true;
} else {
$secure = false;
}
$sep_pos = strpos($value_str, '=');
if($sep_pos) {
$name = substr($value_str, 0, $sep_pos);
$value = substr($value_str, $sep_pos + 1);
$cookie = array(
'name' => $name,
'value' => $value,
'domain' => $domain,
'path' => $path,
'expires' => $expires,
'secure' => $secure
);
return $cookie;
}
return false;
}
function getCookiesForRequest($cookies, $secure = false)
{
$cookie_str = '';
if((!is_null($cookies)) && (is_array($cookies))) {
foreach($cookies as $cookie) {
if(!is_array($cookie)) {
continue;
}
$this->debug("check cookie for validity: " . $cookie['name'] . '=' . $cookie['value']);
if((isset($cookie['expires'])) && (!empty($cookie['expires']))) {
if(strtotime($cookie['expires']) <= time()) {
$this->debug('cookie has expired');
continue;
}
}
if((isset($cookie['domain'])) && (!empty($cookie['domain']))) {
$domain = preg_quote($cookie['domain']);
if(!preg_match("'.*$domain$'i", $this->host)) {
$this->debug('cookie has different domain');
continue;
}
}
if((isset($cookie['path'])) && (!empty($cookie['path']))) {
$path = preg_quote($cookie['path']);
if(!preg_match("'^$path.*'i", $this->path)) {
$this->debug('cookie is for a different path');
continue;
}
}
if((!$secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
$this->debug('cookie is secure, transport is not');
continue;
}
$cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
$this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
}
}
return $cookie_str;
}
}
?><?php
class nusoap_server extends nusoap_base
{
var $headers = array();
var $request = '';
var $requestHeaders = '';
var $requestHeader = NULL;
var $document = '';
var $requestSOAP = '';
var $methodURI = '';
var $methodname = '';
var $methodparams = array();
var $SOAPAction = '';
var $xml_encoding = '';
var $decode_utf8 = true;
var $outgoing_headers = array();
var $response = '';
var $responseHeaders = '';
var $responseSOAP = '';
var $methodreturn = false;
var $methodreturnisliteralxml = false;
var $fault = false;
var $result = 'successful';
var $operations = array();
var $wsdl = false;
var $externalWSDLURL = false;
var $debug_flag = false;
function nusoap_server($wsdl = false)
{
parent::nusoap_base();
global $debug;
global $HTTP_SERVER_VARS;
if(isset($_SERVER)) {
$this->debug("_SERVER is defined:");
$this->appendDebug($this->varDump($_SERVER));
} elseif(isset($HTTP_SERVER_VARS)) {
$this->debug("HTTP_SERVER_VARS is defined:");
$this->appendDebug($this->varDump($HTTP_SERVER_VARS));
} else {
$this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
}
if(isset($debug)) {
$this->debug("In nusoap_server, set debug_flag=$debug based on global flag");
$this->debug_flag = $debug;
} elseif(isset($_SERVER['QUERY_STRING'])) {
$qs = explode('&', $_SERVER['QUERY_STRING']);
foreach($qs as $v) {
if(substr($v, 0, 6) == 'debug=') {
$this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
$this->debug_flag = substr($v, 6);
}
}
} elseif(isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
$qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
foreach($qs as $v) {
if(substr($v, 0, 6) == 'debug=') {
$this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
$this->debug_flag = substr($v, 6);
}
}
}
if($wsdl) {
$this->debug("In nusoap_server, WSDL is specified");
if(is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
$this->wsdl = $wsdl;
$this->externalWSDLURL = $this->wsdl->wsdl;
$this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
} else {
$this->debug('Create wsdl from ' . $wsdl);
$this->wsdl = new wsdl($wsdl);
$this->externalWSDLURL = $wsdl;
}
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
if($err = $this->wsdl->getError()) {
die('WSDL ERROR: ' . $err);
}
}
}
function service($data)
{
global $HTTP_SERVER_VARS;
if(isset($_SERVER['REQUEST_METHOD'])) {
$rm = $_SERVER['REQUEST_METHOD'];
} elseif(isset($HTTP_SERVER_VARS['REQUEST_METHOD'])) {
$rm = $HTTP_SERVER_VARS['REQUEST_METHOD'];
} else {
$rm = '';
}
if(isset($_SERVER['QUERY_STRING'])) {
$qs = $_SERVER['QUERY_STRING'];
} elseif(isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
$qs = $HTTP_SERVER_VARS['QUERY_STRING'];
} else {
$qs = '';
}
$this->debug("In service, request method=$rm query string=$qs strlen(\$data)=" . strlen($data));
if($rm == 'POST') {
$this->debug("In service, invoke the request");
$this->parse_request($data);
if(!$this->fault) {
$this->invoke_method();
}
if(!$this->fault) {
$this->serialize_return();
}
$this->send_response();
} elseif(preg_match('/wsdl/', $qs)) {
$this->debug("In service, this is a request for WSDL");
if($this->externalWSDLURL) {
if(strpos($this->externalWSDLURL, "http://") !== false) {
$this->debug("In service, re-direct for WSDL");
header('Location: ' . $this->externalWSDLURL);
} else {
$this->debug("In service, use file passthru for WSDL");
header("Content-Type: text/xml\r\n");
$pos = strpos($this->externalWSDLURL, "file://");
if($pos === false) {
$filename = $this->externalWSDLURL;
} else {
$filename = substr($this->externalWSDLURL, $pos + 7);
}
$fp = fopen($this->externalWSDLURL, 'r');
fpassthru($fp);
}
} elseif($this->wsdl) {
$this->debug("In service, serialize WSDL");
header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
print $this->wsdl->serialize($this->debug_flag);
if($this->debug_flag) {
$this->debug('wsdl:');
$this->appendDebug($this->varDump($this->wsdl));
print $this->getDebugAsXMLComment();
}
} else {
$this->debug("In service, there is no WSDL");
header("Content-Type: text/html; charset=ISO-8859-1\r\n");
print "This service does not provide WSDL";
}
} elseif($this->wsdl) {
$this->debug("In service, return Web description");
print $this->wsdl->webDescription();
} else {
$this->debug("In service, no Web description");
header("Content-Type: text/html; charset=ISO-8859-1\r\n");
print "This service does not provide a Web description";
}
}
function parse_http_headers()
{
global $HTTP_SERVER_VARS;
$this->request = '';
$this->SOAPAction = '';
if(function_exists('getallheaders')) {
$this->debug("In parse_http_headers, use getallheaders");
$headers = getallheaders();
foreach($headers as $k => $v) {
$k = strtolower($k);
$this->headers[$k] = $v;
$this->request .= "$k: $v\r\n";
$this->debug("$k: $v");
}
if(isset($this->headers['soapaction'])) {
$this->SOAPAction = str_replace('"', '', $this->headers['soapaction']);
}
if(isset($this->headers['content-type']) && strpos($this->headers['content-type'], '=')) {
$enc = str_replace('"', '', substr(strstr($this->headers["content-type"], '='), 1));
if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
$this->xml_encoding = strtoupper($enc);
} else {
$this->xml_encoding = 'US-ASCII';
}
} else {
$this->xml_encoding = 'ISO-8859-1';
}
} elseif(isset($_SERVER) && is_array($_SERVER)) {
$this->debug("In parse_http_headers, use _SERVER");
foreach($_SERVER as $k => $v) {
if(substr($k, 0, 5) == 'HTTP_') {
$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
} else {
$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
}
if($k == 'soapaction') {
$k = 'SOAPAction';
$v = str_replace('"', '', $v);
$v = str_replace('\\', '', $v);
$this->SOAPAction = $v;
} else if($k == 'content-type') {
if(strpos($v, '=')) {
$enc = substr(strstr($v, '='), 1);
$enc = str_replace('"', '', $enc);
$enc = str_replace('\\', '', $enc);
if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
$this->xml_encoding = strtoupper($enc);
} else {
$this->xml_encoding = 'US-ASCII';
}
} else {
$this->xml_encoding = 'ISO-8859-1';
}
}
$this->headers[$k] = $v;
$this->request .= "$k: $v\r\n";
$this->debug("$k: $v");
}
} elseif(is_array($HTTP_SERVER_VARS)) {
$this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
foreach($HTTP_SERVER_VARS as $k => $v) {
if(substr($k, 0, 5) == 'HTTP_') {
$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
$k = strtolower(substr($k, 5));
} else {
$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
$k = strtolower($k);
}
if($k == 'soapaction') {
$k = 'SOAPAction';
$v = str_replace('"', '', $v);
$v = str_replace('\\', '', $v);
$this->SOAPAction = $v;
} else if($k == 'content-type') {
if(strpos($v, '=')) {
$enc = substr(strstr($v, '='), 1);
$enc = str_replace('"', '', $enc);
$enc = str_replace('\\', '', $enc);
if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
$this->xml_encoding = strtoupper($enc);
} else {
$this->xml_encoding = 'US-ASCII';
}
} else {
$this->xml_encoding = 'ISO-8859-1';
}
}
$this->headers[$k] = $v;
$this->request .= "$k: $v\r\n";
$this->debug("$k: $v");
}
} else {
$this->debug("In parse_http_headers, HTTP headers not accessible");
$this->setError("HTTP headers not accessible");
}
}
function parse_request($data = '')
{
$this->debug('entering parse_request()');
$this->parse_http_headers();
$this->debug('got character encoding: ' . $this->xml_encoding);
if(isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
$this->debug('got content encoding: ' . $this->headers['content-encoding']);
if($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
if(function_exists('gzuncompress')) {
if($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
$data = $degzdata;
} elseif($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
$data = $degzdata;
} else {
$this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data');
return;
}
} else {
$this->fault('SOAP-ENV:Client', 'This Server does not support compressed data');
return;
}
}
}
$this->request .= "\r\n" . $data;
$data = $this->parseRequest($this->headers, $data);
$this->requestSOAP = $data;
$this->debug('leaving parse_request');
}
function invoke_method()
{
$this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
$orig_methodname = $this->methodname;
if($this->wsdl) {
if($this->opData = $this->wsdl->getOperationData($this->methodname)) {
$this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
$this->appendDebug('opData=' . $this->varDump($this->opData));
} elseif($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
$this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
$this->appendDebug('opData=' . $this->varDump($this->opData));
$this->methodname = $this->opData['name'];
} else {
$this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
$this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
return;
}
} else {
$this->debug('in invoke_method, no WSDL to validate method');
}
if(strpos($this->methodname, '..') > 0) {
$delim = '..';
} else if(strpos($this->methodname, '.') > 0) {
$delim = '.';
} else {
$delim = '';
}
$this->debug("in invoke_method, delim=$delim");
$class = '';
$method = '';
if(strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1) {
$try_class = substr($this->methodname, 0, strpos($this->methodname, $delim));
if(class_exists($try_class)) {
$class = $try_class;
$method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
$this->debug("in invoke_method, class=$class method=$method delim=$delim");
} else {
$this->debug("in invoke_method, class=$try_class not found");
}
} else {
$try_class = '';
$this->debug("in invoke_method, no class to try");
}
if($class == '') {
if(!function_exists($this->methodname)) {
$this->debug("in invoke_method, function '$this->methodname' not found!");
$this->result = 'fault: method not found';
$this->fault('SOAP-ENV:Client', "method '$this->methodname'('$orig_methodname') not defined in service('$try_class' '$delim')");
return;
}
} else {
$method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
if(!in_array($method_to_compare, get_class_methods($class))) {
$this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
$this->result = 'fault: method not found';
$this->fault('SOAP-ENV:Client', "method '$this->methodname'/'$method_to_compare'('$orig_methodname') not defined in service/'$class'('$try_class' '$delim')");
return;
}
}
if(!$this->verify_method($this->methodname, $this->methodparams)) {
$this->debug('ERROR: request not verified against method signature');
$this->result = 'fault: request failed validation against method signature';
$this->fault('SOAP-ENV:Client', "Operation '$this->methodname' not defined in service.");
return;
}
$this->debug('in invoke_method, params:');
$this->appendDebug($this->varDump($this->methodparams));
$this->debug("in invoke_method, calling '$this->methodname'");
if(!function_exists('call_user_func_array')) {
if($class == '') {
$this->debug('in invoke_method, calling function using eval()');
$funcCall = "\$this->methodreturn = $this->methodname(";
} else {
if($delim == '..') {
$this->debug('in invoke_method, calling class method using eval()');
$funcCall = "\$this->methodreturn = " . $class . "::" . $method . "(";
} else {
$this->debug('in invoke_method, calling instance method using eval()');
$instname = "\$inst_" . time();
$funcCall = $instname . " = new " . $class . "(); ";
$funcCall .= "\$this->methodreturn = " . $instname . "->" . $method . "(";
}
}
if($this->methodparams) {
foreach($this->methodparams as $param) {
if(is_array($param) || is_object($param)) {
$this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
return;
}
$funcCall .= "\"$param\",";
}
$funcCall = substr($funcCall, 0, -1);
}
$funcCall .= ');';
$this->debug('in invoke_method, function call: ' . $funcCall);
@eval($funcCall);
} else {
if($class == '') {
$this->debug('in invoke_method, calling function using call_user_func_array()');
$call_arg = "$this->methodname";
} elseif($delim == '..') {
$this->debug('in invoke_method, calling class method using call_user_func_array()');
$call_arg = array(
$class,
$method
);
} else {
$this->debug('in invoke_method, calling instance method using call_user_func_array()');
$instance = new $class();
$call_arg = array(
&$instance,
$method
);
}
if(is_array($this->methodparams)) {
$this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
} else {
$this->methodreturn = call_user_func_array($call_arg, array());
}
}
$this->debug('in invoke_method, methodreturn:');
$this->appendDebug($this->varDump($this->methodreturn));
$this->debug("in invoke_method, called method $this->methodname, received data of type " . gettype($this->methodreturn));
}
function serialize_return()
{
$this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
if(isset($this->methodreturn) && is_object($this->methodreturn) && ((get_class($this->methodreturn) == 'soap_fault') || (get_class($this->methodreturn) == 'nusoap_fault'))) {
$this->debug('got a fault object from method');
$this->fault = $this->methodreturn;
return;
} elseif($this->methodreturnisliteralxml) {
$return_val = $this->methodreturn;
} else {
$this->debug('got a(n) ' . gettype($this->methodreturn) . ' from method');
$this->debug('serializing return value');
if($this->wsdl) {
if(sizeof($this->opData['output']['parts']) > 1) {
$this->debug('more than one output part, so use the method return unchanged');
$opParams = $this->methodreturn;
} elseif(sizeof($this->opData['output']['parts']) == 1) {
$this->debug('exactly one output part, so wrap the method return in a simple array');
$opParams = array(
$this->methodreturn
);
}
$return_val = $this->wsdl->serializeRPCParameters($this->methodname, 'output', $opParams);
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
if($errstr = $this->wsdl->getError()) {
$this->debug('got wsdl error: ' . $errstr);
$this->fault('SOAP-ENV:Server', 'unable to serialize result');
return;
}
} else {
if(isset($this->methodreturn)) {
$return_val = $this->serialize_val($this->methodreturn, 'return');
} else {
$return_val = '';
$this->debug('in absence of WSDL, assume void return for backward compatibility');
}
}
}
$this->debug('return value:');
$this->appendDebug($this->varDump($return_val));
$this->debug('serializing response');
if($this->wsdl) {
$this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
if($this->opData['style'] == 'rpc') {
$this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
if($this->opData['output']['use'] == 'literal') {
if($this->methodURI) {
$payload = '<ns1:' . $this->methodname . 'Response xmlns:ns1="' . $this->methodURI . '">' . $return_val . '</ns1:' . $this->methodname . "Response>";
} else {
$payload = '<' . $this->methodname . 'Response>' . $return_val . '</' . $this->methodname . 'Response>';
}
} else {
if($this->methodURI) {
$payload = '<ns1:' . $this->methodname . 'Response xmlns:ns1="' . $this->methodURI . '">' . $return_val . '</ns1:' . $this->methodname . "Response>";
} else {
$payload = '<' . $this->methodname . 'Response>' . $return_val . '</' . $this->methodname . 'Response>';
}
}
} else {
$this->debug('style is not rpc for serialization: assume document');
$payload = $return_val;
}
} else {
$this->debug('do not have WSDL for serialization: assume rpc/encoded');
$payload = '<ns1:' . $this->methodname . 'Response xmlns:ns1="' . $this->methodURI . '">' . $return_val . '</ns1:' . $this->methodname . "Response>";
}
$this->result = 'successful';
if($this->wsdl) {
$this->appendDebug($this->wsdl->getDebug());
if(isset($this->opData['output']['encodingStyle'])) {
$encodingStyle = $this->opData['output']['encodingStyle'];
} else {
$encodingStyle = '';
}
$this->responseSOAP = $this->serializeEnvelope($payload, $this->responseHeaders, $this->wsdl->usedNamespaces, $this->opData['style'], $this->opData['output']['use'], $encodingStyle);
} else {
$this->responseSOAP = $this->serializeEnvelope($payload, $this->responseHeaders);
}
$this->debug("Leaving serialize_return");
}
function send_response()
{
$this->debug('Enter send_response');
if($this->fault) {
$payload = $this->fault->serialize();
$this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
$this->outgoing_headers[] = "Status: 500 Internal Server Error";
} else {
$payload = $this->responseSOAP;
}
if(isset($this->debug_flag) && $this->debug_flag) {
$payload .= $this->getDebugAsXMLComment();
}
$this->outgoing_headers[] = "Server: $this->title Server v$this->version";
preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
$this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (" . $rev[1] . ")";
$payload = $this->getHTTPBody($payload);
$type = $this->getHTTPContentType();
$charset = $this->getHTTPContentTypeCharset();
$this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
if(strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {
if(strstr($this->headers['accept-encoding'], 'gzip')) {
if(function_exists('gzencode')) {
if(isset($this->debug_flag) && $this->debug_flag) {
$payload .= "<!-- Content being gzipped -->";
}
$this->outgoing_headers[] = "Content-Encoding: gzip";
$payload = gzencode($payload);
} else {
if(isset($this->debug_flag) && $this->debug_flag) {
$payload .= "<!-- Content will not be gzipped: no gzencode -->";
}
}
} elseif(strstr($this->headers['accept-encoding'], 'deflate')) {
if(function_exists('gzdeflate')) {
if(isset($this->debug_flag) && $this->debug_flag) {
$payload .= "<!-- Content being deflated -->";
}
$this->outgoing_headers[] = "Content-Encoding: deflate";
$payload = gzdeflate($payload);
} else {
if(isset($this->debug_flag) && $this->debug_flag) {
$payload .= "<!-- Content will not be deflated: no gzcompress -->";
}
}
}
}
$this->outgoing_headers[] = "Content-Length: " . strlen($payload);
reset($this->outgoing_headers);
foreach($this->outgoing_headers as $hdr) {
header($hdr, false);
}
print $payload;
$this->response = join("\r\n", $this->outgoing_headers) . "\r\n\r\n" . $payload;
}
function verify_method($operation, $request)
{
if(isset($this->wsdl) && is_object($this->wsdl)) {
if($this->wsdl->getOperationData($operation)) {
return true;
}
} elseif(isset($this->operations[$operation])) {
return true;
}
return false;
}
function parseRequest($headers, $data)
{
$this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' headers:');
$this->appendDebug($this->varDump($headers));
if(!isset($headers['content-type'])) {
$this->setError('Request not of type text/xml (no content-type header)');
return false;
}
if(!strstr($headers['content-type'], 'text/xml')) {
$this->setError('Request not of type text/xml');
return false;
}
if(strpos($headers['content-type'], '=')) {
$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
$this->debug('Got response encoding: ' . $enc);
if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
$this->xml_encoding = strtoupper($enc);
} else {
$this->xml_encoding = 'US-ASCII';
}
} else {
$this->xml_encoding = 'ISO-8859-1';
}
$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
$parser = new nusoap_parser($data, $this->xml_encoding, '', $this->decode_utf8);
$this->debug("parser debug: \n" . $parser->getDebug());
if($err = $parser->getError()) {
$this->result = 'fault: error in msg parsing: ' . $err;
$this->fault('SOAP-ENV:Client', "error in msg parsing:\n" . $err);
} else {
$this->methodURI = $parser->root_struct_namespace;
$this->methodname = $parser->root_struct_name;
$this->debug('methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
$this->debug('calling parser->get_soapbody()');
$this->methodparams = $parser->get_soapbody();
$this->requestHeaders = $parser->getHeaders();
$this->requestHeader = $parser->get_soapheader();
$this->document = $parser->document;
}
}
function getHTTPBody($soapmsg)
{
return $soapmsg;
}
function getHTTPContentType()
{
return 'text/xml';
}
function getHTTPContentTypeCharset()
{
return $this->soap_defencoding;
}
function add_to_map($methodname, $in, $out)
{
$this->operations[$methodname] = array(
'name' => $methodname,
'in' => $in,
'out' => $out
);
}
function register($name, $in = array(), $out = array(), $namespace = false, $soapaction = false, $style = false, $use = false, $documentation = '', $encodingStyle = '')
{
global $HTTP_SERVER_VARS;
if($this->externalWSDLURL) {
die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
}
if(!$name) {
die('You must specify a name when you register an operation');
}
if(!is_array($in)) {
die('You must provide an array for operation inputs');
}
if(!is_array($out)) {
die('You must provide an array for operation outputs');
}
if(false == $namespace) {
}
if(false == $soapaction) {
if(isset($_SERVER)) {
$SERVER_NAME = $_SERVER['SERVER_NAME'];
$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
$HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
} elseif(isset($HTTP_SERVER_VARS)) {
$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
$HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
} else {
$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
}
if($HTTPS == '1' || $HTTPS == 'on') {
$SCHEME = 'https';
} else {
$SCHEME = 'http';
}
$soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
}
if(false == $style) {
$style = "rpc";
}
if(false == $use) {
$use = "encoded";
}
if($use == 'encoded' && $encodingStyle == '') {
$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
}
$this->operations[$name] = array(
'name' => $name,
'in' => $in,
'out' => $out,
'namespace' => $namespace,
'soapaction' => $soapaction,
'style' => $style
);
if($this->wsdl) {
$this->wsdl->addOperation($name, $in, $out, $namespace, $soapaction, $style, $use, $documentation, $encodingStyle);
}
return true;
}
function fault($faultcode, $faultstring, $faultactor = '', $faultdetail = '')
{
if($faultdetail == '' && $this->debug_flag) {
$faultdetail = $this->getDebug();
}
$this->fault = new nusoap_fault($faultcode, $faultactor, $faultstring, $faultdetail);
$this->fault->soap_defencoding = $this->soap_defencoding;
}
function configureWSDL($serviceName, $namespace = false, $endpoint = false, $style = 'rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
{
global $HTTP_SERVER_VARS;
if(isset($_SERVER)) {
$SERVER_NAME = $_SERVER['SERVER_NAME'];
$SERVER_PORT = $_SERVER['SERVER_PORT'];
$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
$HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
} elseif(isset($HTTP_SERVER_VARS)) {
$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
$SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
$HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
} else {
$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
}
$colon = strpos($SERVER_NAME, ":");
if($colon) {
$SERVER_NAME = substr($SERVER_NAME, 0, $colon);
}
if($SERVER_PORT == 80) {
$SERVER_PORT = '';
} else {
$SERVER_PORT = ':' . $SERVER_PORT;
}
if(false == $namespace) {
$namespace = "http://$SERVER_NAME/soap/$serviceName";
}
if(false == $endpoint) {
if($HTTPS == '1' || $HTTPS == 'on') {
$SCHEME = 'https';
} else {
$SCHEME = 'http';
}
$endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
}
if(false == $schemaTargetNamespace) {
$schemaTargetNamespace = $namespace;
}
$this->wsdl = new wsdl;
$this->wsdl->serviceName = $serviceName;
$this->wsdl->endpoint = $endpoint;
$this->wsdl->namespaces['tns'] = $namespace;
$this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
$this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
if($schemaTargetNamespace != $namespace) {
$this->wsdl->namespaces['types'] = $schemaTargetNamespace;
}
$this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces);
if($style == 'document') {
$this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified';
}
$this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
$this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array(
'location' => '',
'loaded' => true
);
$this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array(
'location' => '',
'loaded' => true
);
$this->wsdl->bindings[$serviceName . 'Binding'] = array(
'name' => $serviceName . 'Binding',
'style' => $style,
'transport' => $transport,
'portType' => $serviceName . 'PortType'
);
$this->wsdl->ports[$serviceName . 'Port'] = array(
'binding' => $serviceName . 'Binding',
'location' => $endpoint,
'bindingType' => 'http://schemas.xmlsoap.org/wsdl/soap/'
);
}