Пример #1
0
 /**
  * Pick a random dir authority to query and perform the HTTP request for directory info
  *
  * @param string $uri Uri to request
  * @param string $directoryServer IP and port of the directory to query
  * @throws \Exception No authorities responded
  * @return \Dapphp\TorUtils\ProtocolReply The reply from the directory authority
  */
 private function _request($uri, $directoryServer = null)
 {
     reset($this->_serverList);
     do {
         // pick a server from the list, it is randomized in __construct
         $server = $this->getNextServer();
         if ($server === false) {
             throw new \Exception('No more directory servers available to query');
         }
         list($host, $port) = @explode(':', $server);
         if (!$port) {
             $port = 80;
         }
         $fp = fsockopen($host, $port, $errno, $errstr, $this->_connectTimeout);
         if (!$fp) {
             continue;
         }
         $request = $this->_getHttpRequest('GET', $host, $uri);
         fwrite($fp, $request);
         $response = '';
         while (!feof($fp)) {
             $response .= fgets($fp);
         }
         fclose($fp);
         list($headers, $body) = explode("\r\n\r\n", $response, 2);
         $headers = $this->_parseHttpResponseHeaders($headers);
         if ($headers['status_code'] !== '200') {
             throw new \Exception(sprintf('Directory returned a negative response code to request.  %s %s', $headers['status_code'], $headers['message']));
         }
         $encoding = isset($headers['headers']['content-encoding']) ? $headers['headers']['content-encoding'] : null;
         if ($encoding == 'deflate') {
             if (!function_exists('gzuncompress')) {
                 throw new \Exception('Directory response was gzip compressed but PHP does not have zlib support enabled');
             }
             $body = gzuncompress($body);
             if ($body === false) {
                 throw new \Exception('Failed to inflate response data');
             }
         } else {
             if ($encoding == 'identity') {
                 // nothing to do
             } else {
                 throw new \Exception('Directory sent response in an unknown encoding: ' . $encoding);
             }
         }
         break;
     } while (true);
     $reply = new ProtocolReply();
     $reply->appendReplyLine(sprintf('%s %s', $headers['status_code'], $headers['message']));
     $reply->appendReplyLines(explode("\n", $body));
     return $reply;
 }