[ Index ]
 

Code source de b2evolution 2.1.0-beta

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/blogs/inc/_ext/xmlrpc/ -> _xmlrpcs.php (source)

   1  <?php
   2  /**

   3   * @package evocore

   4   * @subpackage xmlrpc {@link http://xmlrpc.usefulinc.com/doc/}

   5   * @copyright Edd Dumbill <edd@usefulinc.com> (C) 1999-2002

   6   */
   7  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
   8  
   9  // by Edd Dumbill (C) 1999-2002

  10  // <edd@usefulinc.com>

  11  // $Id: _xmlrpcs.php,v 1.3 2007/09/11 20:57:52 fplanque Exp $

  12  
  13  // Copyright (c) 1999,2000,2002 Edd Dumbill.

  14  // All rights reserved.

  15  //

  16  // Redistribution and use in source and binary forms, with or without

  17  // modification, are permitted provided that the following conditions

  18  // are met:

  19  //

  20  //    * Redistributions of source code must retain the above copyright

  21  //      notice, this list of conditions and the following disclaimer.

  22  //

  23  //    * Redistributions in binary form must reproduce the above

  24  //      copyright notice, this list of conditions and the following

  25  //      disclaimer in the documentation and/or other materials provided

  26  //      with the distribution.

  27  //

  28  //    * Neither the name of the "XML-RPC for PHP" nor the names of its

  29  //      contributors may be used to endorse or promote products derived

  30  //      from this software without specific prior written permission.

  31  //

  32  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

  33  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

  34  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

  35  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

  36  // REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

  37  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

  38  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

  39  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

  40  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

  41  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

  42  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

  43  // OF THE POSSIBILITY OF SUCH DAMAGE.

  44  
  45      // XML RPC Server class

  46      // requires: _xmlrpc.php

  47  
  48      if( CANUSEXMLRPC !== TRUE )
  49      {
  50          return;
  51      }
  52  
  53      global $xmlrpcI4;
  54      global $xmlrpcInt;
  55      global $xmlrpcDouble;
  56      global $xmlrpcBoolean;
  57      global $xmlrpcString;
  58      global $xmlrpcDateTime;
  59      global $xmlrpcBase64;
  60      global $xmlrpcArray;
  61      global $xmlrpcStruct;
  62  
  63      global $xmlrpcTypes;
  64      global $xmlrpc_valid_parents;
  65      global $xmlEntities;
  66      global $xmlrpcerr;
  67      global $xmlrpcstr;
  68      global $xmlrpc_defencoding;
  69      global $xmlrpc_internalencoding;
  70      global $xmlrpcName;
  71      global $xmlrpcVersion;
  72      global $xmlrpcerruser;
  73      global $xmlrpcerrxml;
  74      global $xmlrpc_backslash;
  75      global $_xh;
  76  
  77      // listMethods: either a string, or nothing

  78      $_xmlrpcs_listMethods_sig = array(array($xmlrpcArray, $xmlrpcString), array($xmlrpcArray));
  79      $_xmlrpcs_listMethods_doc = 'This method lists all the methods that the XML-RPC server knows how to dispatch';
  80      /**

  81       * listMethods: either a string, or nothing

  82       */
  83  	function _xmlrpcs_listMethods($server, $m)
  84      {
  85          global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
  86          $v=new xmlrpcval();
  87          $dmap=$server->dmap;
  88          $outAr=array();
  89          for(reset($dmap); list($key, $val)=each($dmap); )
  90          {
  91              $outAr[]=new xmlrpcval($key, 'string');
  92          }
  93          $dmap=$_xmlrpcs_dmap;
  94          for(reset($dmap); list($key, $val)=each($dmap); )
  95          {
  96              $outAr[]=new xmlrpcval($key, 'string');
  97          }
  98          $v->addArray($outAr);
  99          return new xmlrpcresp($v);
 100      }
 101  
 102      $_xmlrpcs_methodSignature_sig=array(array($xmlrpcArray, $xmlrpcString));
 103      $_xmlrpcs_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)';
 104      /**

 105        *

 106        */
 107  	function _xmlrpcs_methodSignature($server, $m)
 108      {
 109          global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
 110  
 111          $methName=$m->getParam(0);
 112          $methName=$methName->scalarval();
 113          if (ereg("^system\.", $methName))
 114          {
 115              $dmap=$_xmlrpcs_dmap; $sysCall=1;
 116          }
 117          else
 118          {
 119              $dmap=$server->dmap; $sysCall=0;
 120          }
 121          //    print "<!-- ${methName} -->\n";

 122          if (isset($dmap[$methName]))
 123          {
 124              if ($dmap[$methName]['signature'])
 125              {
 126                  $sigs=array();
 127                  $thesigs=$dmap[$methName]['signature'];
 128                  for($i=0; $i<sizeof($thesigs); $i++)
 129                  {
 130                      $cursig=array();
 131                      $inSig=$thesigs[$i];
 132                      for($j=0; $j<sizeof($inSig); $j++)
 133                      {
 134                          $cursig[]=new xmlrpcval($inSig[$j], 'string');
 135                      }
 136                      $sigs[]=new xmlrpcval($cursig, 'array');
 137                  }
 138                  $r=new xmlrpcresp(new xmlrpcval($sigs, 'array'));
 139              }
 140              else
 141              {
 142                  $r=new xmlrpcresp(new xmlrpcval('undef', 'string'));
 143              }
 144          }
 145          else
 146          {
 147              $r=new xmlrpcresp(0,$xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']);
 148          }
 149          return $r;
 150      }
 151  
 152      $_xmlrpcs_methodHelp_sig=array(array($xmlrpcString, $xmlrpcString));
 153      $_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string';
 154  	function _xmlrpcs_methodHelp($server, $m)
 155      {
 156          global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
 157  
 158          $methName=$m->getParam(0);
 159          $methName=$methName->scalarval();
 160          if (ereg("^system\.", $methName))
 161          {
 162              $dmap=$_xmlrpcs_dmap; $sysCall=1;
 163          }
 164          else
 165          {
 166              $dmap=$server->dmap; $sysCall=0;
 167          }
 168          // print "<!-- ${methName} -->\n";

 169          if (isset($dmap[$methName]))
 170          {
 171              if ($dmap[$methName]['docstring'])
 172              {
 173                  $r=new xmlrpcresp(new xmlrpcval($dmap[$methName]['docstring']), 'string');
 174              }
 175              else
 176              {
 177                  $r=new xmlrpcresp(new xmlrpcval('', 'string'));
 178              }
 179          }
 180          else
 181          {
 182              $r=new xmlrpcresp(0, $xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']);
 183          }
 184          return $r;
 185      }
 186  
 187      $_xmlrpcs_multicall_sig = array(array($xmlrpcArray, $xmlrpcArray));
 188      $_xmlrpcs_multicall_doc = 'Boxcar multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details';
 189  
 190  	function _xmlrpcs_multicall_error($err)
 191      {
 192          if (is_string($err))
 193          {
 194              global $xmlrpcerr, $xmlrpcstr;
 195              $str  = $xmlrpcstr["multicall_$err}"];
 196              $code = $xmlrpcerr["multicall_$err}"];
 197          }
 198          else
 199          {
 200              $code = $err->faultCode();
 201              $str = $err->faultString();
 202          }
 203          $struct['faultCode'] = new xmlrpcval($code, 'int');
 204          $struct['faultString'] = new xmlrpcval($str, 'string');
 205          return new xmlrpcval($struct, 'struct');
 206      }
 207  
 208  	function _xmlrpcs_multicall_do_call($server, $call)
 209      {
 210          if ($call->kindOf() != 'struct')
 211          {
 212              return _xmlrpcs_multicall_error('notstruct');
 213          }
 214          $methName = $call->structmem('methodName');
 215          if (!$methName)
 216          {
 217              return _xmlrpcs_multicall_error('nomethod');
 218          }
 219          if ($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string')
 220          {
 221              return _xmlrpcs_multicall_error('notstring');
 222          }
 223          if ($methName->scalarval() == 'system.multicall')
 224          {
 225              return _xmlrpcs_multicall_error('recursion');
 226          }
 227  
 228          $params = $call->structmem('params');
 229          if (!$params)
 230          {
 231              return _xmlrpcs_multicall_error('noparams');
 232          }
 233          if ($params->kindOf() != 'array')
 234          {
 235              return _xmlrpcs_multicall_error('notarray');
 236          }
 237          $numParams = $params->arraysize();
 238  
 239          $msg = new xmlrpcmsg($methName->scalarval());
 240          for ($i = 0; $i < $numParams; $i++)
 241          {
 242              $msg->addParam($params->arraymem($i));
 243          }
 244  
 245          $result = $server->execute($msg);
 246  
 247          if ($result->faultCode() != 0)
 248          {
 249              return _xmlrpcs_multicall_error($result);    // Method returned fault.

 250          }
 251  
 252          return new xmlrpcval(array($result->value()), 'array');
 253      }
 254  
 255  	function _xmlrpcs_multicall($server, $m)
 256      {
 257          $calls = $m->getParam(0);
 258          $numCalls = $calls->arraysize();
 259          $result = array();
 260  
 261          for ($i = 0; $i < $numCalls; $i++)
 262          {
 263              $call = $calls->arraymem($i);
 264              $result[$i] = _xmlrpcs_multicall_do_call($server, $call);
 265          }
 266  
 267          return new xmlrpcresp(new xmlrpcval($result, 'array'));
 268      }
 269  
 270      $_xmlrpcs_dmap=array(
 271          'system.listMethods' => array(
 272              'function' => '_xmlrpcs_listMethods',
 273              'signature' => $_xmlrpcs_listMethods_sig,
 274              'docstring' => $_xmlrpcs_listMethods_doc),
 275          'system.methodHelp' => array(
 276              'function' => '_xmlrpcs_methodHelp',
 277              'signature' => $_xmlrpcs_methodHelp_sig,
 278              'docstring' => $_xmlrpcs_methodHelp_doc),
 279          'system.methodSignature' => array(
 280              'function' => '_xmlrpcs_methodSignature',
 281              'signature' => $_xmlrpcs_methodSignature_sig,
 282              'docstring' => $_xmlrpcs_methodSignature_doc),
 283          'system.multicall' => array(
 284              'function' => '_xmlrpcs_multicall',
 285              'signature' => $_xmlrpcs_multicall_sig,
 286              'docstring' => $_xmlrpcs_multicall_doc
 287          )
 288      );
 289  
 290      /**

 291       * Register a debugging message to be sent back in output

 292       *

 293       * evocore addition: make debug output optional

 294       */
 295      $_xmlrpc_debuginfo='';
 296  	function xmlrpc_debugmsg($m)
 297      {
 298          global $_xmlrpc_debuginfo;
 299          $_xmlrpc_debuginfo=$_xmlrpc_debuginfo . $m . "\n";
 300      }
 301  
 302      /**

 303       * @package evocore

 304       * @subpackage xmlrpc

 305       */
 306      class xmlrpc_server
 307      {
 308          var $dmap=array();
 309  
 310          /*

 311           * Constructor:

 312           */
 313  		function xmlrpc_server($dispMap='', $serviceNow=1)
 314          {
 315              global $HTTP_RAW_POST_DATA;
 316              // dispMap is a dispatch array of methods

 317              // mapped to function names and signatures

 318              // if a method

 319              // doesn't appear in the map then an unknown

 320              // method error is generated

 321              /* milosch - changed to make passing dispMap optional.

 322               * instead, you can use the class add_to_map() function

 323               * to add functions manually (borrowed from SOAPX4)

 324               */
 325              if($dispMap)
 326              {
 327                  $this->dmap = $dispMap;
 328                  if($serviceNow)
 329                  {
 330                      $this->service();
 331                  }
 332              }
 333          }
 334  
 335  		function serializeDebug()
 336          {
 337              global $_xmlrpc_debuginfo;
 338              if ($_xmlrpc_debuginfo!='')
 339              {
 340                  return "<!-- DEBUG INFO:\n\n" . xmlrpc_encode_entitites($_xmlrpc_debuginfo) . "\n-->\n";
 341              }
 342              else
 343              {
 344                  return '';
 345              }
 346          }
 347  
 348  		function service()
 349          {
 350              //global $xmlrpc_defencoding;

 351  
 352              $r=$this->parseRequest();
 353              //$payload='<?xml version="1.0" encoding="' . $xmlrpc_defencoding . '"?' . '>' . "\n"

 354              // TODO: charset:  encoding=\"iso-8859-1\"

 355              $payload='<?xml version="1.0" ?' . '>' . "\n"
 356                  . $this->serializeDebug()                            // Include debug info as comments
 357                  . $r->serialize();
 358              header('Content-Type: text/xml');
 359              header('Content-Length: ' . (int)strlen($payload));
 360  
 361              logIO( 'O', "service() response:\n".$payload );
 362  
 363              print $payload;
 364          }
 365  
 366          /**

 367           * add a method to the dispatch map

 368           */
 369  		function add_to_map($methodname,$function,$sig,$doc)
 370          {
 371              $this->dmap[$methodname] = array(
 372                  'function'  => $function,
 373                  'signature' => $sig,
 374                  'docstring' => $doc
 375              );
 376          }
 377  
 378  		function verifySignature($in, $sig)
 379          {
 380              for($i=0; $i<sizeof($sig); $i++)
 381              {
 382                  // check each possible signature in turn

 383                  $cursig=$sig[$i];
 384                  if (sizeof($cursig)==$in->getNumParams()+1)
 385                  {
 386                      $itsOK=1;
 387                      for($n=0; $n<$in->getNumParams(); $n++)
 388                      {
 389                          $p=$in->getParam($n);
 390                          // print "<!-- $p -->\n";

 391                          if ($p->kindOf() == 'scalar')
 392                          {
 393                              $pt=$p->scalartyp();
 394                          }
 395                          else
 396                          {
 397                              $pt=$p->kindOf();
 398                          }
 399                          // $n+1 as first type of sig is return type

 400                          if ($pt != $cursig[$n+1])
 401                          {
 402                              $itsOK=0;
 403                              $pno=$n+1; $wanted=$cursig[$n+1]; $got=$pt;
 404                              break;
 405                          }
 406                      }
 407                      if ($itsOK)
 408                      {
 409                          return array(1,'');
 410                      }
 411                  }
 412              }
 413              if (isset($wanted))
 414                  return array(0, "Wanted $wanted}, got $got} at param $pno})");
 415              else
 416                  return array(0, "No method signature matches number of parameters");
 417          }
 418  
 419          /**

 420           *

 421           */
 422  		function parseRequest($data='')
 423          {
 424              global $_xh,$HTTP_RAW_POST_DATA;
 425              global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding,
 426              $_xmlrpcs_dmap, $xmlrpc_internalencoding;
 427  
 428              if ($data=='')
 429              {
 430                  $data=$HTTP_RAW_POST_DATA;
 431              }
 432              // xmlrpc_debugmsg( 'Data received: ['.$data.']' );

 433  
 434              // G. Giunta 2005/02/13: we do NOT expect to receive html entities

 435              // so we do not try to convert them into xml character entities

 436              //$data = xmlrpc_html_entity_xlate($data);

 437              $parser = xml_parser_create($xmlrpc_defencoding);
 438  
 439              $_xh[$parser]=array();
 440              //$_xh[$parser]['st']='';

 441              //$_xh[$parser]['cm']=0;

 442              $_xh[$parser]['isf']=0;
 443              $_xh[$parser]['isf_reason']='';
 444              $_xh[$parser]['params']=array();
 445              $_xh[$parser]['stack']=array();
 446              $_xh[$parser]['valuestack'] = array();
 447              $_xh[$parser]['method']='';
 448  
 449              // decompose incoming XML into request structure

 450  
 451              xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
 452              // G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell

 453              // the xml parser to give us back data in the expected charset

 454              xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $xmlrpc_internalencoding);
 455  
 456              xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
 457              xml_set_character_data_handler($parser, 'xmlrpc_cd');
 458              xml_set_default_handler($parser, 'xmlrpc_dh');
 459              if (!xml_parse($parser, $data, 1))
 460              {
 461                  // return XML error as a faultCode

 462                  $r=new xmlrpcresp(0,
 463                  $xmlrpcerrxml+xml_get_error_code($parser),
 464                  sprintf('XML error: %s at line %d',
 465                      xml_error_string(xml_get_error_code($parser)),
 466                      xml_get_current_line_number($parser)));
 467                  xml_parser_free($parser);
 468              }
 469              else
 470              if ($_xh[$parser]['isf'])
 471              {
 472                  xml_parser_free($parser);
 473                  $r=new xmlrpcresp(0,
 474                      $xmlrpcerr['invalid_request'],
 475                      $xmlrpcstr['invalid_request'] . ' ' . $_xh[$parser]['isf_reason']);
 476              }
 477              else
 478              {
 479                  xml_parser_free($parser);
 480  
 481                  $m=new xmlrpcmsg($_xh[$parser]['method']);
 482                  // now add parameters in

 483                  // fp> commented out because it is commented out below: $plist='';

 484                  //$allOK = 1;

 485                  for($i=0; $i<sizeof($_xh[$parser]['params']); $i++)
 486                  {
 487                      //print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n";

 488                      // dh> commented out for PHP 5.2: $plist.="$i - " .  $_xh[$parser]['params'][$i]. ";\n";

 489                      //$allOK = 0;

 490                      //@eval('$m->addParam(' . $_xh[$parser]['params'][$i]. '); $allOK=1;');

 491                      @$m->addParam($_xh[$parser]['params'][$i]);
 492                      //if (!$allOK)

 493                      //{

 494                      //    break;

 495                      //}

 496                  }
 497                  // uncomment this to really see what the server's getting!

 498                  // xmlrpc_debugmsg($plist);

 499                  //if (!$allOK)

 500                  //{

 501                  //    $r = new xmlrpcresp(0,

 502                    //        $xmlrpcerr['incorrect_params'],

 503                  //        $xmlrpcstr['incorrect_params'] . ": xml error in param " . $i);

 504                  //}

 505                  //else

 506                  //{

 507                      $r = $this->execute($m);
 508                  //}

 509              }
 510              return $r;
 511          }
 512  
 513  		function execute ($m)
 514          {
 515              global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
 516              // now to deal with the method

 517              $methName = $m->method();
 518              logIO( 'I', 'Called method:'.$methName );
 519              $sysCall = ereg("^system\.", $methName);
 520              $dmap = $sysCall ? $_xmlrpcs_dmap : $this->dmap;
 521  
 522              if (!isset($dmap[$methName]['function']))
 523              {
 524                  // No such method

 525                  logIO( 'O', 'No such method:'.$methName );
 526                  return new xmlrpcresp(0,
 527                      $xmlrpcerr['unknown_method'],
 528                      $xmlrpcstr['unknown_method']);
 529              }
 530  
 531              // Check signature.

 532              if (isset($dmap[$methName]['signature']))
 533              {
 534                  $sig = $dmap[$methName]['signature'];
 535                  list($ok, $errstr) = $this->verifySignature($m, $sig);
 536                  if(!$ok)
 537                  {
 538                      // Didn't match.

 539                      logIO( 'O', 'Invalid signature.' );
 540                      return new xmlrpcresp(
 541                          0,
 542                          $xmlrpcerr['incorrect_params'],
 543                          $xmlrpcstr['incorrect_params'] . ": $errstr}"
 544                      );
 545                  }
 546              }
 547  
 548              $func = $dmap[$methName]['function'];
 549  
 550              if ($sysCall)
 551              {
 552                  return call_user_func($func, $this, $m);
 553              }
 554              else
 555              {
 556                  return call_user_func($func, $m);
 557              }
 558          }
 559  
 560  		function echoInput()
 561          {
 562              global $HTTP_RAW_POST_DATA;
 563  
 564              // a debugging routine: just echos back the input

 565              // packet as a string value

 566  
 567              $r=new xmlrpcresp;
 568              $r->xv=new xmlrpcval( "'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
 569              print $r->serialize();
 570          }
 571      }
 572      
 573  /*

 574   * $Log: _xmlrpcs.php,v $

 575   * Revision 1.3  2007/09/11 20:57:52  fplanque

 576   * minor fixes

 577   *

 578   * Revision 1.2  2007/06/26 02:40:54  fplanque

 579   * security checks

 580   *

 581   * Revision 1.1  2007/06/25 10:59:17  fplanque

 582   * MODULES (refactored MVC)

 583   *

 584   * Revision 1.7  2006/12/03 00:06:39  fplanque

 585   * minor

 586   *

 587   */
 588  ?>


Généré le : Thu Nov 29 23:58:50 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics