container->has(EventDispatcherInterface::class)) { $this->event = $this->container->get(EventDispatcherInterface::class); } } public function initCoreMiddleware(string $serverName): void { $this->serverName = $serverName; $this->coreMiddleware = $this->createCoreMiddleware(); $config = $this->container->get(ConfigInterface::class); $this->middlewares = $config->get('middlewares.' . $serverName, []); $this->exceptionHandlers = $config->get('exceptions.handler.' . $serverName, $this->getDefaultExceptionHandler()); $this->initOption(); } public function onRequest($request, $response): void { try { CoordinatorManager::until(Constants::WORKER_START)->yield(); [$psr7Request, $psr7Response] = $this->initRequestAndResponse($request, $response); $psr7Request = $this->coreMiddleware->dispatch($psr7Request); $this->option?->isEnableRequestLifecycle() && $this->event?->dispatch(new RequestReceived( request: $psr7Request, response: $psr7Response, server: $this->serverName )); /** @var Dispatched $dispatched */ $dispatched = $psr7Request->getAttribute(Dispatched::class); $middlewares = $this->middlewares; $registeredMiddlewares = []; if ($dispatched->isFound()) { $registeredMiddlewares = MiddlewareManager::get($this->serverName, $dispatched->handler->route, $psr7Request->getMethod()); $middlewares = array_merge($middlewares, $registeredMiddlewares); } if ($this->option?->isMustSortMiddlewares() || $registeredMiddlewares) { $middlewares = MiddlewareManager::sortMiddlewares($middlewares); } $psr7Response = $this->dispatcher->dispatch($psr7Request, $middlewares, $this->coreMiddleware); } catch (Throwable $throwable) { // Delegate the exception to exception handler. $psr7Response = $this->container->get(SafeCaller::class)->call(function () use ($throwable) { return $this->exceptionHandlerDispatcher->dispatch($throwable, $this->exceptionHandlers); }, static function () { return (new Psr7Response())->withStatus(400); }); } finally { if (isset($psr7Request) && $this->option?->isEnableRequestLifecycle()) { defer(fn () => $this->event?->dispatch(new RequestTerminated( request: $psr7Request, response: $psr7Response ?? null, exception: $throwable ?? null, server: $this->serverName ))); $this->event?->dispatch(new RequestHandled( request: $psr7Request, response: $psr7Response ?? null, exception: $throwable ?? null, server: $this->serverName )); } // Send the Response to client. if (! isset($psr7Response) || ! $psr7Response instanceof ResponseInterface) { return; } if (isset($psr7Request) && $psr7Request->getMethod() === 'HEAD') { $this->responseEmitter->emit($psr7Response, $response, false); } else { $this->responseEmitter->emit($psr7Response, $response); } } } public function getServerName(): string { return $this->serverName; } /** * @return $this */ public function setServerName(string $serverName) { $this->serverName = $serverName; return $this; } protected function initOption(): void { $ports = $this->container->get(ServerFactory::class)->getConfig()?->getServers(); if (! $ports) { return; } foreach ($ports as $port) { if ($port->getName() === $this->serverName) { $this->option = $port->getOptions(); } } $this->option ??= Option::make([]); $this->option->setMustSortMiddlewaresByMiddlewares($this->middlewares); } protected function createDispatcher(string $serverName): Dispatcher { $factory = $this->container->get(DispatcherFactory::class); return $factory->getDispatcher($serverName); } protected function getDefaultExceptionHandler(): array { return [ HttpExceptionHandler::class, ]; } protected function createCoreMiddleware(): CoreMiddlewareInterface { return make(CoreMiddleware::class, [$this->container, $this->serverName]); } /** * Initialize PSR-7 Request and Response objects. * @param mixed $request swoole request or psr server request * @param mixed $response swoole response or swow connection */ protected function initRequestAndResponse($request, $response): array { ResponseContext::set($psr7Response = new Psr7Response()); $psr7Response->setConnection(new WritableConnection($response)); if ($request instanceof ServerRequestInterface) { $psr7Request = $request; } else { $psr7Request = Psr7Request::loadFromSwooleRequest($request); } RequestContext::set($psr7Request); return [$psr7Request, $psr7Response]; } }