| [ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
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 /* $Id: class.xmlrpc_client.inc.php 20295 2006-02-15 12:31:25Z $ */ 35 36 class xmlrpc_client 37 { 38 var $path; 39 var $server; 40 var $port=0; 41 var $method='http'; 42 var $errno; 43 var $errstr; 44 var $debug=0; 45 var $username=''; 46 var $password=''; 47 var $cert=''; 48 var $certpass=''; 49 var $verifypeer=1; 50 var $verifyhost=1; 51 var $no_multicall=False; 52 var $proxy = ''; 53 var $proxyport=0; 54 var $proxy_user = ''; 55 var $proxy_pass = ''; 56 /** 57 * List of http compression methods accepted by the client for responses. 58 * NB: PHP supports deflate, gzip compressions out of the box if compiled w. zlib 59 * 60 * NNB: you can set it to any non-empty array for HTTP11 and HTTPS, since 61 * in those cases it will be up to CURL to decide the compression methods 62 * it supports. You might check for the presence of 'zlib' in the output of 63 * curl_version() to determine wheter compression is supported or not 64 */ 65 var $accepted_compression = array(); 66 /** 67 * Name of compression scheme to be used for sending requests. 68 * Either null, gzip or deflate 69 */ 70 var $request_compression = ''; 71 /** 72 * CURL handle: used for keep-alive connections (PHP 4.3.8 up, see: 73 * http://curl.haxx.se/docs/faq.html#7.3) 74 */ 75 var $xmlrpc_curl_handle = null; 76 /// Whether to use persistent connections for http 1.1 and https 77 var $keepalive = false; 78 79 function xmlrpc_client($path, $server='', $port='', $method='') 80 { 81 // allow user to specify all params in $path 82 if($server == '' and $port == '' and $method == '') 83 { 84 $parts = parse_url($path); 85 $server = $parts['host']; 86 $path = $parts['path']; 87 if(isset($parts['query'])) 88 { 89 $path .= '?'.$parts['query']; 90 } 91 if(isset($parts['fragment'])) 92 { 93 $path .= '#'.$parts['fragment']; 94 } 95 if(isset($parts['port'])) 96 { 97 $port = $parts['port']; 98 } 99 if(isset($parts['scheme'])) 100 { 101 $method = $parts['scheme']; 102 } 103 if(isset($parts['user'])) 104 { 105 $this->username = $parts['user']; 106 } 107 if(isset($parts['pass'])) 108 { 109 $this->password = $parts['pass']; 110 } 111 } 112 if($path == '' || $path[0] != '/') 113 { 114 $this->path='/'.$path; 115 } 116 else 117 { 118 $this->path=$path; 119 } 120 $this->server=$server; 121 if($port != '') 122 { 123 $this->port=$port; 124 } 125 if($method != '') 126 { 127 $this->method=$method; 128 } 129 130 // if ZLIB is enabled, let the server by default accept compressed requests 131 if(function_exists('gzinflate') || ( 132 function_exists('curl_init') && (($info = curl_version()) && 133 ((is_string($info) && strpos($info, 'zlib') !== null) || isset($info['libz_version']))) 134 )) 135 { 136 $this->accepted_compression = array('gzip', 'deflate'); 137 } 138 139 // keepalives: enabled by default ONLY for PHP >= 4.3.8 140 // (see http://curl.haxx.se/docs/faq.html#7.3) 141 if(version_compare(phpversion(), '4.3.8') >= 0) 142 { 143 $this->keepalive = true; 144 } 145 } 146 147 function setDebug($in) 148 { 149 if ($in) 150 { 151 $this->debug = 1; 152 } 153 else 154 { 155 $this->debug = 0; 156 } 157 } 158 159 function setCredentials($u, $p) 160 { 161 $this->username=$u; 162 $this->password=$p; 163 } 164 165 function setCertificate($cert, $certpass) 166 { 167 $this->cert = $cert; 168 $this->certpass = $certpass; 169 } 170 171 function setSSLVerifyPeer($i) 172 { 173 $this->verifypeer = $i; 174 } 175 176 function setSSLVerifyHost($i) 177 { 178 $this->verifyhost = $i; 179 } 180 /** 181 * set proxy info 182 * 183 * @param string $proxyhost 184 * @param string $proxyport. Defaults to 8080 for HTTP and 443 for HTTPS 185 * @param string $proxyusername 186 * @param string $proxypassword 187 * @access public 188 */ 189 function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') 190 { 191 $this->proxy = $proxyhost; 192 $this->proxyport = $proxyport; 193 $this->proxy_user = $proxyusername; 194 $this->proxy_pass = $proxypassword; 195 } 196 197 function& send($msg, $timeout=0, $method='') 198 { 199 // if user does not specify http protocol, use native method of this client 200 // (i.e. method set during call to constructor) 201 if($method == '') 202 { 203 $method = $this->method; 204 } 205 206 if(is_array($msg)) 207 { 208 // $msg is an array of xmlrpcmsg's 209 $r =& $this->multicall($msg, $timeout, $method); 210 return $r; 211 } 212 elseif(is_string($msg)) 213 { 214 $n =& new xmlrpcmsg(''); 215 $n->payload = $msg; 216 $msg = $n; 217 } 218 219 // where msg is an xmlrpcmsg 220 $msg->debug=$this->debug; 221 222 switch($method) 223 { 224 case 'https': 225 $r =& $this->sendPayloadHTTPS( 226 $msg, 227 $this->server, 228 $this->port, 229 $timeout, 230 $this->username, 231 $this->password, 232 $this->cert, 233 $this->certpass, 234 $this->proxy, 235 $this->proxyport, 236 $this->proxy_user, 237 $this->proxy_pass, 238 'https', 239 $this->keepalive 240 ); 241 break; 242 case 'http11': 243 $r =& $this->sendPayloadCURL( 244 $msg, 245 $this->server, 246 $this->port, 247 $timeout, 248 $this->username, 249 $this->password, 250 null, 251 null, 252 $this->proxy, 253 $this->proxyport, 254 $this->proxy_user, 255 $this->proxy_pass, 256 'http', 257 $this->keepalive 258 ); 259 break; 260 case 'http10': 261 default: 262 $r =& $this->sendPayloadHTTP10( 263 $msg, 264 $this->server, 265 $this->port, 266 $timeout, 267 $this->username, 268 $this->password, 269 $this->proxy, 270 $this->proxyport, 271 $this->proxy_user, 272 $this->proxy_pass 273 ); 274 } 275 276 return $r; 277 } 278 279 function &sendPayloadHTTP10($msg, $server, $port, $timeout=0,$username='', $password='', 280 $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='') 281 { 282 if($port==0) 283 { 284 $port=80; 285 } 286 287 // Only create the payload if it was not created previously 288 if(empty($msg->payload)) 289 { 290 $msg->createPayload(); 291 } 292 293 // Deflate request body and set appropriate request headers 294 if(function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate')) 295 { 296 if($this->request_compression == 'gzip') 297 { 298 $a = @gzencode($msg->payload); 299 if($a) 300 { 301 $msg->payload = $a; 302 $encoding_hdr = "Content-Encoding: gzip\r\n"; 303 } 304 } 305 else 306 { 307 $a = @gzdeflate($msg->payload); 308 if($a) 309 { 310 $msg->payload = $a; 311 $encoding_hdr = "Content-Encoding: deflate\r\n"; 312 } 313 } 314 } 315 else 316 { 317 $encoding_hdr = ''; 318 } 319 320 // thanks to Grant Rauscher <grant7@firstworld.net> 321 // for this 322 $credentials=''; 323 if($username!='') 324 { 325 $credentials='Authorization: Basic ' . base64_encode($username . ':' . $password) . "\r\n"; 326 } 327 328 $accepted_encoding = ''; 329 if(is_array($this->accepted_compression) && count($this->accepted_compression)) 330 { 331 $accepted_encoding = 'Accept-Encoding: ' . implode(', ', $this->accepted_compression) . "\r\n"; 332 } 333 334 $proxy_credentials = ''; 335 if($proxyhost) 336 { 337 if($proxyport == 0) 338 { 339 $proxyport = 8080; 340 } 341 $connectserver = $proxyhost; 342 $connectport = $proxyport; 343 $uri = 'http://'.$server.':'.$port.$this->path; 344 if($proxyusername != '') 345 { 346 $proxy_credentials = 'Proxy-Authorization: Basic ' . base64_encode($proxyusername.':'.$proxypassword) . "\r\n"; 347 } 348 } 349 else 350 { 351 $connectserver = $server; 352 $connectport = $port; 353 $uri = $this->path; 354 } 355 356 $op= "POST " . $uri. " HTTP/1.0\r\n" 357 . "User-Agent: " . $GLOBALS['xmlrpcName'] . " " . $GLOBALS['xmlrpcVersion'] . "\r\n" 358 . 'X-EGW-Server: ' . $this->server . ' ' . "\r\n" 359 . 'X-EGW-Version: ' . $GLOBALS['egw_info']['server']['versions']['phpgwapi'] . "\r\n" 360 . "Host: ". $this->server . "\r\n" 361 . $credentials 362 . $proxy_credentials 363 . $accepted_encoding 364 . $encoding_hdr 365 . "Accept-Charset: " . $GLOBALS['xmlrpc_defencoding'] . "\r\n" 366 . "Content-Type: text/xml\r\nContent-Length: " 367 . strlen($msg->payload) . "\r\n\r\n" 368 . $msg->payload; 369 370 if($timeout>0) 371 { 372 $fp = @fsockopen($connectserver, $connectport, $this->errno, $this->errstr, $timeout); 373 } 374 else 375 { 376 $fp = @fsockopen($connectserver, $connectport, $this->errno, $this->errstr); 377 } 378 if($fp) 379 { 380 if($timeout>0 && function_exists('stream_set_timeout')) 381 { 382 stream_set_timeout($fp, $timeout); 383 } 384 } 385 else 386 { 387 $this->errstr='Connect error: '.$this->errstr; 388 $r = CreateObject( 389 'phpgwapi.xmlrpcresp', 390 '', 391 $GLOBALS['xmlrpcerr']['http_error'], 392 $GLOBALS['xmlrpcstr']['http_error'] 393 ); 394 return $r; 395 } 396 397 if(!fputs($fp, $op, strlen($op))) 398 { 399 $this->errstr = 'Write error'; 400 return CreateObject( 401 'phpgwapi.xmlrpcresp', 402 '', 403 $GLOBALS['xmlrpcerr']['http_error'], 404 $GLOBALS['xmlrpcstr']['http_error'] 405 ); 406 } 407 else 408 { 409 // should we reset errno and errstr on succesful socket connection? 410 } 411 $resp =& $msg->parseResponseFile($fp); 412 // shall we move this into parseresponsefile, cuz' we have to close the socket 1st 413 // and do the parsing second if we want to have recursive calls 414 // (i.e. redirects) 415 fclose($fp); 416 return $resp; 417 } 418 419 // contributed by Justin Miller <justin@voxel.net> 420 // requires curl to be built into PHP 421 // NB: CURL versions before 7.11.10 cannot use proxy to talk to https servers! 422 function &sendPayloadHTTPS($msg, $server, $port, $timeout=0,$username='', $password='', $cert='',$certpass='', 423 $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $keepalive=false) 424 { 425 $r =& $this->sendPayloadCURL($msg, $server, $port, $timeout, $username, $password, $cert, $certpass, 426 $proxyhost, $proxyport, $proxyusername, $proxypassword, $keepalive); 427 return $r; 428 } 429 430 function &sendPayloadCURL($msg, $server, $port, $timeout=0, $username='', $password='', $cert='', $certpass='', 431 $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $method='https', $keepalive=false) 432 { 433 if(!function_exists('curl_init')) 434 { 435 $r = CreateObject( 436 'phpgwapi.xmlrpcresp', 437 '', 438 $GLOBALS['xmlrpcerr']['no_curl'], 439 $GLOBALS['xmlrpcstr']['no_curl'] 440 ); 441 return $r; 442 } 443 444 if($method == 'https') 445 { 446 if(($info = curl_version()) && 447 ((is_string($info) && strpos($info, 'OpenSSL') === null) || (is_array($info) && !isset($info['ssl_version'])))) 448 { 449 $this->errstr = 'SSL unavailable on this install'; 450 $r = CreateObject( 451 'phpgwapi.xmlrpcresp', 452 '', 453 $GLOBALS['xmlrpcerr']['no_ssl'], 454 $GLOBALS['xmlrpcstr']['no_ssl'] 455 ); 456 return $r; 457 } 458 } 459 460 if($port == 0) 461 { 462 if($method == 'http') 463 { 464 $port = 80; 465 } 466 else 467 { 468 $port = 443; 469 } 470 } 471 472 // Only create the payload if it was not created previously 473 if(empty($msg->payload)) 474 { 475 $msg->createPayload(); 476 } 477 478 // Deflate request body and set appropriate request headers 479 if(function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate')) 480 { 481 if($this->request_compression == 'gzip') 482 { 483 $a = @gzencode($msg->payload); 484 if($a) 485 { 486 $msg->payload = $a; 487 $encoding_hdr = "Content-Encoding: gzip"; 488 } 489 } 490 else 491 { 492 $a = @gzdeflate($msg->payload); 493 if($a) 494 { 495 $msg->payload = $a; 496 $encoding_hdr = "Content-Encoding: deflate"; 497 } 498 } 499 } 500 else 501 { 502 $encoding_hdr = ''; 503 } 504 505 if(!$keepalive || !$this->xmlrpc_curl_handle) 506 { 507 $curl = curl_init($method . '://' . $server . ':' . $port . $this->path); 508 if($keepalive) 509 { 510 $this->xmlrpc_curl_handle = $curl; 511 } 512 } 513 else 514 { 515 $curl = $this->xmlrpc_curl_handle; 516 } 517 518 // results into variable 519 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 520 521 if($this->debug) 522 { 523 curl_setopt($curl, CURLOPT_VERBOSE, 1); 524 } 525 curl_setopt($curl, CURLOPT_USERAGENT, $GLOBALS['xmlrpcName'].' '.$GLOBALS['xmlrpcVersion']); 526 // required for XMLRPC: post the data 527 curl_setopt($curl, CURLOPT_POST, 1); 528 // the data 529 curl_setopt($curl, CURLOPT_POSTFIELDS, $msg->payload); 530 531 // return the header too 532 curl_setopt($curl, CURLOPT_HTTPHEADER, array( 533 'X-EGW-Server: ' . $this->server, 534 'X-EGW-Version: ' . $GLOBALS['egw_info']['server']['versions']['phpgwapi'], 535 'Content-Type: text/xml' 536 )); 537 538 // will only work with PHP >= 5.0 539 // NB: if we set an empty string, CURL will add http header indicating 540 // ALL methods it is supporting. This is possibly a better option than 541 // letting the user tell what curl can / cannot do... 542 if(is_array($this->accepted_compression) && count($this->accepted_compression)) 543 { 544 //curl_setopt($curl, CURLOPT_ENCODING, implode(',', $this->accepted_compression)); 545 curl_setopt($curl, CURLOPT_ENCODING, ''); 546 } 547 // extra headers 548 $headers = array('Content-Type: text/xml', 'Accept-Charset: '.$GLOBALS['xmlrpc_internalencoding']); 549 // if no keepalive is wanted, let the server know it in advance 550 if(!$keepalive) 551 { 552 $headers[] = 'Connection: close'; 553 } 554 // request compression header 555 if($encoding_hdr) 556 { 557 $headers[] = $encoding_hdr; 558 } 559 560 curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 561 // timeout is borked 562 if($timeout) 563 { 564 curl_setopt($curl, CURLOPT_TIMEOUT, $timeout == 1 ? 1 : $timeout - 1); 565 } 566 567 if($username && $password) 568 { 569 curl_setopt($curl, CURLOPT_USERPWD,"$username:$password"); 570 } 571 572 if($method == 'https') 573 { 574 // set cert file 575 if($cert) 576 { 577 curl_setopt($curl, CURLOPT_SSLCERT, $cert); 578 } 579 // set cert password 580 if($certpass) 581 { 582 curl_setopt($curl, CURLOPT_SSLCERTPASSWD, $certpass); 583 } 584 // whether to verify remote host's cert 585 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifypeer); 586 // whether to verify cert's common name (CN); 0 for no, 1 to verify that it exists, and 2 to verify that it matches the hostname used 587 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $this->verifyhost); 588 } 589 590 // proxy info 591 if($proxyhost) 592 { 593 if($proxyport == 0) 594 { 595 $proxyport = 8080; // NB: even for HTTPS, local connection is on port 8080 596 } 597 curl_setopt($curl, CURLOPT_PROXY,$proxyhost.':'.$proxyport); 598 //curl_setopt($curl, CURLOPT_PROXYPORT,$proxyport); 599 if($proxyusername) 600 { 601 curl_setopt($curl, CURLOPT_PROXYUSERPWD, $proxyusername.':'.$proxypassword); 602 } 603 } 604 605 $result = curl_exec($curl); 606 607 if(!$result) 608 { 609 $this->errstr = 'Write error'; 610 $resp = CreateObject( 611 'phpgwapi.xmlrpcresp', 612 '', 613 $GLOBALS['xmlrpcerr']['curl_fail'], 614 $GLOBALS['xmlrpcstr']['curl_fail'] . ': ' . curl_error($curl) 615 ); 616 if(!$keepalive) 617 { 618 curl_close($curl); 619 } 620 } 621 else 622 { 623 if(!$keepalive) 624 { 625 curl_close($curl); 626 } 627 $resp =& $msg->parseResponse($result, true); 628 } 629 return $resp; 630 } 631 632 function& multicall($msgs, $timeout=0, $method='http') 633 { 634 $results = false; 635 636 if(!$this->no_multicall) 637 { 638 $results = $this->_try_multicall($msgs, $timeout, $method); 639 if($results !== false) 640 { 641 // Either the system.multicall succeeded, or the send 642 // failed (e.g. due to HTTP timeout). In either case, 643 // we're done for now. 644 return $results; 645 } 646 else 647 { 648 // system.multicall unsupported by server, 649 // don't try it next time... 650 $this->no_multicall = true; 651 } 652 } 653 654 // system.multicall is unupported by server: 655 // Emulate multicall via multiple requests 656 $results = array(); 657 foreach($msgs as $msg) 658 { 659 $results[] =& $this->send($msg, $timeout, $method); 660 } 661 return $results; 662 } 663 664 // Attempt to boxcar $msgs via system.multicall. 665 function _try_multicall($msgs, $timeout, $method) 666 { 667 // Construct multicall message 668 $calls = array(); 669 foreach($msgs as $msg) 670 { 671 $call['methodName'] =& new xmlrpcval($msg->method(),'string'); 672 $numParams = $msg->getNumParams(); 673 $params = array(); 674 for($i = 0; $i < $numParams; $i++) 675 { 676 $params[$i] = $msg->getParam($i); 677 } 678 $call['params'] =& new xmlrpcval($params, 'array'); 679 $calls[] =& new xmlrpcval($call, 'struct'); 680 } 681 $multicall =& new xmlrpcmsg('system.multicall'); 682 $multicall->addParam(new xmlrpcval($calls, 'array')); 683 684 // Attempt RPC call 685 $result =& $this->send($multicall, $timeout, $method); 686 //if(!is_object($result)) 687 //{ 688 // return ($result || 0); // transport failed 689 //} 690 691 if($result->faultCode() != 0) 692 { 693 return false; // system.multicall failed 694 } 695 696 // Unpack responses. 697 $rets = $result->value(); 698 if($rets->kindOf() != 'array') 699 { 700 return false; // bad return type from system.multicall 701 } 702 $numRets = $rets->arraysize(); 703 if($numRets != count($msgs)) 704 { 705 return false; // wrong number of return values. 706 } 707 708 $response = array(); 709 for($i = 0; $i < $numRets; $i++) 710 { 711 $val = $rets->arraymem($i); 712 switch($val->kindOf()) 713 { 714 case 'array': 715 if($val->arraysize() != 1) 716 { 717 return false; // Bad value 718 } 719 // Normal return value 720 $response[$i] =& new xmlrpcresp($val->arraymem(0)); 721 break; 722 case 'struct': 723 $code = $val->structmem('faultCode'); 724 if($code->kindOf() != 'scalar' || $code->scalartyp() != 'int') 725 { 726 return false; 727 } 728 $str = $val->structmem('faultString'); 729 if($str->kindOf() != 'scalar' || $str->scalartyp() != 'string') 730 { 731 return false; 732 } 733 $response[$i] =& new xmlrpcresp(0, $code->scalarval(), $str->scalarval()); 734 break; 735 default: 736 return false; 737 } 738 } 739 return $response; 740 } 741 } // end class xmlrpc_client 742 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |