Example #1
0
 /**
  * @coroutine
  *
  * @param \Icicle\Socket\Socket $socket
  * @param \Icicle\Http\Message\Request $request
  * @param mixed[] $options
  *
  * @return \Generator
  *
  * @resolve \Icicle\Http\Message\Response
  */
 public function send(Socket $socket, Request $request, array $options = []) : \Generator
 {
     $timeout = isset($options['timeout']) ? (double) $options['timeout'] : self::DEFAULT_TIMEOUT;
     $allowPersistent = isset($options['allow_persistent']) ? (bool) $options['allow_persistent'] : true;
     $request = (yield from $this->driver->buildRequest($request, $timeout, $allowPersistent));
     yield from $this->driver->writeRequest($socket, $request, $timeout);
     return yield from $this->driver->readResponse($socket, $timeout);
 }
Example #2
0
 /**
  * @param \Icicle\Socket\Socket $socket
  * @param int $cryptoMethod
  * @param float|int $timeout
  * @param bool $allowPersistent
  *
  * @return \Generator
  *
  * @resolve null
  */
 private function process(Socket $socket, int $cryptoMethod, float $timeout, bool $allowPersistent) : \Generator
 {
     $count = 0;
     assert(yield from $this->log->log(Log::DEBUG, 'Accepted client from %s:%d on %s:%d', $socket->getRemoteAddress(), $socket->getRemotePort(), $socket->getLocalAddress(), $socket->getLocalPort()));
     try {
         if (0 !== $cryptoMethod) {
             yield from $socket->enableCrypto($cryptoMethod, $timeout);
         }
         do {
             $request = null;
             try {
                 /** @var \Icicle\Http\Message\Request $request */
                 $request = (yield from $this->driver->readRequest($socket, $timeout));
                 ++$count;
                 /** @var \Icicle\Http\Message\Response $response */
                 $response = (yield from $this->createResponse($request, $socket));
                 assert(yield from $this->log->log(Log::DEBUG, 'Responded to request from %s:%d for %s with %d %s', $socket->getRemoteAddress(), $socket->getRemotePort(), $request->getUri(), $response->getStatusCode(), $response->getReasonPhrase()));
             } catch (TimeoutException $exception) {
                 // Request timeout.
                 if (0 < $count) {
                     assert(yield from $this->log->log(Log::DEBUG, 'Keep-alive timeout from %s:%d on %s:%d', $socket->getRemoteAddress(), $socket->getRemotePort(), $socket->getLocalAddress(), $socket->getLocalPort()));
                     return;
                     // Keep-alive timeout expired.
                 }
                 $response = (yield from $this->createErrorResponse(Response::REQUEST_TIMEOUT, $socket));
             } catch (MessageException $exception) {
                 // Bad request.
                 $response = (yield from $this->createErrorResponse($exception->getCode(), $socket));
             } catch (InvalidValueException $exception) {
                 // Invalid value in message header.
                 $response = (yield from $this->createErrorResponse(Response::BAD_REQUEST, $socket));
             } catch (ParseException $exception) {
                 // Parse error in request.
                 $response = (yield from $this->createErrorResponse(Response::BAD_REQUEST, $socket));
             }
             $response = (yield from $this->driver->buildResponse($response, $request, $timeout, $allowPersistent));
             try {
                 yield from $this->driver->writeResponse($socket, $response, $request, $timeout);
             } finally {
                 $response->getBody()->close();
             }
         } while (strtolower($response->getHeader('Connection')) === 'keep-alive');
     } catch (Throwable $exception) {
         yield from $this->log->log(Log::NOTICE, "Error when handling request from %s:%d: %s", $socket->getRemoteAddress(), $socket->getRemotePort(), $exception->getMessage());
     } finally {
         $socket->close();
     }
     assert(yield from $this->log->log(Log::DEBUG, 'Disconnected client from %s:%d on %s:%d', $socket->getRemoteAddress(), $socket->getRemotePort(), $socket->getLocalAddress(), $socket->getLocalPort()));
 }