diff --git a/src/Application.php b/src/Application.php index 066d1839..d84fa83d 100644 --- a/src/Application.php +++ b/src/Application.php @@ -53,7 +53,16 @@ public function __construct( $this->buffer = new Buffer(bufferSize: 10485760, timer: 0.1); $this->container->set($this->buffer); - $inspector = $container->make(Inspector::class, [ + // Frontend + $feConfig = $this->container->get(FrontendConfig::class); + $feSeparated = $withFrontend && !\in_array( + $feConfig->port, + \array_map(static fn(SocketServer $item): ?int => $item->type === 'tcp' ? $item->port : null, $map, ), + true, + ); + $withFrontend and $this->configureFrontend($feSeparated); + + $inspectorWithFrontend = $inspector = $container->make(Inspector::class, [ // new Traffic\Dispatcher\WebSocket(), new Traffic\Dispatcher\VarDumper(), new Traffic\Dispatcher\Http( @@ -71,11 +80,32 @@ public function __construct( ]); $this->processors[] = $inspector; - $withFrontend and $this->configureFrontend(); + if (!$feSeparated) { + $inspectorWithFrontend = $container->make(Inspector::class, [ + new Traffic\Dispatcher\VarDumper(), + new Traffic\Dispatcher\Http( + [ + $this->container->get(Sender\Frontend\Http\Pipeline::class), + $this->container->get(Middleware\Resources::class), + $this->container->get(Middleware\DebugPage::class), + $this->container->get(Middleware\RayRequestDump::class), + $this->container->get(Middleware\SentryTrap::class), + $this->container->get(Middleware\XHProfTrap::class), + ], + [$this->container->get(Sender\Frontend\Http\RequestHandler::class)], + ), + new Traffic\Dispatcher\Smtp(), + new Traffic\Dispatcher\Monolog(), + ]); + $this->processors[] = $inspectorWithFrontend; + } + $this->configureFileObserver(); foreach ($map as $config) { - $this->prepareServerFiber($config, $inspector, $this->logger); + !$feSeparated && $config->type === 'tcp' && $config->port === $feConfig->port + ? $this->prepareServerFiber($config, $inspectorWithFrontend, $this->logger) + : $this->prepareServerFiber($config, $inspector, $this->logger); } } @@ -175,18 +205,22 @@ public function prepareServerFiber(SocketServer $config, Inspector $inspector, L }); } - public function configureFrontend(): void + public function configureFrontend(bool $separated): void { $this->processors[] = $this->senders[] = $wsSender = Sender\FrontendSender::create($this->logger); - $this->container->set($wsSender->getEventStorage(), Sender\Frontend\EventStorage::class); + $this->container->set($wsSender); + $this->container->set($wsSender->getEventStorage()); + $this->container->set($wsSender->getConnectionPool()); + + if (!$separated) { + return; + } // Separated port $inspector = $this->container->make(Inspector::class, [ new Traffic\Dispatcher\Http( - [ - new Sender\Frontend\Http\Pipeline($this->logger, $wsSender), - ], - [new Sender\Frontend\Http\RequestHandler($wsSender->getConnectionPool())], + [$this->container->get(Sender\Frontend\Http\Pipeline::class)], + [$this->container->get(Sender\Frontend\Http\RequestHandler::class)], silentMode: true, ), ]); diff --git a/src/Command/Run.php b/src/Command/Run.php index fa72e9cf..6e18b28c 100644 --- a/src/Command/Run.php +++ b/src/Command/Run.php @@ -32,6 +32,8 @@ final class Run extends Command implements SignalableCommandInterface { private ?Application $app = null; + private Logger $logger; + private bool $cancelled = false; public function configure(): void @@ -129,6 +131,7 @@ protected function execute( InputInterface $input, OutputInterface $output, ): int { + $this->logger = new Logger($output); try { // Print intro $output->writeln(\sprintf('%s v%s', Info::NAME, Info::version())); @@ -147,7 +150,7 @@ protected function execute( )->finish(); $container->set($registry); $container->set($input, InputInterface::class); - $container->set(new Logger($output)); + $container->set($this->logger); $this->app = $container->get(Application::class, [ 'map' => $this->getServers($container), 'senders' => $registry->getSenders($senders), @@ -157,16 +160,9 @@ protected function execute( $this->app->run(); } catch (\Throwable $e) { - if ($output->isVerbose()) { - // Write colorful exception (title, message, stacktrace) - $output->writeln(\sprintf("%s", $e::class)); - } - - $output->writeln(\sprintf("%s", $e->getMessage())); - - if ($output->isDebug()) { - $output->writeln(\sprintf("%s", $e->getTraceAsString())); - } + do { + $this->logger->exception($e); + } while ($e = $e->getPrevious()); } return Command::SUCCESS; diff --git a/src/Handler/Http/Handler/Fallback.php b/src/Handler/Http/Handler/Fallback.php index 2423ac59..0bea1afb 100644 --- a/src/Handler/Http/Handler/Fallback.php +++ b/src/Handler/Http/Handler/Fallback.php @@ -9,6 +9,7 @@ use Buggregator\Trap\Handler\Http\RequestHandler; use Buggregator\Trap\Handler\Pipeline; use Buggregator\Trap\Proto\Frame; +use Buggregator\Trap\Sender\Frontend\Http\Pipeline as FrontendPipeline; use Buggregator\Trap\Traffic\StreamClient; use Nyholm\Psr7\Response; use Psr\Http\Message\ResponseInterface; @@ -81,6 +82,10 @@ public function handle(StreamClient $streamClient, ServerRequestInterface $reque $streamClient->disconnect(); } + if (isset($response) && $response->hasHeader(FrontendPipeline::FRONTEND_HEADER)) { + return; + } + if (!$gotFrame) { yield new Frame\Http( $request, diff --git a/src/Sender/Frontend/Http/Pipeline.php b/src/Sender/Frontend/Http/Pipeline.php index 70e4f036..b714a429 100644 --- a/src/Sender/Frontend/Http/Pipeline.php +++ b/src/Sender/Frontend/Http/Pipeline.php @@ -6,6 +6,7 @@ use Buggregator\Trap\Handler\Http\Middleware; use Buggregator\Trap\Handler\Pipeline as MiddlewaresPipeline; +use Buggregator\Trap\Info; use Buggregator\Trap\Logger; use Nyholm\Psr7\Response; use Psr\Http\Message\ResponseInterface; @@ -19,6 +20,8 @@ */ final class Pipeline implements Middleware { + public const FRONTEND_HEADER = 'X-Trap-Frontend'; + /** @var MiddlewaresPipeline */ private MiddlewaresPipeline $pipeline; @@ -48,6 +51,6 @@ public function handle(ServerRequestInterface $request, callable $next): Respons return $response->getStatusCode() === 404 ? $next($request) - : $response; + : $response->withHeader(self::FRONTEND_HEADER, Info::version()); } } diff --git a/src/Service/Container.php b/src/Service/Container.php index 32acfafb..76fcd90f 100644 --- a/src/Service/Container.php +++ b/src/Service/Container.php @@ -88,7 +88,7 @@ public function make(string $class, array $arguments = []): object try { $result = $this->injector->make($class, \array_merge((array) $binding, $arguments)); } catch (\Throwable $e) { - throw new class("Unable to create object of class $class.", previous: $e, ) extends \RuntimeException implements NotFoundExceptionInterface {}; + throw new class("Unable to create object of class $class.", previous: $e) extends \RuntimeException implements NotFoundExceptionInterface {}; } }