Exemple #1
0
 /**
  * Another way to perform a query, with an array having all parameters.
  * Works the same way as query(), first item in array should be method name,
  * any subsequent items will be passed to remote server.
  */
 function query_arg($args)
 {
     $method = array_shift($args);
     // Create the request and encode it
     $request = new XMLRPC_Request($method, $args);
     $xml = $request->getXml();
     //		$this->use_gzip = 0;
     if ($this->use_gzip) {
         $xml = pack("C1C1C1C1VC1C1", 0x1f, 0x8b, 8, 0, 0, 2, 0xff) . gzdeflate($xml) . pack("VV", crc32($xml), strlen($xml));
     }
     $length = strlen($xml);
     // HTTP uses \r\n for lineendings
     $r = "\r\n";
     $request = "POST {$this->path} HTTP/1.0{$r}";
     $request .= "Host: {$this->server}{$r}";
     $request .= "Content-Type: text/xml{$r}";
     $request .= "User-Agent: {$this->useragent}{$r}";
     if ($this->gzip_available) {
         $request .= "Accept-Encoding: gzip;q=1, identity;1=0.5{$r}";
     }
     // We can decode gzip which we prefer. identify (clear) works too
     if ($this->use_gzip) {
         $request .= "Content-Encoding: gzip{$r}";
     }
     // Send content gziped
     $request .= "Content-Length: {$length}{$r}{$r}";
     $reqlen = strlen($request) + $length;
     $request .= $xml;
     //Now send the request
     if ($this->debug) {
         echo '<pre>' . $request . "</pre>\n\n";
     }
     $errno = 0;
     $errstr = "";
     if (!$this->fp) {
         if ($this->method == "https") {
             if (!is_readable($this->ssl_ca_cert)) {
                 $this->error = new XMLRPC_Error(XMLRPC_Error::CONNECT_FAILED, "SSL CA cert is missing or isnt readable.");
                 return false;
             }
             if (!is_readable($this->ssl_client_cert)) {
                 $this->error = new XMLRPC_Error(XMLRPC_Error::CONNECT_FAILED, "SSL client cert missing or isnt readable.");
                 return false;
             }
             // HTTPs connection
             $this->context = stream_context_create(array('ssl' => array('cafile' => $this->ssl_ca_cert, 'local_cert' => $this->ssl_client_cert)));
             $this->fp = @stream_socket_client("tls://" . $this->server . ":" . $this->port . "/", $errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $this->context);
         } else {
             $this->fp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout);
         }
     }
     if (!$this->fp) {
         $this->error = new XMLRPC_Error(XMLRPC_Error::CONNECT_FAILED, "Failed to connect to " . $this->server . ":" . $this->port . ": {$errstr}.");
         return false;
     }
     stream_set_blocking($this->fp, true);
     /*
     		$piecelen = 80000000;
     		if($reqlen > $piecelen)
     		{
     			$piece = null;
     			$offset = 0;
     			while($offset < $reqlen)
     			{
     				if($reqlen - $offset > $piecelen)
     				{
     					$piece = substr($request, $offset, $piecelen);
     					$offset+=$piecelen;
     				}else
     				{
     					$piece = substr($request, $offset);
     					$offset += $reqlen-$offset;
     				}
     				print "Wriing $offset -+ $piecelen..\n";
     				fputs($this->fp, $piece);
     			}
     		}
     		else
     */
     fputs($this->fp, $request);
     $contents = '';
     $headers = array();
     $gotFirstLine = false;
     $gettingHeaders = true;
     $contentLength = 0;
     // We want blocking on first request
     stream_set_blocking($this->fp, true);
     while (1) {
         $buff = fread($this->fp, 1024);
         // But if we got more data queued we dont want to block...
         stream_set_blocking($this->fp, false);
         $this->rxbuff .= $buff;
         if ($gettingHeaders) {
             while (1) {
                 $pos = strpos($this->rxbuff, "\r\n");
                 if ($pos === false) {
                     break;
                 }
                 $line = trim(substr($this->rxbuff, 0, $pos));
                 $this->rxbuff = substr($this->rxbuff, strlen($line) + 2);
                 if (!$gotFirstLine) {
                     //Check line for '200'
                     if (strstr($line, '200') === false) {
                         $this->error = new XMLRPC_Error(XMLRPC_Error::INVALID_STATUS_CODE, 'Failed to received XMLRPC response. HTTP status code was not 200');
                         return false;
                     }
                     $gotFirstLine = true;
                     continue;
                 }
                 if ($line == '') {
                     $gettingHeaders = false;
                     $contentLength = $headers['Content-Length'];
                     break;
                 }
                 list($k, $v) = explode(":", $line);
                 $headers[trim($k)] = trim($v);
             }
             if ($gettingHeaders) {
                 continue;
             }
         }
         if (strlen($this->rxbuff) >= $contentLength) {
             $contents = substr($this->rxbuff, 0, $contentLength);
             $this->rxbuff = substr($this->rxbuff, $contentLength);
             break;
         }
     }
     if ($this->gzip_available && array_key_exists("Content-Encoding", $headers)) {
         if ($headers['Content-Encoding'] == "gzip") {
             $ret = gzinflate(substr($contents, 10));
             if ($ret === false) {
                 // The decoding failed!
                 $this->error = new XMLRPC_Error(XMLRPC_Error::BROKEN_GZIP, 'XMLRPC response headers specified gzip encoding, failed to decompress.');
                 return false;
             }
             $contents = $ret;
         } else {
             // What encoding is this?!
             $this->error = new XMLRPC_Error(XMLRPC_Error::UNKNOWN_ENCODING, 'XLMRPC response headers specified unknown encoding: ' . $headers['Content-Encoding'] . '. Cannot decompress..');
             return false;
         }
     }
     if ($this->debug) {
         echo '<pre>' . $contents . "</pre>\n\n";
     }
     // Now parse what we 've got back
     $this->message = new XMLRPC_Message($contents);
     if (!$this->message->parse()) {
         // XML error
         if ($this->debug) {
             $this->error = new XMLRPC_Error(XMLRPC_Error::PARSE_ERROR, 'XMLRPC response parse error. Not well formed. Error: ' . $this->message->parseError);
         } else {
             $this->error = new XMLRPC_Error(XMLRPC_Error::PARSE_ERROR, 'XMLRPC response parse error. Not well formed.');
         }
         return false;
     }
     // Is the message a fault ?
     if ($this->message->messageType == 'fault') {
         $this->error = new XMLRPC_Error($this->message->faultCode, $this->message->faultString);
         return false;
     }
     // Message must be OK
     return true;
 }
 function query()
 {
     $args = func_get_args();
     $method = array_shift($args);
     $request = new XMLRPC_Request($method, $args);
     $length = $request->getLength();
     $xml = $request->getXml();
     $header = "Content-type: text/xml\r\nContent-length: {$length}\r\n";
     //choose transport
     if ($this->httpsWrapperEnabled()) {
         $opts = array('http' => array('method' => 'POST', 'header' => $header, 'content' => $xml), 'ssl' => array('cafile' => dirname(__FILE__) . '/cacert.pem', 'verify_peer' => true, 'verify_peer_name' => true));
         $contents = file_get_contents($this->url, false, stream_context_create($opts));
     } else {
         $ch = curl_init();
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);
         curl_setopt($ch, CURLOPT_HEADER, false);
         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
         curl_setopt($ch, CURLOPT_URL, $this->url);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
         curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: text/xml'));
         curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
         $contents = curl_exec($ch);
         curl_close($ch);
     }
     // Now parse what we've got back
     $this->message = new XMLRPC_Message($contents);
     if (!$this->message->parse()) {
         // XML error
         $this->error = new XMLRPC_Error(-32700, 'parse error. not well formed');
         return false;
     }
     // Is the message a fault?
     if ($this->message->messageType == 'fault') {
         $this->error = new XMLRPC_Error($this->message->faultCode, $this->message->faultString);
         return false;
     }
     // Message must be OK
     return true;
 }