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()));
}