📄 xmlrpc.php
字号:
foreach ($this->cookies as $name => $cookie) { if ($cookie['version']) { $cookieheader .= 'Cookie: $Version="' . $cookie['version'] . '"; '; $cookieheader .= $name . '="' . $cookie['value'] . '";'; if ($cookie['path']) $cookieheader .= ' $Path="' . $cookie['path'] . '";'; if ($cookie['domain']) $cookieheader .= ' $Domain="' . $cookie['domain'] . '";'; if ($cookie['port']) $cookieheader .= ' $Port="' . $cookie['domain'] . '";'; $cookieheader = substr($cookieheader, 0, -1) . "\r\n"; } else { $cookieheader .= 'Cookie: ' . $name . '=' . $cookie['value'] . "\r\n"; } } $op= 'POST ' . $uri. " HTTP/1.0\r\n" . 'User-Agent: ' . $GLOBALS['xmlrpcName'] . ' ' . $GLOBALS['xmlrpcVersion'] . "\r\n" . 'Host: '. $server . ':' . $port . "\r\n" . $credentials . $proxy_credentials . $accepted_encoding . $encoding_hdr . 'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings) . "\r\n" . $cookieheader . 'Content-Type: ' . $msg->content_type . "\r\nContent-Length: " . strlen($payload) . "\r\n\r\n" . $payload; if($this->debug > 1) { print "<PRE>\n---SENDING---\n" . htmlentities($op) . "\n---END---\n</PRE>"; // let the client see this now in case http times out... flush(); } if($timeout>0) { $fp=@fsockopen($connectserver, $connectport, $this->errno, $this->errstr, $timeout); } else { $fp=@fsockopen($connectserver, $connectport, $this->errno, $this->errstr); } if($fp) { if($timeout>0 && function_exists('stream_set_timeout')) { stream_set_timeout($fp, $timeout); } } else { $this->errstr='Connect error: '.$this->errstr; $r=&new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr . ' (' . $this->errno . ')'); return $r; } if(!fputs($fp, $op, strlen($op))) { $this->errstr='Write error'; $r=&new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr); return $r; } else { // reset errno and errstr on succesful socket connection $this->errstr = ''; } // G. Giunta 2005/10/24: close socket before parsing. // should yeld slightly better execution times, and make easier recursive calls (e.g. to follow http redirects) $ipd=''; while($data=fread($fp, 32768)) { // shall we check for $data === FALSE? // as per the manual, it signals an error $ipd.=$data; } fclose($fp); $r =& $msg->parseResponse($ipd, false, $this->return_type); return $r; } /** * @access private */ function &sendPayloadHTTPS($msg, $server, $port, $timeout=0, $username='', $password='', $authtype=1, $cert='',$certpass='', $cacert='', $cacertdir='', $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, $keepalive=false, $key='', $keypass='') { $r =& $this->sendPayloadCURL($msg, $server, $port, $timeout, $username, $password, $authtype, $cert, $certpass, $cacert, $cacertdir, $proxyhost, $proxyport, $proxyusername, $proxypassword, $proxyauthtype, 'https', $keepalive, $key, $keypass); return $r; } /** * Contributed by Justin Miller <justin@voxel.net> * Requires curl to be built into PHP * NB: CURL versions before 7.11.10 cannot use proxy to talk to https servers! * @access private */ function &sendPayloadCURL($msg, $server, $port, $timeout=0, $username='', $password='', $authtype=1, $cert='', $certpass='', $cacert='', $cacertdir='', $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, $method='https', $keepalive=false, $key='', $keypass='') { if(!function_exists('curl_init')) { $this->errstr='CURL unavailable on this install'; $r=&new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_curl'], $GLOBALS['xmlrpcstr']['no_curl']); return $r; } if($method == 'https') { if(($info = curl_version()) && ((is_string($info) && strpos($info, 'OpenSSL') === null) || (is_array($info) && !isset($info['ssl_version'])))) { $this->errstr='SSL unavailable on this install'; $r=&new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_ssl'], $GLOBALS['xmlrpcstr']['no_ssl']); return $r; } } if($port == 0) { if($method == 'http') { $port = 80; } else { $port = 443; } } // Only create the payload if it was not created previously if(empty($msg->payload)) { $msg->createPayload($this->request_charset_encoding); } // Deflate request body and set appropriate request headers $payload = $msg->payload; if(function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate')) { if($this->request_compression == 'gzip') { $a = @gzencode($payload); if($a) { $payload = $a; $encoding_hdr = 'Content-Encoding: gzip'; } } else { $a = @gzcompress($payload); if($a) { $payload = $a; $encoding_hdr = 'Content-Encoding: deflate'; } } } else { $encoding_hdr = ''; } if($this->debug > 1) { print "<PRE>\n---SENDING---\n" . htmlentities($payload) . "\n---END---\n</PRE>"; // let the client see this now in case http times out... flush(); } if(!$keepalive || !$this->xmlrpc_curl_handle) { $curl = curl_init($method . '://' . $server . ':' . $port . $this->path); if($keepalive) { $this->xmlrpc_curl_handle = $curl; } } else { $curl = $this->xmlrpc_curl_handle; } // results into variable curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); if($this->debug) { curl_setopt($curl, CURLOPT_VERBOSE, 1); } curl_setopt($curl, CURLOPT_USERAGENT, $GLOBALS['xmlrpcName'].' '.$GLOBALS['xmlrpcVersion']); // required for XMLRPC: post the data curl_setopt($curl, CURLOPT_POST, 1); // the data curl_setopt($curl, CURLOPT_POSTFIELDS, $payload); // return the header too curl_setopt($curl, CURLOPT_HEADER, 1); // will only work with PHP >= 5.0 // NB: if we set an empty string, CURL will add http header indicating // ALL methods it is supporting. This is possibly a better option than // letting the user tell what curl can / cannot do... if(is_array($this->accepted_compression) && count($this->accepted_compression)) { //curl_setopt($curl, CURLOPT_ENCODING, implode(',', $this->accepted_compression)); // empty string means 'any supported by CURL' (shall we catch errors in case CURLOPT_SSLKEY undefined ?) if (count($this->accepted_compression) == 1) { curl_setopt($curl, CURLOPT_ENCODING, $this->accepted_compression[0]); } else curl_setopt($curl, CURLOPT_ENCODING, ''); } // extra headers $headers = array('Content-Type: ' . $msg->content_type , 'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings)); // if no keepalive is wanted, let the server know it in advance if(!$keepalive) { $headers[] = 'Connection: close'; } // request compression header if($encoding_hdr) { $headers[] = $encoding_hdr; } curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); // timeout is borked if($timeout) { curl_setopt($curl, CURLOPT_TIMEOUT, $timeout == 1 ? 1 : $timeout - 1); } if($username && $password) { curl_setopt($curl, CURLOPT_USERPWD, $username.':'.$password); if (defined('CURLOPT_HTTPAUTH')) { curl_setopt($curl, CURLOPT_HTTPAUTH, $authtype); } else if ($authtype != 1) { error_log('XML-RPC: xmlrpc_client::send: warning. Only Basic auth is supported by the current PHP/curl install'); } } if($method == 'https') { // set cert file if($cert) { curl_setopt($curl, CURLOPT_SSLCERT, $cert); } // set cert password if($certpass) { curl_setopt($curl, CURLOPT_SSLCERTPASSWD, $certpass); } // whether to verify remote host's cert curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifypeer); // set ca certificates file/dir if($cacert) { curl_setopt($curl, CURLOPT_CAINFO, $cacert); } if($cacertdir) { curl_setopt($curl, CURLOPT_CAPATH, $cacertdir); } // set key file (shall we catch errors in case CURLOPT_SSLKEY undefined ?) if($key) { curl_setopt($curl, CURLOPT_SSLKEY, $key); } // set key password (shall we catch errors in case CURLOPT_SSLKEY undefined ?) if($keypass) { curl_setopt($curl, CURLOPT_SSLKEYPASSWD, $keypass); } // 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 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $this->verifyhost); } // proxy info if($proxyhost) { if($proxyport == 0) { $proxyport = 8080; // NB: even for HTTPS, local connection is on port 8080 } curl_setopt($curl, CURLOPT_PROXY,$proxyhost.':'.$proxyport); //curl_setopt($curl, CURLOPT_PROXYPORT,$proxyport); if($proxyusername) { curl_setopt($curl, CURLOPT_PROXYUSERPWD, $proxyusername.':'.$proxypassword); if (defined('CURLOPT_PROXYAUTH')) { curl_setopt($curl, CURLOPT_PROXYAUTH, $proxyauthtype); } else if ($proxyauthtype != 1) { error_log('XML-RPC: xmlrpc_client::send: warning. Only Basic auth to proxy is supported by the current PHP/curl install'); } } } // NB: should we build cookie http headers by hand rather than let CURL do it? // the following code does not honour 'expires', 'path' and 'domain' cookie attributes // set to clint obj the the user... if (count($this->cookies)) { $cookieheader = ''; foreach ($this->cookies as $name => $cookie) { $cookieheader .= $name . '=' . $cookie['value'] . ', '; } curl_setopt($curl, CURLOPT_COOKIE, substr($cookieheader, 0, -2)); } $result = curl_exec($curl); if(!$result) { $this->errstr='no response'; $resp=&new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['curl_fail'], $GLOBALS['xmlrpcstr']['curl_fail']. ': '. curl_error($curl)); if(!$keepalive) { curl_close($curl); } } else { if(!$keepalive) { curl_close($curl); } $resp =& $msg->parseResponse($result, true, $this->return_type); } return $resp; } /** * Send an array of request messages and return an array of responses. * Unless $this->no_multicall has been set to true, it will try first * to use one single xmlrpc call to server method system.multicall, and * revert to sending many successive calls in case of failure. * This failure is also stored in $this->no_multicall for subsequent calls. * Unfortunately, there is no server error code universally used to denote * the fact that multicall is unsupported, so there is no way to reliably * distinguish between that and a temporary failure. * If you are sure that server supports multicall and do not want to * fallback to using many single calls, set the fourth parameter to FALSE. * * NB: trying to shoehorn extra functionality into existing syntax has resulted * in pretty much convoluted code... * * @param array $msgs an array of xmlrpcmsg objects * @param integer $timeout connection timeout (in seconds) * @param string $method the http protocol variant to be used * @param boolean fallback When true, upon receiveing an error during multicall, multiple single calls will be attempted * @return array * @access public */ function multicall($msgs, $timeout=0, $method='', $fallback=true) { if ($method == '') { $method = $this->method; } if(!$this->no_multicall) { $results = $this->_try_multicall($msgs, $timeout, $method); if(is_array($results)) { // System.multicall succeeded return $results; } else { // either system.multicall is unsupported by server, // or call failed for some other reason. if ($fallback) { // Don't try it next time... $this->no_multicall = true; } else { if (is_a($results, 'xmlrpcresp')) { $result = $results; } else { $result =& new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['multicall_error'], $GLOBALS['xmlrpcstr']['multicall_error']); } } } } else { // override fallback, in case careless user tries to do two // opposite things at the same time $fallback = true; } $results = array(); if ($fallback) { // system.multicall is (probably) unsupported by server: // emulate multicall via multiple requests foreach($msgs as $msg) { $results[] =& $this->send($msg, $timeout, $method);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -