| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- <?php
- // by Edd Dumbill (C) 1999,2000
- // <edd@usefulinc.com>
- // $Id: Server.php,v 1.2 2002/02/28 10:59:30 ssb Exp $
- // 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']="";
-
- $plist = '';
- // 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();
- }
- }
- ?>
|