a8e29d0305
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
88 lines
2.6 KiB
PHP
88 lines
2.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace KTXC\Runtime\Http;
|
|
|
|
use KTXC\Application\Execution\ExecutionDescriptor;
|
|
use KTXC\Http\Middleware\AuthenticationMiddleware;
|
|
use KTXC\Http\Middleware\FirewallMiddleware;
|
|
use KTXC\Http\Middleware\MiddlewarePipeline;
|
|
use KTXC\Http\Middleware\RouterMiddleware;
|
|
use KTXC\Http\Middleware\TenantMiddleware;
|
|
use KTXC\Http\Request\Request;
|
|
use KTXC\Http\Request\RequestContext;
|
|
use KTXC\Http\Response\Response;
|
|
use KTXC\KernelInterface;
|
|
|
|
final class HttpRuntime
|
|
{
|
|
public function __construct(
|
|
private readonly KernelInterface $kernel,
|
|
private readonly bool $debug,
|
|
) {
|
|
}
|
|
|
|
public function run(?Request $request = null, bool $send = true): Response
|
|
{
|
|
$request ??= Request::createFromGlobals();
|
|
$requestContext = null;
|
|
|
|
try {
|
|
return $this->kernel->executionRunner()->execute(
|
|
ExecutionDescriptor::http(),
|
|
function () use ($request, $send, &$requestContext): Response {
|
|
$requestContext = $this->kernel->container()->get(RequestContext::class);
|
|
$requestContext->initialize($request);
|
|
|
|
$response = $this->pipeline()->handle($request);
|
|
if ($send) {
|
|
$response->send();
|
|
}
|
|
|
|
return $response;
|
|
},
|
|
function (\Throwable $error) use ($send): Response {
|
|
$response = $this->errorResponse($error);
|
|
if ($send) {
|
|
$response->send();
|
|
}
|
|
|
|
return $response;
|
|
},
|
|
);
|
|
} finally {
|
|
$requestContext?->clear();
|
|
}
|
|
}
|
|
|
|
private function pipeline(): MiddlewarePipeline
|
|
{
|
|
$pipeline = new MiddlewarePipeline($this->kernel->container());
|
|
$pipeline->pipe(TenantMiddleware::class);
|
|
$pipeline->pipe(FirewallMiddleware::class);
|
|
$pipeline->pipe(AuthenticationMiddleware::class);
|
|
$pipeline->pipe(RouterMiddleware::class);
|
|
|
|
return $pipeline;
|
|
}
|
|
|
|
private function errorResponse(\Throwable $error): Response
|
|
{
|
|
error_log(sprintf(
|
|
'Application error: %s in %s:%d',
|
|
$error->getMessage(),
|
|
$error->getFile(),
|
|
$error->getLine(),
|
|
));
|
|
|
|
$content = $this->debug
|
|
? '<pre>' . htmlspecialchars((string) $error) . '</pre>'
|
|
: 'An error occurred. Please try again later.';
|
|
|
|
return new Response($content, Response::HTTP_INTERNAL_SERVER_ERROR, [
|
|
'Content-Type' => 'text/html; charset=UTF-8',
|
|
]);
|
|
}
|
|
}
|