Server.php in XML/RPC package: inability to switch off debugging - suggested modification
"Pascal Van Hecke (Yahoo)" <[email protected]>
| Newsgroups | gmane.comp.php.pear.devel,gmane.comp.php.xml-rpc |
|---|---|
| Message-ID | <[email protected]> |
Hi,
In the Server.php file of the XML/RPC package (contributed by Edd Dumbill
and pearified by Stig Bakken), there's no option to switch of the output of
an (outcommented) debug log in the resulting XML-RPC response.
Because the XML_RPC_Server class only method is its constructor, and this
constructor does everything, the only way to modify this was by adding an
extra debug parameter in the constructor.
Because the current signature is:
function XML_RPC_Server($dispMap, $serviceNow=1)
and I wanted to have backwards compatibility, I changed the signature to
function XML_RPC_Server($dispMap, $option_array = 1)
and then checked the $option_array parameter for "arrayness" :-).
A possible constructor could be now:
$DB_RPC_RemoteDataObjectServer = new XML_RPC_Server
(
array
(
"query" => array
(
"function" =>
"DB_RPC_RemoteDataObjectServer_query",
)
//,
//"other_function"=> array
("function" => "test_rpc_server")
),
array
(
"debug" => 0
)
);
Part of the modified and attached Server.php file is quoted hereunder
(functions XML_RPC_Server and serializeDebug have been changed)
Could this maybe be incorporated in PEAR CVS?
Regards,
pascal van hecke
Line 150-94
class XML_RPC_Server
{
var $dmap=array();
var $debug;
// function XML_RPC_Server($dispMap, $serviceNow=1)//changed by pvh
function XML_RPC_Server($dispMap, $option_array = 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 (is_array($option_array))
// second parameter carries associative array with some
initialisation
{
if (array_key_exists("debug", $option_array))
$this->debug = $option_array["debug"];
if (array_key_exists("serviceNow", $option_array))
$serviceNow = $option_array["serviceNow"];
else
$serviceNow = 1;
}
else
// second parameter matches $servicenow param in old
signature
{
$serviceNow = $option_array;
}
if ($serviceNow)
{
$this->service();
}
}
function serializeDebug()
{
global $XML_RPC_Server_debuginfo;
if ($XML_RPC_Server_debuginfo!="" and $this->debug)
return "<!-- DEBUG INFO:\n\n" .
$XML_RPC_Server_debuginfo . "\n-->\n";
else
return "";
}
--
PEAR Development Mailing List (http://pear.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Server.php
(a/octet-stream, 11.9 KB)
<?php // by Edd Dumbill (C) 1999,2000 // <[email protected]> // $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 <[email protected]> // 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(); var $debug; // function XML_RPC_Server($dispMap, $serviceNow=1)//changed by pvh function XML_RPC_Server($dispMap, $option_array = 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 (is_array($option_array)) // second parameter carries associative array with some initialisation { if (array_key_exists("debug", $option_array)) $this->debug = $option_array["debug"]; if (array_key_exists("serviceNow", $option_array)) $serviceNow = $option_array["serviceNow"]; else $serviceNow = 1; } else // second parameter matches $servicenow param in old signature { $serviceNow = $option_array; } if ($serviceNow) { $this->service(); } } function serializeDebug() { global $XML_RPC_Server_debuginfo; if ($XML_RPC_Server_debuginfo!="" and $this->debug) 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(); } } ?>