home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / XML / RPC / Server.php < prev   
Encoding:
PHP Script  |  2008-07-02  |  22.8 KB  |  686 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * Server commands for our PHP implementation of the XML-RPC protocol
  7.  *
  8.  * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
  9.  * It has support for HTTP transport, proxies and authentication.
  10.  *
  11.  * PHP versions 4 and 5
  12.  *
  13.  * LICENSE: License is granted to use or modify this software
  14.  * ("XML-RPC for PHP") for commercial or non-commercial use provided the
  15.  * copyright of the author is preserved in any distributed or derivative work.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  *
  28.  * @category   Web Services
  29.  * @package    XML_RPC
  30.  * @author     Edd Dumbill <edd@usefulinc.com>
  31.  * @author     Stig Bakken <stig@php.net>
  32.  * @author     Martin Jansen <mj@php.net>
  33.  * @author     Daniel Convissor <danielc@php.net>
  34.  * @copyright  1999-2001 Edd Dumbill, 2001-2006 The PHP Group
  35.  * @version    CVS: $Id: Server.php,v 1.37 2006/10/28 16:42:34 danielc Exp $
  36.  * @link       http://pear.php.net/package/XML_RPC
  37.  */
  38.  
  39.  
  40. /**
  41.  * Pull in the XML_RPC class
  42.  */
  43. require_once 'XML/RPC.php';
  44.  
  45.  
  46. /**
  47.  * signature for system.listMethods: return = array,
  48.  * parameters = a string or nothing
  49.  * @global array $GLOBALS['XML_RPC_Server_listMethods_sig']
  50.  */
  51. $GLOBALS['XML_RPC_Server_listMethods_sig'] = array(
  52.     array($GLOBALS['XML_RPC_Array'],
  53.           $GLOBALS['XML_RPC_String']
  54.     ),
  55.     array($GLOBALS['XML_RPC_Array'])
  56. );
  57.  
  58. /**
  59.  * docstring for system.listMethods
  60.  * @global string $GLOBALS['XML_RPC_Server_listMethods_doc']
  61.  */
  62. $GLOBALS['XML_RPC_Server_listMethods_doc'] = 'This method lists all the'
  63.         . ' methods that the XML-RPC server knows how to dispatch';
  64.  
  65. /**
  66.  * signature for system.methodSignature: return = array,
  67.  * parameters = string
  68.  * @global array $GLOBALS['XML_RPC_Server_methodSignature_sig']
  69.  */
  70. $GLOBALS['XML_RPC_Server_methodSignature_sig'] = array(
  71.     array($GLOBALS['XML_RPC_Array'],
  72.           $GLOBALS['XML_RPC_String']
  73.     )
  74. );
  75.  
  76. /**
  77.  * docstring for system.methodSignature
  78.  * @global string $GLOBALS['XML_RPC_Server_methodSignature_doc']
  79.  */
  80. $GLOBALS['XML_RPC_Server_methodSignature_doc'] = 'Returns an array of known'
  81.         . ' signatures (an array of arrays) for the method name passed. If'
  82.         . ' no signatures are known, returns a none-array (test for type !='
  83.         . ' array to detect missing signature)';
  84.  
  85. /**
  86.  * signature for system.methodHelp: return = string,
  87.  * parameters = string
  88.  * @global array $GLOBALS['XML_RPC_Server_methodHelp_sig']
  89.  */
  90. $GLOBALS['XML_RPC_Server_methodHelp_sig'] = array(
  91.     array($GLOBALS['XML_RPC_String'],
  92.           $GLOBALS['XML_RPC_String']
  93.     )
  94. );
  95.  
  96. /**
  97.  * docstring for methodHelp
  98.  * @global string $GLOBALS['XML_RPC_Server_methodHelp_doc']
  99.  */
  100. $GLOBALS['XML_RPC_Server_methodHelp_doc'] = 'Returns help text if defined'
  101.         . ' for the method passed, otherwise returns an empty string';
  102.  
  103. /**
  104.  * dispatch map for the automatically declared XML-RPC methods.
  105.  * @global array $GLOBALS['XML_RPC_Server_dmap']
  106.  */
  107. $GLOBALS['XML_RPC_Server_dmap'] = array(
  108.     'system.listMethods' => array(
  109.         'function'  => 'XML_RPC_Server_listMethods',
  110.         'signature' => $GLOBALS['XML_RPC_Server_listMethods_sig'],
  111.         'docstring' => $GLOBALS['XML_RPC_Server_listMethods_doc']
  112.     ),
  113.     'system.methodHelp' => array(
  114.         'function'  => 'XML_RPC_Server_methodHelp',
  115.         'signature' => $GLOBALS['XML_RPC_Server_methodHelp_sig'],
  116.         'docstring' => $GLOBALS['XML_RPC_Server_methodHelp_doc']
  117.     ),
  118.     'system.methodSignature' => array(
  119.         'function'  => 'XML_RPC_Server_methodSignature',
  120.         'signature' => $GLOBALS['XML_RPC_Server_methodSignature_sig'],
  121.         'docstring' => $GLOBALS['XML_RPC_Server_methodSignature_doc']
  122.     )
  123. );
  124.  
  125. /**
  126.  * @global string $GLOBALS['XML_RPC_Server_debuginfo']
  127.  */
  128. $GLOBALS['XML_RPC_Server_debuginfo'] = '';
  129.  
  130.  
  131. /**
  132.  * Lists all the methods that the XML-RPC server knows how to dispatch
  133.  *
  134.  * @return object  a new XML_RPC_Response object
  135.  */
  136. function XML_RPC_Server_listMethods($server, $m)
  137. {
  138.     global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
  139.  
  140.     $v = new XML_RPC_Value();
  141.     $outAr = array();
  142.     foreach ($server->dmap as $key => $val) {
  143.         $outAr[] = new XML_RPC_Value($key, 'string');
  144.     }
  145.     foreach ($XML_RPC_Server_dmap as $key => $val) {
  146.         $outAr[] = new XML_RPC_Value($key, 'string');
  147.     }
  148.     $v->addArray($outAr);
  149.     return new XML_RPC_Response($v);
  150. }
  151.  
  152. /**
  153.  * Returns an array of known signatures (an array of arrays)
  154.  * for the given method
  155.  *
  156.  * If no signatures are known, returns a none-array
  157.  * (test for type != array to detect missing signature)
  158.  *
  159.  * @return object  a new XML_RPC_Response object
  160.  */
  161. function XML_RPC_Server_methodSignature($server, $m)
  162. {
  163.     global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
  164.  
  165.     $methName = $m->getParam(0);
  166.     $methName = $methName->scalarval();
  167.     if (strpos($methName, 'system.') === 0) {
  168.         $dmap = $XML_RPC_Server_dmap;
  169.         $sysCall = 1;
  170.     } else {
  171.         $dmap = $server->dmap;
  172.         $sysCall = 0;
  173.     }
  174.     //  print "<!-- ${methName} -->\n";
  175.     if (isset($dmap[$methName])) {
  176.         if ($dmap[$methName]['signature']) {
  177.             $sigs = array();
  178.             $thesigs = $dmap[$methName]['signature'];
  179.             for ($i = 0; $i < sizeof($thesigs); $i++) {
  180.                 $cursig = array();
  181.                 $inSig = $thesigs[$i];
  182.                 for ($j = 0; $j < sizeof($inSig); $j++) {
  183.                     $cursig[] = new XML_RPC_Value($inSig[$j], 'string');
  184.                 }
  185.                 $sigs[] = new XML_RPC_Value($cursig, 'array');
  186.             }
  187.             $r = new XML_RPC_Response(new XML_RPC_Value($sigs, 'array'));
  188.         } else {
  189.             $r = new XML_RPC_Response(new XML_RPC_Value('undef', 'string'));
  190.         }
  191.     } else {
  192.         $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
  193.                                   $XML_RPC_str['introspect_unknown']);
  194.     }
  195.     return $r;
  196. }
  197.  
  198. /**
  199.  * Returns help text if defined for the method passed, otherwise returns
  200.  * an empty string
  201.  *
  202.  * @return object  a new XML_RPC_Response object
  203.  */
  204. function XML_RPC_Server_methodHelp($server, $m)
  205. {
  206.     global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
  207.  
  208.     $methName = $m->getParam(0);
  209.     $methName = $methName->scalarval();
  210.     if (strpos($methName, 'system.') === 0) {
  211.         $dmap = $XML_RPC_Server_dmap;
  212.         $sysCall = 1;
  213.     } else {
  214.         $dmap = $server->dmap;
  215.         $sysCall = 0;
  216.     }
  217.  
  218.     if (isset($dmap[$methName])) {
  219.         if ($dmap[$methName]['docstring']) {
  220.             $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]['docstring']),
  221.                                                         'string');
  222.         } else {
  223.             $r = new XML_RPC_Response(new XML_RPC_Value('', 'string'));
  224.         }
  225.     } else {
  226.         $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
  227.                                      $XML_RPC_str['introspect_unknown']);
  228.     }
  229.     return $r;
  230. }
  231.  
  232. /**
  233.  * @return void
  234.  */
  235. function XML_RPC_Server_debugmsg($m)
  236. {
  237.     global $XML_RPC_Server_debuginfo;
  238.     $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n";
  239. }
  240.  
  241.  
  242. /**
  243.  * A server for receiving and replying to XML RPC requests
  244.  *
  245.  * <code>
  246.  * $server = new XML_RPC_Server(
  247.  *     array(
  248.  *         'isan8' =>
  249.  *             array(
  250.  *                 'function' => 'is_8',
  251.  *                 'signature' =>
  252.  *                      array(
  253.  *                          array('boolean', 'int'),
  254.  *                          array('boolean', 'int', 'boolean'),
  255.  *                          array('boolean', 'string'),
  256.  *                          array('boolean', 'string', 'boolean'),
  257.  *                      ),
  258.  *                 'docstring' => 'Is the value an 8?'
  259.  *             ),
  260.  *     ),
  261.  *     1,
  262.  *     0
  263.  * ); 
  264.  * </code>
  265.  *
  266.  * @category   Web Services
  267.  * @package    XML_RPC
  268.  * @author     Edd Dumbill <edd@usefulinc.com>
  269.  * @author     Stig Bakken <stig@php.net>
  270.  * @author     Martin Jansen <mj@php.net>
  271.  * @author     Daniel Convissor <danielc@php.net>
  272.  * @copyright  1999-2001 Edd Dumbill, 2001-2006 The PHP Group
  273.  * @version    Release: 1.5.1
  274.  * @link       http://pear.php.net/package/XML_RPC
  275.  */
  276. class XML_RPC_Server
  277. {
  278.     /**
  279.      * Should the payload's content be passed through mb_convert_encoding()?
  280.      *
  281.      * @see XML_RPC_Server::setConvertPayloadEncoding()
  282.      * @since Property available since Release 1.5.1
  283.      * @var boolean
  284.      */
  285.     var $convert_payload_encoding = false;
  286.  
  287.     /**
  288.      * The dispatch map, listing the methods this server provides.
  289.      * @var array
  290.      */
  291.     var $dmap = array();
  292.  
  293.     /**
  294.      * The present response's encoding
  295.      * @var string
  296.      * @see XML_RPC_Message::getEncoding()
  297.      */
  298.     var $encoding = '';
  299.  
  300.     /**
  301.      * Debug mode (0 = off, 1 = on)
  302.      * @var integer
  303.      */
  304.     var $debug = 0;
  305.  
  306.     /**
  307.      * The response's HTTP headers
  308.      * @var string
  309.      */
  310.     var $server_headers = '';
  311.  
  312.     /**
  313.      * The response's XML payload
  314.      * @var string
  315.      */
  316.     var $server_payload = '';
  317.  
  318.  
  319.     /**
  320.      * Constructor for the XML_RPC_Server class
  321.      *
  322.      * @param array $dispMap   the dispatch map. An associative array
  323.      *                          explaining each function. The keys of the main
  324.      *                          array are the procedure names used by the
  325.      *                          clients. The value is another associative array
  326.      *                          that contains up to three elements:
  327.      *                            + The 'function' element's value is the name
  328.      *                              of the function or method that gets called.
  329.      *                              To define a class' method: 'class::method'.
  330.      *                            + The 'signature' element (optional) is an
  331.      *                              array describing the return values and
  332.      *                              parameters
  333.      *                            + The 'docstring' element (optional) is a
  334.      *                              string describing what the method does
  335.      * @param int $serviceNow  should the HTTP response be sent now?
  336.      *                          (1 = yes, 0 = no)
  337.      * @param int $debug       should debug output be displayed?
  338.      *                          (1 = yes, 0 = no)
  339.      *
  340.      * @return void
  341.      */
  342.     function XML_RPC_Server($dispMap, $serviceNow = 1, $debug = 0)
  343.     {
  344.         global $HTTP_RAW_POST_DATA;
  345.  
  346.         if ($debug) {
  347.             $this->debug = 1;
  348.         } else {
  349.             $this->debug = 0;
  350.         }
  351.  
  352.         $this->dmap = $dispMap;
  353.  
  354.         if ($serviceNow) {
  355.             $this->service();
  356.         } else {
  357.             $this->createServerPayload();
  358.             $this->createServerHeaders();
  359.         }
  360.     }
  361.  
  362.     /**
  363.      * @return string  the debug information if debug debug mode is on
  364.      */
  365.     function serializeDebug()
  366.     {
  367.         global $XML_RPC_Server_debuginfo, $HTTP_RAW_POST_DATA;
  368.  
  369.         if ($this->debug) {
  370.             XML_RPC_Server_debugmsg('vvv POST DATA RECEIVED BY SERVER vvv' . "\n"
  371.                                     . $HTTP_RAW_POST_DATA
  372.                                     . "\n" . '^^^ END POST DATA ^^^');
  373.         }
  374.  
  375.         if ($XML_RPC_Server_debuginfo != '') {
  376.             return "<!-- PEAR XML_RPC SERVER DEBUG INFO:\n\n"
  377.                    . $GLOBALS['XML_RPC_func_ereg_replace']('--', '- - ', $XML_RPC_Server_debuginfo)
  378.                    . "-->\n";
  379.         } else {
  380.             return '';
  381.         }
  382.     }
  383.  
  384.     /**
  385.      * Sets whether the payload's content gets passed through
  386.      * mb_convert_encoding()
  387.      *
  388.      * Returns PEAR_ERROR object if mb_convert_encoding() isn't available.
  389.      *
  390.      * @param int $in  where 1 = on, 0 = off
  391.      *
  392.      * @return void
  393.      *
  394.      * @see XML_RPC_Message::getEncoding()
  395.      * @since Method available since Release 1.5.1
  396.      */
  397.     function setConvertPayloadEncoding($in)
  398.     {
  399.         if ($in && !function_exists('mb_convert_encoding')) {
  400.             return $this->raiseError('mb_convert_encoding() is not available',
  401.                               XML_RPC_ERROR_PROGRAMMING);
  402.         }
  403.         $this->convert_payload_encoding = $in;
  404.     }
  405.  
  406.     /**
  407.      * Sends the response
  408.      *
  409.      * The encoding and content-type are determined by
  410.      * XML_RPC_Message::getEncoding()
  411.      *
  412.      * @return void
  413.      *
  414.      * @uses XML_RPC_Server::createServerPayload(),
  415.      *       XML_RPC_Server::createServerHeaders()
  416.      */
  417.     function service()
  418.     {
  419.         if (!$this->server_payload) {
  420.             $this->createServerPayload();
  421.         }
  422.         if (!$this->server_headers) {
  423.             $this->createServerHeaders();
  424.         }
  425.  
  426.         /*
  427.          * $server_headers needs to remain a string for compatibility with
  428.          * old scripts using this package, but PHP 4.4.2 no longer allows
  429.          * line breaks in header() calls.  So, we split each header into
  430.          * an individual call.  The initial replace handles the off chance
  431.          * that someone composed a single header with multiple lines, which
  432.          * the RFCs allow.
  433.          */
  434.         $this->server_headers = $GLOBALS['XML_RPC_func_ereg_replace']("[\r\n]+[ \t]+",
  435.                                 ' ', trim($this->server_headers));
  436.         $headers = $GLOBALS['XML_RPC_func_split']("[\r\n]+", $this->server_headers);
  437.         foreach ($headers as $header)
  438.         {
  439.             header($header);
  440.         }
  441.  
  442.         print $this->server_payload;
  443.     }
  444.  
  445.     /**
  446.      * Generates the payload and puts it in the $server_payload property
  447.      *
  448.      * If XML_RPC_Server::setConvertPayloadEncoding() was set to true,
  449.      * the payload gets passed through mb_convert_encoding()
  450.      * to ensure the payload matches the encoding set in the
  451.      * XML declaration.  The encoding type can be manually set via
  452.      * XML_RPC_Message::setSendEncoding().
  453.      *
  454.      * @return void
  455.      *
  456.      * @uses XML_RPC_Server::parseRequest(), XML_RPC_Server::$encoding,
  457.      *       XML_RPC_Response::serialize(), XML_RPC_Server::serializeDebug()
  458.      * @see  XML_RPC_Server::setConvertPayloadEncoding()
  459.      */
  460.     function createServerPayload()
  461.     {
  462.         $r = $this->parseRequest();
  463.         $this->server_payload = '<?xml version="1.0" encoding="'
  464.                               . $this->encoding . '"?>' . "\n"
  465.                               . $this->serializeDebug()
  466.                               . $r->serialize();
  467.         if ($this->convert_payload_encoding) {
  468.             $this->server_payload = mb_convert_encoding($this->server_payload,
  469.                                                         $this->encoding);
  470.         }
  471.     }
  472.  
  473.     /**
  474.      * Determines the HTTP headers and puts them in the $server_headers
  475.      * property
  476.      *
  477.      * @return boolean  TRUE if okay, FALSE if $server_payload isn't set.
  478.      *
  479.      * @uses XML_RPC_Server::createServerPayload(),
  480.      *       XML_RPC_Server::$server_headers
  481.      */
  482.     function createServerHeaders()
  483.     {
  484.         if (!$this->server_payload) {
  485.             return false;
  486.         }
  487.         $this->server_headers = 'Content-Length: '
  488.                               . strlen($this->server_payload) . "\r\n"
  489.                               . 'Content-Type: text/xml;'
  490.                               . ' charset=' . $this->encoding;
  491.         return true;
  492.     }
  493.  
  494.     /**
  495.      * @return array
  496.      */
  497.     function verifySignature($in, $sig)
  498.     {
  499.         for ($i = 0; $i < sizeof($sig); $i++) {
  500.             // check each possible signature in turn
  501.             $cursig = $sig[$i];
  502.             if (sizeof($cursig) == $in->getNumParams() + 1) {
  503.                 $itsOK = 1;
  504.                 for ($n = 0; $n < $in->getNumParams(); $n++) {
  505.                     $p = $in->getParam($n);
  506.                     // print "<!-- $p -->\n";
  507.                     if ($p->kindOf() == 'scalar') {
  508.                         $pt = $p->scalartyp();
  509.                     } else {
  510.                         $pt = $p->kindOf();
  511.                     }
  512.                     // $n+1 as first type of sig is return type
  513.                     if ($pt != $cursig[$n+1]) {
  514.                         $itsOK = 0;
  515.                         $pno = $n+1;
  516.                         $wanted = $cursig[$n+1];
  517.                         $got = $pt;
  518.                         break;
  519.                     }
  520.                 }
  521.                 if ($itsOK) {
  522.                     return array(1);
  523.                 }
  524.             }
  525.         }
  526.         if (isset($wanted)) {
  527.             return array(0, "Wanted ${wanted}, got ${got} at param ${pno}");
  528.         } else {
  529.             $allowed = array();
  530.             foreach ($sig as $val) {
  531.                 end($val);
  532.                 $allowed[] = key($val);
  533.             }
  534.             $allowed = array_unique($allowed);
  535.             $last = count($allowed) - 1;
  536.             if ($last > 0) {
  537.                 $allowed[$last] = 'or ' . $allowed[$last];
  538.             }
  539.             return array(0,
  540.                          'Signature permits ' . implode(', ', $allowed)
  541.                                 . ' parameters but the request had '
  542.                                 . $in->getNumParams());
  543.         }
  544.     }
  545.  
  546.     /**
  547.      * @return object  a new XML_RPC_Response object
  548.      *
  549.      * @uses XML_RPC_Message::getEncoding(), XML_RPC_Server::$encoding
  550.      */
  551.     function parseRequest($data = '')
  552.     {
  553.         global $XML_RPC_xh, $HTTP_RAW_POST_DATA,
  554.                 $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml,
  555.                 $XML_RPC_defencoding, $XML_RPC_Server_dmap;
  556.  
  557.         if ($data == '') {
  558.             $data = $HTTP_RAW_POST_DATA;
  559.         }
  560.  
  561.         $this->encoding = XML_RPC_Message::getEncoding($data);
  562.         $parser_resource = xml_parser_create($this->encoding);
  563.         $parser = (int) $parser_resource;
  564.  
  565.         $XML_RPC_xh[$parser] = array();
  566.         $XML_RPC_xh[$parser]['cm']     = 0;
  567.         $XML_RPC_xh[$parser]['isf']    = 0;
  568.         $XML_RPC_xh[$parser]['params'] = array();
  569.         $XML_RPC_xh[$parser]['method'] = '';
  570.         $XML_RPC_xh[$parser]['stack'] = array();    
  571.         $XML_RPC_xh[$parser]['valuestack'] = array();    
  572.  
  573.         $plist = '';
  574.  
  575.         // decompose incoming XML into request structure
  576.  
  577.         xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true);
  578.         xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee');
  579.         xml_set_character_data_handler($parser_resource, 'XML_RPC_cd');
  580.         if (!xml_parse($parser_resource, $data, 1)) {
  581.             // return XML error as a faultCode
  582.             $r = new XML_RPC_Response(0,
  583.                                       $XML_RPC_errxml+xml_get_error_code($parser_resource),
  584.                                       sprintf('XML error: %s at line %d',
  585.                                               xml_error_string(xml_get_error_code($parser_resource)),
  586.                                               xml_get_current_line_number($parser_resource)));
  587.             xml_parser_free($parser_resource);
  588.         } elseif ($XML_RPC_xh[$parser]['isf']>1) {
  589.             $r = new XML_RPC_Response(0,
  590.                                       $XML_RPC_err['invalid_request'],
  591.                                       $XML_RPC_str['invalid_request']
  592.                                       . ': '
  593.                                       . $XML_RPC_xh[$parser]['isf_reason']);
  594.             xml_parser_free($parser_resource);
  595.         } else {
  596.             xml_parser_free($parser_resource);
  597.             $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']);
  598.             // now add parameters in
  599.             for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) {
  600.                 // print '<!-- ' . $XML_RPC_xh[$parser]['params'][$i]. "-->\n";
  601.                 $plist .= "$i - " . var_export($XML_RPC_xh[$parser]['params'][$i], true) . " \n";
  602.                 $m->addParam($XML_RPC_xh[$parser]['params'][$i]);
  603.             }
  604.  
  605.             if ($this->debug) {
  606.                 XML_RPC_Server_debugmsg($plist);
  607.             }
  608.  
  609.             // now to deal with the method
  610.             $methName = $XML_RPC_xh[$parser]['method'];
  611.             if (strpos($methName, 'system.') === 0) {
  612.                 $dmap = $XML_RPC_Server_dmap;
  613.                 $sysCall = 1;
  614.             } else {
  615.                 $dmap = $this->dmap;
  616.                 $sysCall = 0;
  617.             }
  618.  
  619.             if (isset($dmap[$methName]['function'])
  620.                 && is_string($dmap[$methName]['function'])
  621.                 && strpos($dmap[$methName]['function'], '::') !== false)
  622.             {
  623.                 $dmap[$methName]['function'] =
  624.                         explode('::', $dmap[$methName]['function']);
  625.             }
  626.  
  627.             if (isset($dmap[$methName]['function'])
  628.                 && is_callable($dmap[$methName]['function']))
  629.             {
  630.                 // dispatch if exists
  631.                 if (isset($dmap[$methName]['signature'])) {
  632.                     $sr = $this->verifySignature($m,
  633.                                                  $dmap[$methName]['signature'] );
  634.                 }
  635.                 if (!isset($dmap[$methName]['signature']) || $sr[0]) {
  636.                     // if no signature or correct signature
  637.                     if ($sysCall) {
  638.                         $r = call_user_func($dmap[$methName]['function'], $this, $m);
  639.                     } else {
  640.                         $r = call_user_func($dmap[$methName]['function'], $m);
  641.                     }
  642.                     if (!is_a($r, 'XML_RPC_Response')) {
  643.                         $r = new XML_RPC_Response(0, $XML_RPC_err['not_response_object'],
  644.                                                   $XML_RPC_str['not_response_object']);
  645.                     }
  646.                 } else {
  647.                     $r = new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
  648.                                               $XML_RPC_str['incorrect_params']
  649.                                               . ': ' . $sr[1]);
  650.                 }
  651.             } else {
  652.                 // else prepare error response
  653.                 $r = new XML_RPC_Response(0, $XML_RPC_err['unknown_method'],
  654.                                           $XML_RPC_str['unknown_method']);
  655.             }
  656.         }
  657.         return $r;
  658.     }
  659.  
  660.     /**
  661.      * Echos back the input packet as a string value
  662.      *
  663.      * @return void
  664.      *
  665.      * Useful for debugging.
  666.      */
  667.     function echoInput()
  668.     {
  669.         global $HTTP_RAW_POST_DATA;
  670.  
  671.         $r = new XML_RPC_Response(0);
  672.         $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
  673.         print $r->serialize();
  674.     }
  675. }
  676.  
  677. /*
  678.  * Local variables:
  679.  * tab-width: 4
  680.  * c-basic-offset: 4
  681.  * c-hanging-comment-ender-p: nil
  682.  * End:
  683.  */
  684.  
  685. ?>
  686.