getProtocolVersion() . ' ' . $response->getStatusCode() . ' ' . $response->getReasonPhrase()); } foreach ($response->getHeaders() as $name => $values) { // Allow replacement for first occurrence of header but afterward do not replace // to allow multiple headers to be sent, e.g. for Set-Cookie headers. $replace = true; foreach ($values as $value) { header($name . ': ' . $value, $replace); $replace = false; } } } $body = $response->getBody(); if ($body instanceof SelfEmittableStreamInterface) { while (ob_get_level()) { ob_end_clean(); } // Optimization for streams that use php functions like readfile() as fastpath for serving files. $body->emit(); } else { echo $body->__toString(); } } public function handle(ServerRequestInterface $request): ResponseInterface { try { $response = $this->requestHandler->handle($request); } catch (ImmediateResponseException $exception) { $response = $exception->getResponse(); } return $response; } /** * Set up the application and shut it down afterwards */ final public function run() { try { $request = ServerRequestFactory::fromGlobals(); } catch (\InvalidArgumentException $e) { $this->logger?->debug('Rejected invalid request: {message}', [ 'message' => $e->getMessage(), 'exception' => $e, ]); $this->sendResponse(new Response(null, 400)); return; } $response = $this->handle($request); $this->sendResponse($response); } }