home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / Server.php < prev    next >
Encoding:
PHP Script  |  2004-03-24  |  11.6 KB  |  311 lines

  1. <?php
  2. // /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // by Edd Dumbill (C) 1999,2000
  4. // <edd@usefulinc.com>
  5.  
  6. // License is granted to use or modify this software ("XML-RPC for PHP")
  7. // for commercial or non-commercial use provided the copyright of the author
  8. // is preserved in any distributed or derivative work.
  9.  
  10. // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
  11. // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12. // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  13. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  14. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  15. // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  17. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  19. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20.  
  21. // Adapted to PEAR standards by Stig S∩┐╜her Bakken <stig@php.net>
  22. // /* $Id: Server.php,v 1.6 2004/03/15 13:58:39 pajoye Exp $ */
  23.  
  24. require_once "XML/RPC.php";
  25.  
  26. // listMethods: either a string, or nothing
  27. $GLOBALS['XML_RPC_Server_listMethods_sig'] =
  28.     array(array($GLOBALS['XML_RPC_Array'], $GLOBALS['XML_RPC_String']),
  29.           array($GLOBALS['XML_RPC_Array']));
  30. $GLOBALS['XML_RPC_Server_listMethods_doc'] =
  31.     'This method lists all the methods that the XML-RPC server knows how to dispatch';
  32.  
  33. function XML_RPC_Server_listMethods($server, $m)
  34. {
  35.     global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
  36.     $v = new XML_RPC_Value();
  37.     $dmap = $server->dmap;
  38.     $outAr = array();
  39.     for (reset($dmap); list($key, $val) = each($dmap); ) {
  40.         $outAr[] = new XML_RPC_Value($key, "string");
  41.     }
  42.     $dmap = $XML_RPC_Server_dmap;
  43.     for (reset($dmap); list($key, $val) = each($dmap); ) {
  44.         $outAr[] = new XML_RPC_Value($key, "string");
  45.     }
  46.     $v->addArray($outAr);
  47.     return new XML_RPC_Response($v);
  48. }
  49.  
  50. $GLOBALS['XML_RPC_Server_methodSignature_sig'] =
  51.     array(array($GLOBALS['XML_RPC_Array'], $GLOBALS['XML_RPC_String']));
  52. $GLOBALS['XML_RPC_Server_methodSignature_doc'] =
  53.     '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)';
  54.  
  55. function XML_RPC_Server_methodSignature($server, $m)
  56. {
  57.     global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
  58.  
  59.     $methName = $m->getParam(0);
  60.     $methName = $methName->scalarval();
  61.     if (ereg("^system\.", $methName)) {
  62.         $dmap = $XML_RPC_Server_dmap;
  63.         $sysCall = 1;
  64.     } else {
  65.         $dmap = $server->dmap;
  66.         $sysCall = 0;
  67.     }
  68.     //  print "<!-- ${methName} -->\n";
  69.     if (isset($dmap[$methName])) {
  70.         if ($dmap[$methName]["signature"]) {
  71.             $sigs = array();
  72.             $thesigs = $dmap[$methName]["signature"];
  73.             for ($i = 0; $i < sizeof($thesigs); $i++) {
  74.                 $cursig = array();
  75.                 $inSig = $thesigs[$i];
  76.                 for ($j = 0; $j < sizeof($inSig); $j++) {
  77.                     $cursig[] = new XML_RPC_Value($inSig[$j], "string");
  78.                 }
  79.                 $sigs[] = new XML_RPC_Value($cursig, "array");
  80.             }
  81.             $r = new XML_RPC_Response(new XML_RPC_Value($sigs, "array"));
  82.         } else {
  83.             $r = new XML_RPC_Response(new XML_RPC_Value("undef", "string"));
  84.         }
  85.     } else {
  86.         $r = new XML_RPC_Response(0, $XML_RPC_err["introspect_unknown"],
  87.                                      $XML_RPC_str["introspect_unknown"]);
  88.     }
  89.     return $r;
  90. }
  91.  
  92. $GLOBALS['XML_RPC_Server_methodHelp_sig'] =
  93.     array(array($GLOBALS['XML_RPC_String'], $GLOBALS['XML_RPC_String']));
  94. $GLOBALS['XML_RPC_Server_methodHelp_doc'] =
  95.     'Returns help text if defined for the method passed, otherwise returns an empty string';
  96.  
  97. function XML_RPC_Server_methodHelp($server, $m)
  98. {
  99.     global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
  100.  
  101.     $methName = $m->getParam(0);
  102.     $methName = $methName->scalarval();
  103.     if (ereg("^system\.", $methName)) {
  104.         $dmap = $XML_RPC_Server_dmap;
  105.         $sysCall = 1;
  106.     } else {
  107.         $dmap = $server->dmap;
  108.         $sysCall = 0;
  109.     }
  110.     //  print "<!-- ${methName} -->\n";
  111.     if (isset($dmap[$methName])) {
  112.         if ($dmap[$methName]["docstring"]) {
  113.             $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]["docstring"]), "string");
  114.         } else {
  115.             $r = new XML_RPC_Response(new XML_RPC_Value("", "string"));
  116.         }
  117.     } else {
  118.         $r = new XML_RPC_Response(0, $XML_RPC_err["introspect_unknown"],
  119.                                      $XML_RPC_str["introspect_unknown"]);
  120.     }
  121.     return $r;
  122. }
  123.  
  124. $GLOBALS['XML_RPC_Server_dmap'] = array(
  125.     "system.listMethods" =>
  126.         array("function"  => "XML_RPC_Server_listMethods",
  127.               "signature" => $GLOBALS['XML_RPC_Server_listMethods_sig'],
  128.               "docstring" => $GLOBALS['XML_RPC_Server_listMethods_doc']),
  129.  
  130.     "system.methodHelp" =>
  131.         array("function"  => "XML_RPC_Server_methodHelp",
  132.               "signature" => $GLOBALS['XML_RPC_Server_methodHelp_sig'],
  133.               "docstring" => $GLOBALS['XML_RPC_Server_methodHelp_doc']),
  134.  
  135.     "system.methodSignature" =>
  136.         array("function"  => "XML_RPC_Server_methodSignature",
  137.               "signature" => $GLOBALS['XML_RPC_Server_methodSignature_sig'],
  138.               "docstring" => $GLOBALS['XML_RPC_Server_methodSignature_doc'])
  139. );
  140.  
  141. $GLOBALS['XML_RPC_Server_debuginfo'] = "";
  142.  
  143. function XML_RPC_Server_debugmsg($m)
  144. {
  145.     global $XML_RPC_Server_debuginfo;
  146.     $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n";
  147. }
  148.  
  149. class XML_RPC_Server
  150. {
  151.     var $dmap = array();
  152.  
  153.     function XML_RPC_Server($dispMap, $serviceNow = 1)
  154.     {
  155.         global $HTTP_RAW_POST_DATA;
  156.         // dispMap is a despatch array of methods
  157.         // mapped to function names and signatures
  158.         // if a method
  159.         // doesn't appear in the map then an unknown
  160.         // method error is generated
  161.         $this->dmap = $dispMap;
  162.         if ($serviceNow) {
  163.             $this->service();
  164.         }
  165.     }
  166.  
  167.     function serializeDebug()
  168.     {
  169.         global $XML_RPC_Server_debuginfo;
  170.         if ($XML_RPC_Server_debuginfo != "")
  171.             return "<!-- DEBUG INFO:\n\n" . $XML_RPC_Server_debuginfo . "\n-->\n";
  172.         else
  173.             return "";
  174.     }
  175.  
  176.     function service()
  177.     {
  178.         $r = $this->parseRequest();
  179.         $payload = "<?xml version=\"1.0\"?>\n" .
  180.             $this->serializeDebug() .
  181.             $r->serialize();
  182.         header('Content-Length: ' . strlen($payload));
  183.         header('Content-Type: text/xml');
  184.         print $payload;
  185.     }
  186.  
  187.     function verifySignature($in, $sig)
  188.     {
  189.         for ($i = 0; $i < sizeof($sig); $i++) {
  190.             // check each possible signature in turn
  191.             $cursig = $sig[$i];
  192.             if (sizeof($cursig) == $in->getNumParams() + 1) {
  193.                 $itsOK = 1;
  194.                 for ($n = 0; $n < $in->getNumParams(); $n++) {
  195.                     $p = $in->getParam($n);
  196.                     // print "<!-- $p -->\n";
  197.                     if ($p->kindOf() == "scalar") {
  198.                         $pt = $p->scalartyp();
  199.                     } else {
  200.                         $pt = $p->kindOf();
  201.                     }
  202.                     // $n+1 as first type of sig is return type
  203.                     if ($pt != $cursig[$n+1]) {
  204.                         $itsOK = 0;
  205.                         $pno = $n+1;
  206.                         $wanted = $cursig[$n+1];
  207.                         $got = $pt;
  208.                         break;
  209.                     }
  210.                 }
  211.                 if ($itsOK)
  212.                     return array(1);
  213.             }
  214.         }
  215.         return array(0, "Wanted ${wanted}, got ${got} at param ${pno})");
  216.     }
  217.  
  218.     function parseRequest($data = "")
  219.     {
  220.         global $XML_RPC_xh,$HTTP_RAW_POST_DATA;
  221.         global $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml,
  222.             $XML_RPC_defencoding, $XML_RPC_Server_dmap;
  223.  
  224.         if ($data == "") {
  225.             $data = $HTTP_RAW_POST_DATA;
  226.         }
  227.         $parser = xml_parser_create($XML_RPC_defencoding);
  228.  
  229.         $XML_RPC_xh[$parser] = array();
  230.         $XML_RPC_xh[$parser]['st'] = "";
  231.         $XML_RPC_xh[$parser]['cm'] = 0;
  232.         $XML_RPC_xh[$parser]['isf'] = 0;
  233.         $XML_RPC_xh[$parser]['params'] = array();
  234.         $XML_RPC_xh[$parser]['method'] = "";
  235.  
  236.         $plist = '';
  237.  
  238.         // decompose incoming XML into request structure
  239.  
  240.         xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
  241.         xml_set_element_handler($parser, "XML_RPC_se", "XML_RPC_ee");
  242.         xml_set_character_data_handler($parser, "XML_RPC_cd");
  243.         xml_set_default_handler($parser, "XML_RPC_dh");
  244.         if (!xml_parse($parser, $data, 1)) {
  245.             // return XML error as a faultCode
  246.             $r = new XML_RPC_Response(0,
  247.                                       $XML_RPC_errxml+xml_get_error_code($parser),
  248.                                       sprintf("XML error: %s at line %d",
  249.                                               xml_error_string(xml_get_error_code($parser)),
  250.                                               xml_get_current_line_number($parser)));
  251.             xml_parser_free($parser);
  252.         } else {
  253.             xml_parser_free($parser);
  254.             $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']);
  255.             // now add parameters in
  256.             for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) {
  257.                 // print "<!-- " . $XML_RPC_xh[$parser]['params'][$i]. "-->\n";
  258.                 $plist .= "$i - " . $XML_RPC_xh[$parser]['params'][$i] . " \n";
  259.                 eval('$m->addParam(' . $XML_RPC_xh[$parser]['params'][$i] . ");");
  260.             }
  261.             XML_RPC_Server_debugmsg($plist);
  262.             // now to deal with the method
  263.             $methName = $XML_RPC_xh[$parser]['method'];
  264.             if (ereg("^system\.", $methName)) {
  265.                 $dmap = $XML_RPC_Server_dmap;
  266.                 $sysCall = 1;
  267.             } else {
  268.                 $dmap = $this->dmap;
  269.                 $sysCall = 0;
  270.             }
  271.             if (isset($dmap[$methName]['function'])) {
  272.                 // dispatch if exists
  273.                 if (isset($dmap[$methName]['signature'])) {
  274.                     $sr = $this->verifySignature($m,
  275.                                                  $dmap[$methName]['signature'] );
  276.                 }
  277.                 if ( (!isset($dmap[$methName]['signature'])) || $sr[0]) {
  278.                     // if no signature or correct signature
  279.                     if ($sysCall) {
  280.                         eval('$r=' . $dmap[$methName]['function'] . '($this, $m);');
  281.                     } else {
  282.                         eval('$r=' . $dmap[$methName]['function'] . '($m);');
  283.                     }
  284.                 } else {
  285.                     $r = new XML_RPC_Response(0, $XML_RPC_err["incorrect_params"],
  286.                                                  $XML_RPC_str["incorrect_params"] .
  287.                                                  ": " . $sr[1]);
  288.                 }
  289.             } else {
  290.                 // else prepare error response
  291.                 $r = new XML_RPC_Response(0, $XML_RPC_err["unknown_method"],
  292.                                              $XML_RPC_str["unknown_method"]);
  293.             }
  294.         }
  295.         return $r;
  296.     }
  297.  
  298.   function echoInput() {
  299.         global $HTTP_RAW_POST_DATA;
  300.  
  301.         // a debugging routine: just echos back the input
  302.         // packet as a string value
  303.  
  304.         $r = new XML_RPC_Response;
  305.         $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, "string");
  306.         print $r->serialize();
  307.   }
  308. }
  309.  
  310. ?>
  311.