Beispiel #1
0
 /**
  * @coroutine
  *
  * @param \Icicle\Http\Message\Request $request
  * @param mixed[] $options
  *
  * @return \Generator
  *
  * @resolve \Icicle\Http\Message\Response
  */
 public function send(Request $request, array $options = []) : \Generator
 {
     $timeout = isset($options['timeout']) ? (double) $options['timeout'] : self::DEFAULT_TIMEOUT;
     $cryptoMethod = isset($options['crypto_method']) ? (int) $options['crypto_method'] : self::DEFAULT_CRYPTO_METHOD;
     $request = $request->withHeader('Connection', 'close');
     $count = 0;
     try {
         do {
             $uri = $request->getUri();
             $host = $uri->getHost();
             $port = $uri->getPort();
             if ('' === $host || 0 === $port) {
                 throw new InvalidArgumentError('Request URI must have a host and port.');
             }
             /** @var \Icicle\Socket\Socket $socket */
             $socket = (yield from Dns\connect($uri->getHost(), $uri->getPort(), $options));
             if ($uri->getScheme() === 'https') {
                 yield from $socket->enableCrypto($cryptoMethod, $timeout);
             }
             /** @var \Icicle\Http\Message\Response $response */
             $response = (yield from $this->requester->send($socket, $request, $options));
             if ($this->follow) {
                 switch ($response->getStatusCode()) {
                     case Response::SEE_OTHER:
                         $request = $request->withMethod($request->getMethod() === 'HEAD' ? 'HEAD' : 'GET');
                         // No break.
                     // No break.
                     case Response::MOVED_PERMANENTLY:
                     case Response::FOUND:
                     case Response::TEMPORARY_REDIRECT:
                     case Response::PERMANENT_REDIRECT:
                         $socket->close();
                         // Close original connection.
                         if (++$count > $this->maxRedirects) {
                             throw new RedirectException(sprintf('Too many redirects encountered (max redirects: %d).', $this->maxRedirects));
                         }
                         if (!$response->hasHeader('Location')) {
                             throw new RedirectException('No Location header found in redirect response.');
                         }
                         $request = $request->withUri(new BasicUri($response->getHeader('Location')));
                         $response = null;
                         // Let's go around again!
                 }
             }
         } while (null === $response);
     } finally {
         $request->getBody()->close();
     }
     return $response;
 }