Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

310 lines (277 sloc) 11.402 kb
<?php
// by Edd Dumbill (C) 1999,2000
// <edd@usefulinc.com>
// $Id$
// License is granted to use or modify this software ("XML-RPC for PHP")
// for commercial or non-commercial use provided the copyright of the author
// is preserved in any distributed or derivative work.
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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 AUTHOR 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.
// Adapted to PEAR standards by Stig Sæther Bakken <stig@php.net>
// XML RPC Server class
// requires: xmlrpc.inc
require_once "XML/RPC.php";
// listMethods: either a string, or nothing
$GLOBALS['XML_RPC_Server_listMethods_sig']=
array(array($GLOBALS['XML_RPC_Array'], $GLOBALS['XML_RPC_String']),
array($GLOBALS['XML_RPC_Array']));
$GLOBALS['XML_RPC_Server_listMethods_doc']=
'This method lists all the methods that the XML-RPC server knows how to dispatch';
function XML_RPC_Server_listMethods($server, $m)
{
global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
$v=new XML_RPC_Value();
$dmap=$server->dmap;
$outAr=array();
for(reset($dmap); list($key, $val)=each($dmap); ) {
$outAr[]=new XML_RPC_Value($key, "string");
}
$dmap=$XML_RPC_Server_dmap;
for(reset($dmap); list($key, $val)=each($dmap); ) {
$outAr[]=new XML_RPC_Value($key, "string");
}
$v->addArray($outAr);
return new XML_RPC_Response($v);
}
$GLOBALS['XML_RPC_Server_methodSignature_sig']=
array(array($GLOBALS['XML_RPC_Array'], $GLOBALS['XML_RPC_String']));
$GLOBALS['XML_RPC_Server_methodSignature_doc']=
'Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
function XML_RPC_Server_methodSignature($server, $m)
{
global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
$methName=$m->getParam(0);
$methName=$methName->scalarval();
if (ereg("^system\.", $methName)) {
$dmap=$XML_RPC_Server_dmap; $sysCall=1;
} else {
$dmap=$server->dmap; $sysCall=0;
}
// print "<!-- ${methName} -->\n";
if (isset($dmap[$methName])) {
if ($dmap[$methName]["signature"]) {
$sigs=array();
$thesigs=$dmap[$methName]["signature"];
for($i=0; $i<sizeof($thesigs); $i++) {
$cursig=array();
$inSig=$thesigs[$i];
for($j=0; $j<sizeof($inSig); $j++) {
$cursig[]=new XML_RPC_Value($inSig[$j], "string");
}
$sigs[]=new XML_RPC_Value($cursig, "array");
}
$r=new XML_RPC_Response(new XML_RPC_Value($sigs, "array"));
} else {
$r=new XML_RPC_Response(new XML_RPC_Value("undef", "string"));
}
} else {
$r=new XML_RPC_Response(0,
$XML_RPC_err["introspect_unknown"],
$XML_RPC_str["introspect_unknown"]);
}
return $r;
}
$GLOBALS['XML_RPC_Server_methodHelp_sig']=
array(array($GLOBALS['XML_RPC_String'], $GLOBALS['XML_RPC_String']));
$GLOBALS['XML_RPC_Server_methodHelp_doc']=
'Returns help text if defined for the method passed, otherwise returns an empty string';
function XML_RPC_Server_methodHelp($server, $m)
{
global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
$methName=$m->getParam(0);
$methName=$methName->scalarval();
if (ereg("^system\.", $methName)) {
$dmap=$XML_RPC_Server_dmap; $sysCall=1;
} else {
$dmap=$server->dmap; $sysCall=0;
}
// print "<!-- ${methName} -->\n";
if (isset($dmap[$methName])) {
if ($dmap[$methName]["docstring"]) {
$r=new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]["docstring"]),
"string");
} else {
$r=new XML_RPC_Response(new XML_RPC_Value("", "string"));
}
} else {
$r=new XML_RPC_Response(0,
$XML_RPC_err["introspect_unknown"],
$XML_RPC_str["introspect_unknown"]);
}
return $r;
}
$GLOBALS['XML_RPC_Server_dmap']=array(
"system.listMethods" =>
array("function" => "XML_RPC_Server_listMethods",
"signature" => $GLOBALS['XML_RPC_Server_listMethods_sig'],
"docstring" => $GLOBALS['XML_RPC_Server_listMethods_doc']),
"system.methodHelp" =>
array("function" => "XML_RPC_Server_methodHelp",
"signature" => $GLOBALS['XML_RPC_Server_methodHelp_sig'],
"docstring" => $GLOBALS['XML_RPC_Server_methodHelp_doc']),
"system.methodSignature" =>
array("function" => "XML_RPC_Server_methodSignature",
"signature" => $GLOBALS['XML_RPC_Server_methodSignature_sig'],
"docstring" => $GLOBALS['XML_RPC_Server_methodSignature_doc'])
);
$GLOBALS['XML_RPC_Server_debuginfo']="";
function XML_RPC_Server_debugmsg($m)
{
global $XML_RPC_Server_debuginfo;
$XML_RPC_Server_debuginfo=$XML_RPC_Server_debuginfo . $m . "\n";
}
class XML_RPC_Server
{
var $dmap=array();
function XML_RPC_Server($dispMap, $serviceNow=1)
{
global $HTTP_RAW_POST_DATA;
// dispMap is a despatch array of methods
// mapped to function names and signatures
// if a method
// doesn't appear in the map then an unknown
// method error is generated
$this->dmap=$dispMap;
if ($serviceNow) {
$this->service();
}
}
function serializeDebug()
{
global $XML_RPC_Server_debuginfo;
if ($XML_RPC_Server_debuginfo!="")
return "<!-- DEBUG INFO:\n\n" .
$XML_RPC_Server_debuginfo . "\n-->\n";
else
return "";
}
function service()
{
$r=$this->parseRequest();
$payload="<?xml version=\"1.0\"?>\n" .
$this->serializeDebug() .
$r->serialize();
Header("Content-type: text/xml\nContent-length: " .
strlen($payload));
print $payload;
}
function verifySignature($in, $sig)
{
for($i=0; $i<sizeof($sig); $i++) {
// check each possible signature in turn
$cursig=$sig[$i];
if (sizeof($cursig)==$in->getNumParams()+1) {
$itsOK=1;
for($n=0; $n<$in->getNumParams(); $n++) {
$p=$in->getParam($n);
// print "<!-- $p -->\n";
if ($p->kindOf() == "scalar") {
$pt=$p->scalartyp();
} else {
$pt=$p->kindOf();
}
// $n+1 as first type of sig is return type
if ($pt != $cursig[$n+1]) {
$itsOK=0;
$pno=$n+1; $wanted=$cursig[$n+1]; $got=$pt;
break;
}
}
if ($itsOK)
return array(1);
}
}
return array(0, "Wanted ${wanted}, got ${got} at param ${pno})");
}
function parseRequest($data="")
{
global $XML_RPC_xh,$HTTP_RAW_POST_DATA;
global $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml,
$XML_RPC_defencoding, $XML_RPC_Server_dmap;
if ($data=="") {
$data=$HTTP_RAW_POST_DATA;
}
$parser = xml_parser_create($XML_RPC_defencoding);
$XML_RPC_xh[$parser]=array();
$XML_RPC_xh[$parser]['st']="";
$XML_RPC_xh[$parser]['cm']=0;
$XML_RPC_xh[$parser]['isf']=0;
$XML_RPC_xh[$parser]['params']=array();
$XML_RPC_xh[$parser]['method']="";
// decompose incoming XML into request structure
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($parser, "XML_RPC_se", "XML_RPC_ee");
xml_set_character_data_handler($parser, "XML_RPC_cd");
xml_set_default_handler($parser, "XML_RPC_dh");
if (!xml_parse($parser, $data, 1)) {
// return XML error as a faultCode
$r=new XML_RPC_Response(0,
$XML_RPC_errxml+xml_get_error_code($parser),
sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
xml_parser_free($parser);
} else {
xml_parser_free($parser);
$m=new XML_RPC_Message($XML_RPC_xh[$parser]['method']);
// now add parameters in
for($i=0; $i<sizeof($XML_RPC_xh[$parser]['params']); $i++) {
// print "<!-- " . $XML_RPC_xh[$parser]['params'][$i]. "-->\n";
$plist.="$i - " . $XML_RPC_xh[$parser]['params'][$i]. " \n";
eval('$m->addParam(' . $XML_RPC_xh[$parser]['params'][$i]. ");");
}
XML_RPC_Server_debugmsg($plist);
// now to deal with the method
$methName=$XML_RPC_xh[$parser]['method'];
if (ereg("^system\.", $methName)) {
$dmap=$XML_RPC_Server_dmap; $sysCall=1;
} else {
$dmap=$this->dmap; $sysCall=0;
}
if (isset($dmap[$methName]['function'])) {
// dispatch if exists
if (isset($dmap[$methName]['signature'])) {
$sr=$this->verifySignature($m,
$dmap[$methName]['signature'] );
}
if ( (!isset($dmap[$methName]['signature'])) || $sr[0]) {
// if no signature or correct signature
if ($sysCall) {
eval('$r=' . $dmap[$methName]['function'] .
'($this, $m);');
} else {
eval('$r=' . $dmap[$methName]['function'] .
'($m);');
}
} else {
$r=new XML_RPC_Response(0,
$XML_RPC_err["incorrect_params"],
$XML_RPC_str["incorrect_params"].": ". $sr[1]);
}
} else {
// else prepare error response
$r=new XML_RPC_Response(0,
$XML_RPC_err["unknown_method"],
$XML_RPC_str["unknown_method"]);
}
}
return $r;
}
function echoInput() {
global $HTTP_RAW_POST_DATA;
// a debugging routine: just echos back the input
// packet as a string value
$r=new XML_RPC_Response;
$r->xv=new XML_RPC_Value( "'Aha said I: '" . $HTTP_RAW_POST_DATA, "string");
print $r->serialize();
}
}
?>
Jump to Line
Something went wrong with that request. Please try again.