[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/phpgwapi/inc/ -> class.xmlrpc_server_php.inc.php (source)

   1  <?php
   2  // Copyright (c) 1999,2000,2001 Edd Dumbill.
   3  // All rights reserved.
   4  //
   5  // Redistribution and use in source and binary forms, with or without
   6  // modification, are permitted provided that the following conditions
   7  // are met:
   8  //
   9  //    * Redistributions of source code must retain the above copyright
  10  //      notice, this list of conditions and the following disclaimer.
  11  //
  12  //    * Redistributions in binary form must reproduce the above
  13  //      copyright notice, this list of conditions and the following
  14  //      disclaimer in the documentation and/or other materials provided
  15  //      with the distribution.
  16  //
  17  //    * Neither the name of the "XML-RPC for PHP" nor the names of its
  18  //      contributors may be used to endorse or promote products derived
  19  //      from this software without specific prior written permission.
  20  //
  21  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25  // REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  28  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  30  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  32  // OF THE POSSIBILITY OF SUCH DAMAGE.
  33  
  34    /*
  35     * Incorporated for egroupware by Miles Lott <milos@groupwhere.org>         
  36     */
  37  
  38    /* $Id: class.xmlrpc_server_php.inc.php 20295 2006-02-15 12:31:25Z  $ */
  39  
  40      /* BEGIN server class */
  41      class xmlrpc_server extends xmlrpc_server_shared
  42      {
  43          var $dmap = array();
  44          var $authed = False;
  45          var $req_array = array();
  46          var $resp_struct = array();
  47          var $debug = False;
  48          var $method_requested;
  49          var $log = False; //'/tmp/xmlrpc.log';
  50  
  51  		function xmlrpc_server($dispMap='', $serviceNow=0)
  52          {
  53              // dispMap is a dispatch array of methods
  54              // mapped to function names and signatures
  55              // if a method
  56              // doesn't appear in the map then an unknown
  57              // method error is generated
  58              if($dispMap)
  59              {
  60                  $this->dmap = $dispMap;
  61                  if ($serviceNow)
  62                  {
  63                      $this->service();
  64                  }
  65              }
  66          }
  67  
  68  		function serializeDebug()
  69          {
  70              if ($GLOBALS['_xmlrpc_debuginfo'] != '')
  71              {
  72                  return "<!-- DEBUG INFO:\n\n" . $GLOBALS['_xmlrpc_debuginfo'] . "\n-->\n";
  73              }
  74              else
  75              {
  76                  return '';
  77              }
  78          }
  79  
  80  		function service($r=False)
  81          {
  82              if (!$r)    // do we have a response, or we need to parse the request
  83              {
  84                  $r = $this->parseRequest();
  85              }
  86              if (!$r)
  87              {
  88                  header('WWW-Authenticate: Basic realm="eGroupWare xmlrpc"');
  89                  header('HTTP/1.0 401 Unauthorized');
  90                  // for the log:
  91                  $payload = "WWW-Authenticate: Basic realm=\"eGroupWare xmlrpc\"\nHTTP/1.0 401 Unauthorized\n";
  92              }
  93              else
  94              {
  95                  $payload = "<?xml version=\"1.0\"?>\n" . $this->serializeDebug() . $r->serialize();
  96                  header("Content-type: text/xml");
  97                  header("Content-length: " . strlen($payload));
  98                  echo $GLOBALS['egw']->translation->convert($payload,$GLOBALS['egw']->translation->charset(),'utf-8');
  99              }
 100  
 101              if ($this->log)
 102              {
 103                  $fp = fopen($this->log,'a+');
 104                  fwrite($fp,"\n\n".date('Y-m-d H:i:s') . " authorized="
 105                      . ($this->authed?$GLOBALS['egw_info']['user']['account_lid']:'False')
 106                      . ", method='$this->last_method'\n");
 107                  fwrite($fp,"==== GOT ============================\n" . $GLOBALS['HTTP_RAW_POST_DATA']
 108                      . "\n==== RETURNED =======================\n");
 109                  fputs($fp,$payload);
 110                  fclose($fp);
 111              }
 112  
 113              if ($this->debug)
 114              {
 115                  $this->echoInput();
 116  
 117                  $fp = fopen('/tmp/xmlrpc_debug.out','w');
 118                  fputs($fp,$payload);
 119                  fclose($fp);
 120              }
 121          }
 122  
 123          /*
 124          add a method to the dispatch map
 125          */
 126  		function add_to_map($methodname,$function,$sig,$doc)
 127          {
 128              $this->dmap[$methodname] = array(
 129                  'function'  => $function,
 130                  'signature' => $sig,
 131                  'docstring' => $doc
 132              );
 133          }
 134  
 135  		function verifySignature($in, $sig)
 136          {
 137              for($i=0; $i<sizeof($sig); $i++)
 138              {
 139                  // check each possible signature in turn
 140                  $cursig = $sig[$i];
 141                  if (sizeof($cursig) == $in->getNumParams()+1)
 142                  {
 143                      $itsOK = 1;
 144                      for($n=0; $n<$in->getNumParams(); $n++)
 145                      {
 146                          $p = $in->getParam($n);
 147                          // print "<!-- $p -->\n";
 148                          if ($p->kindOf() == 'scalar')
 149                          {
 150                              $pt = $p->scalartyp();
 151                          }
 152                          else
 153                          {
 154                              $pt = $p->kindOf();
 155                          }
 156                          // $n+1 as first type of sig is return type
 157                          if ($pt != $cursig[$n+1])
 158                          {
 159                              $itsOK  = 0;
 160                              $pno    = $n+1;
 161                              $wanted = $cursig[$n+1];
 162                              $got    = $pt;
 163                              break;
 164                          }
 165                      }
 166                      if ($itsOK)
 167                      {
 168                          return array(1);
 169                      }
 170                  }
 171              }
 172              return array(0, "Wanted $wanted, got $got at param $pno)");
 173          }
 174  
 175  		function reqtoarray($_req,$recursed=False)
 176          {
 177              switch(gettype($_req))
 178              {
 179                  case 'object':
 180                      if($recursed)
 181                      {
 182                          return $_req->getval();
 183                      }
 184                      else
 185                      {
 186                          $this->req_array = $_req->getval();
 187                      }
 188                      break;
 189                  case 'array':
 190                      @reset($_req);
 191                      $ele = array();
 192                      while(list($key,$val) = @each($_req))
 193                      {
 194                          if($recursed)
 195                          {
 196                              $ele[$key] = $this->reqtoarray($val,True);
 197                          }
 198                          else
 199                          {
 200                              $this->req_array[$key] = $this->reqtoarray($val,True);
 201                          }
 202                      }
 203                      if($recursed)
 204                      {
 205                          return $ele;
 206                      }
 207                      break;
 208                  case 'string':
 209                  case 'integer':
 210                      if($recursed)
 211                      {
 212                          return $_req;
 213                      }
 214                      else
 215                      {
 216                          $this->req_array[] = $_req;
 217                      }
 218                      break;
 219                  default:
 220                      break;
 221              }
 222          }
 223  
 224  		function build_resp($_res)
 225          {
 226              if (is_array($_res))
 227              {
 228                  $i = 0;
 229                  $is_array = True;
 230                  foreach($_res as $key => $val)
 231                  {
 232                      $ele[$key] = $this->build_resp($val,True);
 233                      $is_array = $is_array && $i === $key;
 234                      ++$i;
 235                  }
 236                  return CreateObject('phpgwapi.xmlrpcval',$ele,$is_array ? 'array' : 'struct');
 237              }
 238              $_type = (is_integer($_res) ? 'int' : gettype($_res));
 239  
 240              if ($_type == 'string' && (ereg('^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$',$_res) ||
 241                  ereg('^[0-9]{4}[0-9]{2}[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$',$_res)))
 242              {
 243                  $_type = 'dateTime.iso8601';
 244              }
 245              // Passing an integer of 0 to the xmlrpcval constructor results in the value being lost. (jengo)
 246              if ($_type == 'int' && $_res == 0)
 247              {
 248                  return CreateObject('phpgwapi.xmlrpcval','0',$_type);
 249              }
 250              return CreateObject('phpgwapi.xmlrpcval',$_res,$_type);
 251          }
 252  
 253  		function parseRequest($data='')
 254          {
 255              $r = False;
 256  
 257              if ($data == '')
 258              {
 259                  $data = $GLOBALS['HTTP_RAW_POST_DATA'];
 260              }
 261              $parser = xml_parser_create($GLOBALS['xmlrpc_defencoding']);
 262  
 263              $GLOBALS['_xh'][$parser] = array();
 264              $GLOBALS['_xh'][$parser]['isf']    = 0;
 265              $GLOBALS['_xh'][$parser]['isf_reason'] = '';
 266              $GLOBALS['_xh'][$parser]['params'] = array();
 267              $GLOBALS['_xh'][$parser]['stack']=array();
 268              $GLOBALS['_xh'][$parser]['valuestack'] = array();
 269              $GLOBALS['_xh'][$parser]['method'] = '';
 270  
 271              // decompose incoming XML into request structure
 272              xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
 273              xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
 274              xml_set_character_data_handler($parser, 'xmlrpc_cd');
 275              xml_set_default_handler($parser, 'xmlrpc_dh');
 276              if (!xml_parse($parser, $data, 1))
 277              {
 278                  // return XML error as a faultCode
 279                  $r = CreateObject('phpgwapi.xmlrpcresp','',
 280                      $GLOBALS['xmlrpcerrxml'] + xml_get_error_code($parser),
 281                      sprintf('XML error: %s at line %d',
 282                      xml_error_string(xml_get_error_code($parser)),
 283                      xml_get_current_line_number($parser))
 284                  );
 285                  xml_parser_free($parser);
 286              }
 287              elseif ($GLOBALS['_xh'][$parser]['isf'])
 288              {
 289                  xml_parser_free($parser);
 290                  $r = CreateObject(
 291                      'phpgwapi.xmlrpcresp',
 292                      0,
 293                      $GLOBALS['xmlrpcerr']['invalid_request'],
 294                      $GLOBALS['xmlrpcstr']['invalid_request'] . ' ' . $GLOBALS['_xh'][$parser]['isf_reason']
 295                  );
 296              }
 297              else
 298              {
 299                  xml_parser_free($parser);
 300                  $m = CreateObject('phpgwapi.xmlrpcmsg',$GLOBALS['_xh'][$parser]['method']);
 301                  // now add parameters in
 302                  $plist = '';
 303                  for($i=0; $i<sizeof($GLOBALS['_xh'][$parser]['params']); $i++)
 304                  {
 305                      // print "<!-- " . $GLOBALS['_xh'][$parser]['params'][$i]. "-->\n");
 306                      $m->addParam($GLOBALS['_xh'][$parser]['params'][$i]);
 307                  }
 308  
 309                  // now to deal with the method
 310                  $methName  = $GLOBALS['_xh'][$parser]['method'];
 311                  $_methName = $GLOBALS['_xh'][$parser]['method'];
 312                  $this->last_method = $methName;
 313  
 314                  if(ereg("^system\.", $methName))
 315                  {
 316                      $dmap = $GLOBALS['_xmlrpcs_dmap'];
 317                      $sysCall=1;
 318                  }
 319                  else
 320                  {
 321                      $dmap = $this->dmap;
 322                      $sysCall=0;
 323                  }
 324  
 325                  if(!isset($dmap[$methName]['function']))
 326                  {
 327                      if($sysCall && $this->authed)
 328                      {
 329                          $r = CreateObject('phpgwapi.xmlrpcresp',
 330                              '',
 331                              $GLOBALS['xmlrpcerr']['unknown_method'],
 332                              $GLOBALS['xmlrpcstr']['unknown_method'] . ': ' . $methName
 333                          );
 334                          return $r;
 335                      }
 336                      if($this->authed)
 337                      {
 338                          /* phpgw mod - fetch the (bo) class methods to create the dmap */
 339                          // This part is to update session action to match
 340                          $this->method_requested = $methName;
 341  
 342                          $method = $methName;
 343                          $tmp = explode('.',$methName);
 344                          $methName = $tmp[2];
 345                          $service  = $tmp[1];
 346                          $class    = $tmp[0];
 347  
 348                          if(ereg('^service',$method))
 349                          {
 350                              $t = 'phpgwapi.' . $class . '.exec';
 351                              $dmap = ExecMethod($t,array($service,'list_methods','xmlrpc'));
 352                          }
 353                          elseif($GLOBALS['egw']->acl->check('run',1,$class))
 354                          {
 355                              /* This only happens if they have app access.  If not, we will
 356                               * return a fault below.
 357                               */
 358                              $listmeth = $class . '.' . $service . '.' . 'list_methods';
 359                              $dmap = ExecMethod($listmeth,'xmlrpc');
 360                          }
 361                          else
 362                          {
 363                              $r = CreateObject('phpgwapi.xmlrpcresp',
 364                                  '',
 365                                  $GLOBALS['xmlrpcerr']['no_access'],
 366                                  $GLOBALS['xmlrpcstr']['no_access']
 367                              );
 368                              return $r;
 369                          }
 370  
 371                          $this->dmap = $dmap;
 372                          /* _debug_array($this->dmap);exit; */
 373                      }
 374                  }
 375  
 376                  if (isset($dmap[$methName]['function']))
 377                  {
 378                      // dispatch if exists
 379                      if (isset($dmap[$methName]['signature']))
 380                      {
 381                          list($sr, $errstr) = $this->verifySignature($m, $dmap[$methName]['signature']);
 382                          if(!$sr)
 383                          {
 384                              // Didn't match.
 385  
 386                              return CreateObject(
 387                                  'phpgwapi.xmlrpcresp',
 388                                  0,
 389                                  $GLOBALS['xmlrpcerr']['incorrect_params'],
 390                                  $GLOBALS['xmlrpcstr']['incorrect_params'] . ": $errstr}"
 391                              );
 392                          }
 393                      }
 394                      if((!isset($dmap[$methName]['signature'])) || $sr)
 395                      {
 396                          // if no signature or correct signature
 397                          if($sysCall)
 398                          {
 399                              $r = call_user_func($dmap[$methName]['function'], $this, $m);
 400                          }
 401                          else
 402                          {
 403                              if(function_exists($dmap[$methName]['function']))
 404                              {
 405                                  $r = call_user_func($dmap[$methName]['function'],$m);
 406                              }
 407                              else
 408                              {
 409                                  /* phpgw mod - finally, execute the function call and return the values */
 410                                  $params = $GLOBALS['_xh'][$parser]['params'][0];
 411                                  if(count($params) != 0)
 412                                  {
 413                                      $p = $params;
 414                                      $params = $p->getval();
 415                                  }
 416  
 417                                  // _debug_array($params);
 418                                  $this->reqtoarray($params);
 419                                  // decode from utf-8 to our charset
 420                                  $this->req_array = $GLOBALS['egw']->translation->convert($this->req_array,'utf-8');
 421                                  //_debug_array($this->req_array);
 422                                  if (ereg('^service',$method))
 423                                  {
 424                                      $res = ExecMethod('phpgwapi.service.exec',array($service,$methName,$this->req_array));
 425                                  }
 426                                  else
 427                                  {
 428                                      list($s,$c,$m) = explode('.',$_methName);
 429                                      $res = ExecMethod($s . '.' . $c . '.' . $dmap[$methName]['function'],$this->req_array);
 430                                  }
 431                                  //$this->resp_struct = array($this->build_resp($res,True));
 432                                  //@reset($this->resp_struct);
 433                                  //$r = CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$this->resp_struct,'struct'));
 434                                  // this fixes the unnecessary (and not standard-conform) array/xmlrpc struct around everything
 435                                  $r = CreateObject('phpgwapi.xmlrpcresp',$this->build_resp($res,True));
 436                                  // _debug_array($r);
 437                              }
 438                          }
 439                      }
 440                      else
 441                      {
 442                          $r = CreateObject('phpgwapi.xmlrpcresp',
 443                              '',
 444                              $GLOBALS['xmlrpcerr']['incorrect_params'],
 445                              $GLOBALS['xmlrpcstr']['incorrect_params'] . ': ' . $sr[1]
 446                          );
 447                      }
 448                  }
 449                  else
 450                  {
 451                      // else prepare error response
 452                      if(!$this->authed)
 453                      {
 454                          $r = False;    // send 401 header to force authorization
 455                              /*CreateObject('phpgwapi.xmlrpcresp',
 456                              CreateObject('phpgwapi.xmlrpcval',
 457                                  'UNAUTHORIZED',
 458                                  'string'
 459                              )
 460                          );*/
 461                      }
 462                      else
 463                      {
 464                          $r = CreateObject('phpgwapi.xmlrpcresp',
 465                              '',
 466                              $GLOBALS['xmlrpcerr']['unknown_method'],
 467                              $GLOBALS['xmlrpcstr']['unknown_method'] . ': ' . $methName
 468                          );
 469                      }
 470                  }
 471              }
 472              unset($GLOBALS['_xh'][$parser]);
 473              return $r;
 474          }
 475  
 476  		function echoInput()
 477          {
 478              // a debugging routine: just echos back the input
 479              // packet as a string value
 480  
 481              $r = CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',"'Aha said I: '"
 482                  . $GLOBALS['HTTP_RAW_POST_DATA'],'string'));
 483              //echo $r->serialize();
 484  
 485              $fp = fopen('/tmp/xmlrpc_debug.in','w');
 486              fputs($fp,$r->serialize);
 487              fputs($fp,$GLOBALS['HTTP_RAW_POST_DATA']);
 488              fclose($fp);
 489          }
 490  
 491  		function xmlrpc_error($error_number, $error_string)
 492          {
 493              $r = CreateObject('phpgwapi.xmlrpcresp',
 494                  '',
 495                  $error_number,
 496                  $error_string . ': ' . $this->last_method
 497              );
 498              $this->service($r);
 499              exit;
 500          }
 501      }
 502  ?>


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7