Ejemplo n.º 1
0
 /**
  * {@inheritdoc}
  */
 public function send(RequestInterface $request, array $options = array())
 {
     $options += Client::$defaultOptions;
     $curlOptions = $options['curl'] + array(CURLOPT_URL => (string) $request->getUri(), CURLOPT_CUSTOMREQUEST => $request->getMethod(), CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_HTTPHEADER => \EasyRequest\get_headers($request), CURLOPT_ENCODING => $request->getHeaderLine('Accept-Encoding'), CURLOPT_NOBODY => $options['nobody'], CURLOPT_CONNECTTIMEOUT => $options['timeout'], CURLOPT_HTTP_VERSION => $request->getProtocolVersion() == '1.0' ? CURL_HTTP_VERSION_1_0 : CURL_HTTP_VERSION_1_1);
     if ($options['upload']) {
         $body = $request->getBody();
         $curlOptions += array(CURLOPT_UPLOAD => true, CURLOPT_READFUNCTION => function ($ch, $fp, $length) use($body) {
             return $body->read($length);
         });
     } elseif ($options['body']) {
         $curlOptions[CURLOPT_POSTFIELDS] = (string) $request->getBody();
     }
     if ($options['proxy']) {
         $curlOptions += array(CURLOPT_PROXY => $options['proxy'], CURLOPT_PROXYTYPE => $options['proxy_type']);
         if ($options['proxy_userpwd']) {
             $curlOptions[CURLOPT_PROXYUSERPWD] = $options['proxy_userpwd'];
         }
     }
     if ($options['bindto']) {
         $curlOptions[CURLOPT_INTERFACE] = $options['bindto'];
     }
     $header = $body = '';
     $curlOptions[CURLOPT_HEADERFUNCTION] = $this->handleResponseHeader($header);
     $ch = curl_init();
     curl_setopt_array($ch, $curlOptions);
     $result = curl_exec($ch);
     curl_close($ch);
     if ($result === false) {
         throw new Exception(sprintf('%d - %s', curl_errno($ch), curl_error($ch)));
     }
     $body = substr($result, strlen($header));
     return Response::parse($header, $body);
 }
Ejemplo n.º 2
0
 /**
  * {@inheritdoc}
  */
 public function send(RequestInterface $request, array $options = array())
 {
     static $ports = array('https' => 443, 'http' => 80, '' => 80);
     $options += Client::$defaultOptions;
     $uri = $request->getUri();
     $targetHost = $host = $uri->getHost();
     $targetPort = $port = $uri->getPort() ? $uri->getPort() : $ports[$uri->getScheme()];
     $requestTarget = $request->getRequestTarget();
     if ($options['proxy']) {
         list($host, $port) = explode(':', $options['proxy']);
         $requestTarget = (string) $uri;
     }
     if (!($stream = $this->getConnection($host, $port, $errno, $errstr, $options, $uri))) {
         throw new Exception(sprintf("Couldn't connect to %s:%s. %s - %s", $host, $port, $errno, $errstr));
     }
     $httpsThroughSocks = $options['proxy'] && $options['proxy_type'] != Client::PROXY_HTTP && $uri->getScheme() == 'https';
     $headers = \EasyRequest\get_headers($request);
     $headers[] = 'Connection: close';
     // handle proxy
     if ($options['proxy']) {
         try {
             switch ($options['proxy_type']) {
                 case Client::PROXY_HTTP:
                     if ($options['proxy_userpwd']) {
                         $headers[] = 'Proxy-Authorization: Basic ' . base64_encode($options['proxy_userpwd']);
                     }
                     break;
                 case Client::PROXY_SOCKS5:
                     $this->handleSocks5($stream, $options, $targetHost, $targetPort);
                     break;
                 case Client::PROXY_SOCKS4:
                 case Client::PROXY_SOCKS4A:
                     if ($options['proxy_userpwd']) {
                         // socks4 does not support authentication,
                         // if user give a wrong version, just handle it
                         $this->handleSocks5($stream, $options, $targetHost, $targetPort);
                     } else {
                         $this->handleSocks4($stream, $options, $targetHost, $targetPort);
                     }
                     break;
             }
         } catch (\Exception $e) {
             fclose($stream);
             throw $e;
         }
         if ($httpsThroughSocks) {
             $this->toggleCrypto($stream, true);
         }
     }
     // build request header
     $header = sprintf("%s %s HTTP/%s\r\n", $request->getMethod(), $requestTarget, $request->getProtocolVersion());
     $header .= implode("\r\n", $headers) . "\r\n";
     $header .= "\r\n";
     $this->sendRequest($header, $request->getBody(), $options, function ($message) use($stream) {
         fwrite($stream, $message);
     });
     $request->getBody()->close();
     // ignore some warning such as "SSL: Connection reset by peer",
     // this issue sometimes happen on some SOCKS servers while
     // browsing to HTTPS website.
     $httpsThroughSocks && ($level = error_reporting(~E_WARNING));
     $response = '';
     while (!feof($stream)) {
         $response .= fgets($stream, 1024);
     }
     fclose($stream);
     $httpsThroughSocks && error_reporting($level);
     list($header, $body) = explode("\r\n\r\n", $response, 2) + array('', '');
     $response = Response::parse($header, '');
     if ($response->getHeaderLine('Transfer-Encoding') == 'chunked') {
         $body = \EasyRequest\decode_chunked($body);
     }
     if ($response->getHeaderLine('Content-Encoding') == 'gzip') {
         $body = \EasyRequest\decode_gzip($body);
     }
     $response->getBody()->write($body);
     return $response;
 }