Source for file _functions_xmlrpc.php
Documentation is available at _functions_xmlrpc.php
* @subpackage xmlrpc {@link http://xmlrpc.usefulinc.com/doc/}
* @copyright Edd Dumbill <edd@usefulinc.com> (C) 1999-2001
// by Edd Dumbill (C) 1999-2002
// $Id: _functions_xmlrpc.php,v 1.9.2.6 2005/08/31 19:32:31 fplanque Exp $
// additional fixes for case of missing xml extension file by Michel Valdrighi <m@tidakada.com>
// Copyright (c) 1999,2000,2002 Edd Dumbill.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of the "XML-RPC for PHP" nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
if( !defined('DB_USER') ) die( 'Please, do not access this page directly.' );
# b2 fix. some servers have stupid warnings
function logIO($m=
"",$n=
"")
// Original fix for missing extension file by "Michel Valdrighi" <m@tidakada.com>
{ // We'll not be able to do dynamic loading (fix by Sakichan)
{ // Win 32 fix. From: "Leo West" <lwest@imaginet.fr>
// G. Giunta 2005/01/29: declare global these variables,
// so that xmlrpc.inc will work even if included from within a function
// NB: it will give warnings in PHP3, so we comment it out
// Milosch: Next round, maybe we should explicitly request these via $GLOBALS where used.
global $xmlrpc_defencoding;
global $xmlrpc_internalencoding;
global $xmlrpc_backslash;
$xmlrpcBoolean=
'boolean';
$xmlrpcDateTime=
'dateTime.iso8601';
$xmlrpc_valid_parents =
array(
'BOOLEAN' =>
array('VALUE'),
'STRING' =>
array('VALUE'),
'DOUBLE' =>
array('VALUE'),
'DATETIME.ISO8601' =>
array('VALUE'),
'BASE64' =>
array('VALUE'),
'ARRAY' =>
array('VALUE'),
'STRUCT' =>
array('VALUE'),
'PARAM' =>
array('PARAMS'),
'METHODNAME' =>
array('METHODCALL'),
'PARAMS' =>
array('METHODCALL', 'METHODRESPONSE'),
'MEMBER' =>
array('STRUCT'),
'NAME' =>
array('MEMBER'),
'DATA' =>
array('ARRAY'),
'FAULT' =>
array('METHODRESPONSE'),
'VALUE' =>
array('MEMBER', 'DATA', 'PARAM', 'FAULT'),
// These are left untranslated because they are sent back to the remote system
$xmlrpcerr['unknown_method']=
1;
$xmlrpcstr['unknown_method']=
'Unknown method';
$xmlrpcerr['invalid_return']=
2;
$xmlrpcstr['invalid_return']=
'Invalid return payload: enable debugging to examine incoming payload';
$xmlrpcerr['incorrect_params']=
3;
$xmlrpcstr['incorrect_params']=
'Incorrect parameters passed to method';
$xmlrpcerr['introspect_unknown']=
4;
$xmlrpcstr['introspect_unknown']=
"Can't introspect: method unknown";
$xmlrpcerr['http_error']=
5;
$xmlrpcstr['http_error']=
"Didn't receive 200 OK from remote server.";
$xmlrpcstr['no_data']=
'No data received from server.';
$xmlrpcstr['no_ssl']=
'No SSL support compiled in.';
$xmlrpcerr['curl_fail']=
8;
$xmlrpcstr['curl_fail']=
'CURL error';
$xmlrpcerr['invalid_request']=
15;
$xmlrpcstr['invalid_request']=
'Invalid request payload';
$xmlrpcerr['multicall_notstruct'] =
9;
$xmlrpcstr['multicall_notstruct'] =
'system.multicall expected struct';
$xmlrpcerr['multicall_nomethod'] =
10;
$xmlrpcstr['multicall_nomethod'] =
'missing methodName';
$xmlrpcerr['multicall_notstring'] =
11;
$xmlrpcstr['multicall_notstring'] =
'methodName is not a string';
$xmlrpcerr['multicall_recursion'] =
12;
$xmlrpcstr['multicall_recursion'] =
'recursive system.multicall forbidden';
$xmlrpcerr['multicall_noparams'] =
13;
$xmlrpcstr['multicall_noparams'] =
'missing params';
$xmlrpcerr['multicall_notarray'] =
14;
$xmlrpcstr['multicall_notarray'] =
'params is not an array';
// The charset encoding expected by the server for received messages and
// by the client for received responses
$xmlrpc_defencoding=
'UTF-8';
// The encoding used by PHP.
// String values received will be converted to this.
$xmlrpc_internalencoding=
'ISO-8859-1';
$xmlrpcName=
'XML-RPC for PHP';
// let user errors start at 800
// let XML parse errors start at 100
// formulate backslashes for escaping regexp
$xmlrpc_backslash=
chr(92).
chr(92);
// used to store state during parsing
// quick explanation of components:
// ac - used to accumulate values
// isf - used to indicate a fault
// lv - used to indicate "looking for a value": implements
// the logic to allow values with no types to be strings
// params - used to store parameters in method calls
// method - used to store method name
// stack - array with genealogy of xml elements names:
// used to validate nesting of xmlrpc elements
* To help correct communication of non-ascii chars inside strings, regardless
* of the charset used when sending requests, parsing them, sending responses
* and parsing responses, convert all non-ascii chars present in the message
* into their equivalent 'charset entity'. Charset entities enumerated this way
* are independent of the charset encoding used to transmit them, and all XML
* parsers are bound to understand them.
$top=
split('&', $string);
if (ereg("^([#a-zA-Z0-9]+);", $top[$i], $regs))
if (ereg("^#([0-9]+)$", $ent, $regs))
* These entities originate from HTML specs (1.1, proposed 2.0, etc),
* and are taken directly from php-4.3.1/ext/mbstring/html_entities.c.
* Until php provides functionality to translate these entities in its
* core library, use this function.
"ϑ" =>
"ϑ",
"ℵ" =>
"ℵ",
return strtr($data, $entities);
for($position =
0; $position <
$length; $position++
)
$character =
substr($data, $position, 1);
if ($code <
32 ||
$code >
159)
$character =
("&#".
strval($code).
";");
$escapeddata .=
$character;
global $_xh, $xmlrpcDateTime, $xmlrpcString, $xmlrpc_valid_parents;
// if invalid xmlrpc already detected, skip all processing
if ($_xh[$parser]['isf'] <
2)
// check for correct element nesting
// top level element can only be of 2 types
if (count($_xh[$parser]['stack']) ==
0)
if ($name !=
'METHODRESPONSE' &&
$name !=
'METHODCALL')
$_xh[$parser]['isf'] =
2;
$_xh[$parser]['isf_reason'] =
'missing top level xmlrpc element';
// not top level element: see if parent is OK
if (!in_array($_xh[$parser]['stack'][0], $xmlrpc_valid_parents[$name]))
$_xh[$parser]['isf'] =
2;
$_xh[$parser]['isf_reason'] =
"xmlrpc element $name cannot be child of {$_xh[$parser]['stack'][0]}";
//$_xh[$parser]['st'].='array(';
// this last line turns quoting off
// this means if we get an empty array we'll
// simply get a bit of whitespace in the eval
// create an empty array to hold child values, and push it onto appropriate stack
$cur_val['values'] =
array();
$cur_val['type'] =
$name;
//$_xh[$parser]['st'].='"';
//$_xh[$parser]['st']='';
// clear value, so we can check later if no value will passed for this param/member
$_xh[$parser]['value']=
null;
//$_xh[$parser]['st'].='new xmlrpcval(';
// look for a value: if this is still true by the
// time we reach the end tag for value then the type is string
$_xh[$parser]['vt']=
'value';
if ($_xh[$parser]['vt']!=
'value')
//two data elements inside a value: an error occurred!
$_xh[$parser]['isf'] =
2;
$_xh[$parser]['isf_reason'] =
"$name element following a {$_xh[$parser]['vt']} element inside a single value";
/*if ($name=='DATETIME.ISO8601' || $name=='STRING')
if ($name=='DATETIME.ISO8601')
$_xh[$parser]['vt']=$xmlrpcDateTime;
// No quoting is required here -- but
// at the end of the element we must check
// for data format errors.
//$_xh[$parser]['ac']='';
// avoid warnings later on if no NAME is found before VALUE inside
// a struct member predefining member name as NULL
$_xh[$parser]['valuestack'][0]['name'] =
'';
// clear value, so we can check later if no value will passed for this param/member
$_xh[$parser]['value']=
null;
// valid elements that add little to processing
/// INVALID ELEMENT: RAISE ISF so that it is later recognized!!!
$_xh[$parser]['isf'] =
2;
$_xh[$parser]['isf_reason'] =
"found not-xmlrpc xml element $name";
// Save current element name to stack, to validate nesting
global $_xh,$xmlrpcTypes,$xmlrpcString,$xmlrpcDateTime;
if ($_xh[$parser]['isf'] <
2)
// push this element name from stack
// NB: if XML validates, correct opening/closing is guaranteed and
// we do not have to check for $name == $curr_elem.
// we also checked for proper nesting at start of elements...
//if ($_xh[$parser]['cm'] && substr($_xh[$parser]['st'], -1) ==',')
// $_xh[$parser]['st']=substr($_xh[$parser]['st'],0,-1);
//$_xh[$parser]['st'].=')';
// fetch out of stack array of values, and promote it to current value
$_xh[$parser]['value'] =
$cur_val['values'];
//$_xh[$parser]['st'].= $_xh[$parser]['ac'] . '" => ';
$_xh[$parser]['valuestack'][0]['name'] =
$_xh[$parser]['ac'];
//if ($_xh[$parser]['qt']==1)
// we use double quotes rather than single so backslashification works OK
//$_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';
$_xh[$parser]['value']=
$_xh[$parser]['ac'];
elseif ($name==
'DATETIME.ISO8601')
$_xh[$parser]['vt']=
$xmlrpcDateTime;
$_xh[$parser]['value']=
$_xh[$parser]['ac'];
//$_xh[$parser]['st'].='base64_decode("'. $_xh[$parser]['ac'] . '")';
///@todo check for failure of base64 decoding / catch warnings
elseif ($name==
'BOOLEAN')
// special case here: we translate boolean 1 or 0 into PHP
// constants true or false
// NB: this simple checks helps a lot sanitizing input, ie no
// security problems around here
if ($_xh[$parser]['ac']==
'1')
//$_xh[$parser]['ac']='true';
$_xh[$parser]['value']=
true;
//$_xh[$parser]['ac']='false';
// log if receiveing something strange, even though we set the value to false anyway
if ($_xh[$parser]['ac']!=
'0')
error_log('XML-RPC: invalid value received in BOOLEAN: '.
$_xh[$parser]['ac']);
$_xh[$parser]['value']=
false;
//$_xh[$parser]['st'].=$_xh[$parser]['ac'];
// we must check that only 0123456789-.<space> are characters here
if (!ereg("^[+-]?[eE0123456789 \\t\\.]+$", $_xh[$parser]['ac']))
// TODO: find a better way of throwing an error
error_log('XML-RPC: non numeric value received in DOUBLE: '.
$_xh[$parser]['ac']);
//$_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";
$_xh[$parser]['value']=
'ERROR_NON_NUMERIC_FOUND';
//$_xh[$parser]['st'].=(double)$_xh[$parser]['ac'];
$_xh[$parser]['value']=(double)
$_xh[$parser]['ac'];
// we must check that only 0123456789-<space> are characters here
if (!ereg("^[+-]?[0123456789 \\t]+$", $_xh[$parser]['ac']))
// TODO: find a better way of throwing an error
error_log('XML-RPC: non numeric value received in INT: '.
$_xh[$parser]['ac']);
//$_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";
$_xh[$parser]['value']=
'ERROR_NON_NUMERIC_FOUND';
//$_xh[$parser]['st'].=(int)$_xh[$parser]['ac'];
$_xh[$parser]['value']=(int)
$_xh[$parser]['ac'];
$_xh[$parser]['lv']=
3; // indicate we've found a value
// This if() detects if no scalar was inside <VALUE></VALUE>
if ($_xh[$parser]['vt']==
'value')
$_xh[$parser]['value']=
$_xh[$parser]['ac'];
$_xh[$parser]['vt']=
$xmlrpcString;
/*if (strlen($_xh[$parser]['ac'])>0 &&
$_xh[$parser]['vt']==$xmlrpcString)
$_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';
// This if() detects if no scalar was inside <VALUE></VALUE>
if($_xh[$parser]['st'][strlen($_xh[$parser]['st'])-1] == '(')
$_xh[$parser]['st'].= '""';
// G. Giunta 2005/03/12 save some chars in the reconstruction of string vals...
if ($_xh[$parser]['vt'] != $xmlrpcString)
$_xh[$parser]['st'].=", '" . $_xh[$parser]['vt'] . "')";
$_xh[$parser]['st'].=")";
$_xh[$parser]['st'].=',';
// build the xmlrpc val out of the data received, and substitute it
$temp =
new xmlrpcval($_xh[$parser]['value'], $_xh[$parser]['vt']);
// check if we are inside an array or struct:
// if value just built is inside an array, let's move it into array on the stack
if (count($_xh[$parser]['valuestack']) &&
$_xh[$parser]['valuestack'][0]['type']==
'ARRAY')
$_xh[$parser]['valuestack'][0]['values'][] =
$temp;
$_xh[$parser]['value'] =
$temp;
// add to array in the stack the last element built
// unless no VALUE was found
if ($_xh[$parser]['value'])
$_xh[$parser]['valuestack'][0]['values'][$_xh[$parser]['valuestack'][0]['name']] =
$_xh[$parser]['value'];
error_log('XML-RPC: missing VALUE inside STRUCT in received xml');
//$_xh[$parser]['params'][]=$_xh[$parser]['st'];
if ($_xh[$parser]['value'])
$_xh[$parser]['params'][]=
$_xh[$parser]['value'];
error_log('XML-RPC: missing VALUE inside PARAM in received xml');
$_xh[$parser]['method']=
ereg_replace("^[\n\r\t ]+", '', $_xh[$parser]['ac']);
// End of INVALID ELEMENT!
// shall we add an assert here for unreachable code???
// if it's a valid type name, set the type
/*if (isset($xmlrpcTypes[strtolower($name)]))
$_xh[$parser]['vt']=strtolower($name);
global $_xh, $xmlrpc_backslash;
//if (ereg("^[\n\r \t]+$", $data)) return;
// print "adding [${data}]\n";
// skip processing if xml fault already detected
if ($_xh[$parser]['isf'] <
2)
if ($_xh[$parser]['lv']!=
3)
// "lookforvalue==3" means that we've found an entire value
// and should discard any further character data
if ($_xh[$parser]['lv']==
1)
// if we've found text and we're just in a <value> then
// turn quoting on, as this will be a string
// and say we've found a value
if(!@isset
($_xh[$parser]['ac']))
$_xh[$parser]['ac'] =
'';
//$_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));
$_xh[$parser]['ac'].=
$data;
global $_xh, $xmlrpc_backslash;
// skip processing if xml fault already detected
if ($parser[$_xh]['isf'] <
2)
if (substr($data, 0, 1) ==
'&' &&
substr($data, -
1, 1) ==
';')
if ($_xh[$parser]['lv']==
1)
//$_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));
$_xh[$parser]['ac'].=
$data;
function send($msg, $timeout=
0, $method=
'http')
// $msg is an array of xmlrpcmsg's
return $this->multicall($msg, $timeout, $method);
// where msg is an xmlrpcmsg
$msg->debug=
$this->debug;
function sendPayloadHTTP10($msg, $server, $port, $timeout=
0,$username=
'', $password=
'')
global $xmlrpcerr, $xmlrpcstr, $xmlrpcName, $xmlrpcVersion, $xmlrpc_defencoding;
$this->errstr=
'Connect error';
$r=
new xmlrpcresp(0, $xmlrpcerr['http_error'],$xmlrpcstr['http_error']);
// Only create the payload if it was not created previously
// thanks to Grant Rauscher <grant7@firstworld.net>
$credentials=
'Authorization: Basic ' .
base64_encode($username .
':' .
$password) .
"\r\n";
$op=
"POST " .
$this->path.
" HTTP/1.0\r\n" .
"User-Agent: " .
$xmlrpcName .
" " .
$xmlrpcVersion .
"\r\n" .
"Host: ".
$server .
"\r\n" .
"Accept-Charset: " .
$xmlrpc_defencoding .
"\r\n" .
"Content-Type: text/xml\r\nContent-Length: " .
strlen($msg->payload) .
"\r\n\r\n" .
$r=
new xmlrpcresp(0, $xmlrpcerr['http_error'], $xmlrpcstr['http_error']);
$resp=
$msg->parseResponseFile($fp);
// contributed by Justin Miller <justin@voxel.net>
// requires curl to be built into PHP
function sendPayloadHTTPS($msg, $server, $port, $timeout=
0,$username=
'', $password=
'', $cert=
'',$certpass=
'')
global $xmlrpcerr, $xmlrpcstr, $xmlrpcVersion, $xmlrpc_internalencoding;
// Only create the payload if it was not created previously
$this->errstr=
'SSL unavailable on this install';
$r=
new xmlrpcresp(0, $xmlrpcerr['no_ssl'], $xmlrpcstr['no_ssl']);
$curl =
curl_init('https://' .
$server .
':' .
$port .
$this->path);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_USERAGENT, 'PHP XMLRPC '.
$xmlrpcVersion);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $msg->payload);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: text/xml', 'Accept-Charset: '.
$xmlrpc_internalencoding));
// whether to verify remote host's cert
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifypeer);
// whether to verify cert's common name (CN); 0 for no, 1 to verify that it exists, and 2 to verify that it matches the hostname used
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $this->verifyhost);
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout ==
1 ?
1 :
$timeout -
1);
if ($username &&
$password)
curl_setopt($curl, CURLOPT_USERPWD,"$username:$password");
curl_setopt($curl, CURLOPT_SSLCERT, $cert);
curl_setopt($curl, CURLOPT_SSLCERTPASSWD,$certpass);
$result =
curl_exec($curl);
$resp=
new xmlrpcresp(0, $xmlrpcerr['curl_fail'], $xmlrpcstr['curl_fail'].
': '.
curl_error($curl));
$resp =
$msg->parseResponse($result);
function multicall($msgs, $timeout=
0, $method=
'http')
/* TODO - this is not php3-friendly */
// if($results !== false)
// Either the system.multicall succeeded, or the send
// failed (e.g. due to HTTP timeout). In either case,
// system.multicall unsupported by server,
// don't try it next time...
// system.multicall is unupported by server:
// Emulate multicall via multiple requests
while(list
(,$msg) =
@each($msgs))
$results[] =
$this->send($msg, $timeout, $method);
// Attempt to boxcar $msgs via system.multicall.
// Construct multicall message
while(list
(,$msg) =
@each($msgs))
$call['methodName'] =
new xmlrpcval($msg->method(),'string');
$numParams =
$msg->getNumParams();
for ($i =
0; $i <
$numParams; $i++
)
$params[$i] =
$msg->getParam($i);
$call['params'] =
new xmlrpcval($params, 'array');
$multicall =
new xmlrpcmsg('system.multicall');
$multicall->addParam(new xmlrpcval($calls, 'array'));
$result =
$this->send($multicall, $timeout, $method);
return ($result ||
0); // transport failed
if($result->faultCode() !=
0)
return false; // system.multicall failed
$rets =
$result->value();
if($rets->kindOf() !=
'array')
return false; // bad return type from system.multicall
$numRets =
$rets->arraysize();
if($numRets !=
count($msgs))
return false; // wrong number of return values.
for ($i =
0; $i <
$numRets; $i++
)
$val =
$rets->arraymem($i);
if($val->arraysize() !=
1)
return false; // Bad value
$response[$i] =
new xmlrpcresp($val->arraymem(0));
$code =
$val->structmem('faultCode');
if($code->kindOf() !=
'scalar' ||
$code->scalartyp() !=
'int')
$str =
$val->structmem('faultString');
if($str->kindOf() !=
'scalar' ||
$str->scalartyp() !=
'string')
$response[$i] =
new xmlrpcresp(0, $code->scalarval(), $str->scalarval());
} // end class xmlrpc_client
//$this->errstr = htmlspecialchars($fstr); // XXX: encoding probably shouldn't be done here; fix later.
error_log("Invalid type '" .
gettype($val) .
"' (value: $val) passed to xmlrpcresp. Defaulting to empty value.");
$result =
"<methodResponse>\n";
// G. Giunta 2005/2/13: let non-ASCII response messages be tolerated by clients
<value><int>' .
$this->errno .
'</int></value>
$result .=
"<params>\n<param>\n" .
$this->val->serialize() .
$result .=
"\n</methodResponse>";
for($i=
0; $i<
sizeof($pars); $i++
)
// return "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?".">\n<methodCall>\n";
return "<?xml version=\"1.0\"?" .
">\n<methodCall>\n";
return "</methodCall>\n";
// if (sizeof($this->params)) {
$this->payload.=
"<param>\n" .
$p->serialize() .
//$this->payload=str_replace("\n", "\r\n", $this->payload);
while($data=
fread($fp, 32768))
global $_xh,$xmlrpcerr,$xmlrpcstr;
global $xmlrpc_defencoding, $xmlrpc_internalencoding;
//by maHo, replaced htmlspecialchars with htmlentities
print
"<PRE>---GOT---\n" .
htmlentities($data) .
"\n---END---\n</PRE>";
error_log('No response received from server.');
$r =
new xmlrpcresp(0, $xmlrpcerr['no_data'], $xmlrpcstr['no_data']);
// see if we got an HTTP 200 OK, else bomb
// but only do this if we're using the HTTP protocol.
// Strip HTTP 1.1 100 Continue header if present
while (ereg('^HTTP/1.1 1[0-9]{2}', $data))
$pos =
strpos($data, 'HTTP', 12);
// server sent a Continue header without any (valid) content following...
// give the client a chance to know it
if (!$pos &&
!is_int($pos)) // works fine in php 3, 4 and 5
if (!ereg("^HTTP/[0-9\\.]+ 200 ", $data))
error_log('HTTP error, got response: ' .
$errstr);
$r=
new xmlrpcresp(0, $xmlrpcerr['http_error'], $xmlrpcstr['http_error'].
' (' .
$errstr .
')');
// Clean up the accumulator, or it will grow indefinitely long
// if making xmlrpc calls for a while
$_xh[$parser]['headers'] =
array();
$_xh[$parser]['stack'] =
array();
$_xh[$parser]['valuestack'] =
array();
// separate HTTP headers from data
if (ereg("^HTTP", $data))
// be tolerant to usage of \n instead of \r\n to separate headers and data
// (even though it is not valid http)
$pos =
strpos($data,"\r\n\r\n");
// No separation between response headers and body: fault?
// be tolerant to line endings, and extra empty lines
while (list
(,$line) =
@each($ar))
// take care of multi-line headers
$header_name =
trim($arr[0]);
// TO DO: some headers (the ones that allow a CSV list of values)
// do allow many values to be passed using multiple header lines.
// We should add content to $_xh[$parser]['headers'][$header_name]
// instead of replacing it for those...
$_xh[$parser]['headers'][$header_name] =
$arr[1];
for ($i =
2; $i <
count($arr); $i++
)
$_xh[$parser]['headers'][$header_name] .=
':'.
$arr[$i];
$_xh[$parser]['headers'][$header_name] =
trim($_xh[$parser]['headers'][$header_name]);
} else if (isset
($header_name))
$_xh[$parser]['headers'][$header_name] .=
' ' .
trim($line);
if ($this->debug &&
count($_xh[$parser]['headers']))
//foreach ($_xh[$parser]['headers'] as $header)
@reset($_xh[$parser]['headers']);
while(list
($header, $value) =
@each($_xh[$parser]['headers']))
print
"HEADER: $header: $value\n";
// be tolerant of extra whitespace in response body
// be tolerant of junk after methodResponse (e.g. javascript automatically inserted by free hosts)
// idea from Luca Mariano <luca.mariano@email.it> originally in PEARified version of the lib
$pos =
strpos($data, "</methodResponse>");
$pos =
strpos($data, "</methodResponse>", $bd);
$data =
substr($data, 0, $bd);
//$_xh[$parser]['st']='';
$_xh[$parser]['isf_reason']=
0;
//$_xh[$parser]['qt']='';
// G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell
// the xml parser to give us back data in the expected charset
//$xmlrpc_value=new xmlrpcval;
// thanks to Peter Kocks <peter.kocks@baygate.com>
$errstr =
'XML error at line 1, check URL';
$errstr =
sprintf('XML error: %s at line %d',
$r=
new xmlrpcresp(0, $xmlrpcerr['invalid_return'], $xmlrpcstr['invalid_return'].
' ('.
$errstr.
')');
$r->hdrs =
$_xh[$parser]['headers'];
if ($_xh[$parser]['isf'] >
1)
///@todo echo something for user?
$r =
new xmlrpcresp(0, $xmlrpcerr['invalid_return'],
$xmlrpcstr['invalid_return'] .
' ' .
$_xh[$parser]['isf_reason']);
//else if (strlen($_xh[$parser]['st'])==0)
// then something odd has happened
// and it's time to generate a client side error
// indicating something odd went on
$r=
new xmlrpcresp(0, $xmlrpcerr['invalid_return'],
$xmlrpcstr['invalid_return']);
//print "<PRE>---EVALING---[" .
//strlen($_xh[$parser]['st']) . " chars]---\n" .
//htmlspecialchars($_xh[$parser]['st']) . ";\n---END---</PRE>";
print
"<PRE>---PARSED---\n" ;
print
"\n---END---</PRE>";
//@eval('$v=' . $_xh[$parser]['st'] . '; $allOK=1;');
// $r = new xmlrpcresp(0, $xmlrpcerr['invalid_return'], $xmlrpcstr['invalid_return']);
$v =
$_xh[$parser]['value'];
if ($_xh[$parser]['isf'])
$errno_v =
$v->structmem('faultCode');
$errstr_v =
$v->structmem('faultString');
$errno =
$errno_v->scalarval();
// FAULT returned, errno needs to reflect that
$r =
new xmlrpcresp($v, $errno, $errstr_v->scalarval());
$r->hdrs =
$_xh[$parser]['headers'];
* Type will default to string
if ($val!=-
1 ||
!is_int($val) ||
$type!=
'')
if ($xmlrpcTypes[$type]==
1)
elseif ($xmlrpcTypes[$type]==
2)
elseif ($xmlrpcTypes[$type]==
3)
global $xmlrpcTypes, $xmlrpcBoolean;
echo
'<strong>xmlrpcval</strong>: scalar can have only one value<br />';
$typeof=
$xmlrpcTypes[$type];
echo
'<strong>xmlrpcval</strong>: not a scalar type (${typeof})<br />';
if ($type==
$xmlrpcBoolean)
// we're adding to an array here
// a scalar, so set the value and remember we're scalar
echo
'<strong>xmlrpcval</strong>: already initialized as a [' .
$this->kindOf() .
']<br />';
$this->mytype=
$xmlrpcTypes['array'];
$this->me['array']=
$vals;
echo
'<strong>xmlrpcval</strong>: already initialized as a [' .
$this->kindOf() .
']<br />';
$this->mytype=
$xmlrpcTypes['struct'];
$this->me['struct']=
$vals;
while ( list
( $key, $val ) =
each( $ar ) )
echo
"$key => $val<br />";
while ( list
( $key2, $val2 ) =
each( $val ) )
echo
"-- $key2 => $val2<br />";
global $xmlrpcTypes, $xmlrpcBase64, $xmlrpcString,
switch(@$xmlrpcTypes[$typ])
while(list
($key2, $val2)=
each($val))
$rs.=
"<member><name>${key2}</name>\n";
$rs.=
"<array>\n<data>\n";
for($i=
0; $i<
sizeof($val); $i++
)
$rs.=
"</data>\n</array>";
$rs.=
"<${typ}>" .
($val ?
'1' :
'0') .
"</${typ}>";
// G. Giunta 2005/2/13: do NOT use htmlentities, since
// it will produce named html entities, which are invalid xml
// $rs.="<${typ}>" . htmlentities($val). "</${typ}>";
$rs.=
"<${typ}>${val}</${typ}>";
list
($typ, $val) =
each($ar);
$nv=
$this->me['struct'][$m];
return each($this->me['struct']);
global $xmlrpcBoolean, $xmlrpcBase64;
// contributed by I Sofer, 2001-03-24
// add support for nested arrays to scalarval
// i've created a new method here, so as to
// preserve back compatibility
while(list
($id,$cont) =
@each($b))
$b[$id] =
$cont->scalarval();
// add support for structures directly encoding php objects
while(list
($id,$cont) =
@each($t))
$t[$id] =
$cont->scalarval();
while(list
($id,$cont) =
@each($t))
//eval('$b->'.$id.' = $cont;');
//global $xmlrpcBoolean, $xmlrpcBase64;
global $xmlrpcI4, $xmlrpcInt;
$nv=
$this->me['array'][$m];
// return an ISO8601 encoded string
// really, timezones ought to be supported
// but the XML-RPC spec says:
// "Don't assume a timezone. It should be specified by the server in its
// documentation what assumptions it makes about timezones."
// these routines always assume localtime unless
// $utc is set to 1, in which case UTC is assumed
// and an adjustment for locale is made when encoding
// gmstrftime doesn't exist in some versions
// return a timet in the localtime, or UTC
if (ereg("([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})", $idate, $regs))
$t=
gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
$t=
mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
/****************************************************************
* xmlrpc_decode takes a message in PHP xmlrpc object format and *
* tranlates it into native PHP types. *
* author: Dan Libby (dan@libby.com) *
****************************************************************/
* evocore: We add xmlrpc_decode_recurse because the default PHP implementation
* of xmlrpc_decode won't recurse! Bleh!
* update: XML-RPC for PHP now copes with this, but we keep a stub for backward compatibility
$kind =
$xmlrpc_val->kindOf();
for($i =
0; $i <
$size; $i++
)
elseif($kind ==
'struct')
while(list
($key,$value)=
$xmlrpc_val->structeach())
// echo $key, '=>', $arr[$key], '<br />';
define('XMLRPC_EPI_ENABLED','1');
define('XMLRPC_EPI_ENABLED','0');
$kind =
$xmlrpc_val->kindOf();
for($i =
0; $i <
$size; $i++
)
elseif($kind ==
'struct')
while(list
($key,$value)=
$xmlrpc_val->structeach())
/****************************************************************
* xmlrpc_encode takes native php types and encodes them into *
* xmlrpc PHP object format. *
* BUG: All sequential arrays are turned into structs. I don't *
* know of a good way to determine if an array is sequential *
* feature creep -- could support more types via optional type *
* author: Dan Libby (dan@libby.com) *
****************************************************************/
while (list
($k,$v) =
each($php_val))
$xmlrpc_val->addScalar($php_val, $xmlrpcInt);
$xmlrpc_val->addScalar($php_val, $xmlrpcDouble);
$xmlrpc_val->addScalar($php_val, $xmlrpcString);
// Add support for encoding/decoding of booleans, since they are supported in PHP
$xmlrpc_val->addScalar($php_val, $xmlrpcBoolean);
// </G_Giunta_2001-02-29>
// catch "resource", "NULL", "user function", "unknown type"
// giancarlo pinerolo <ping@alt.it>
// an empty object in case (which is already
// at this point), not a boolean.
while (list
($k,$v) =
each($php_val))
$xmlrpc_val->addScalar($php_val, $xmlrpcInt);
$xmlrpc_val->addScalar($php_val, $xmlrpcDouble);
$xmlrpc_val->addScalar($php_val, $xmlrpcString);
// Add support for encoding/decoding of booleans, since they are supported in PHP
$xmlrpc_val->addScalar($php_val, $xmlrpcBoolean);
// </G_Giunta_2001-02-29>
// giancarlo pinerolo <ping@alt.it>
// an empty object in case (which is already
// at this point), not a boolean.