diff --git a/http-handler/Abstracts/Handler.php b/http-handler/Abstracts/Handler.php index 3b93895a..1295a348 100644 --- a/http-handler/Abstracts/Handler.php +++ b/http-handler/Abstracts/Handler.php @@ -3,6 +3,7 @@ namespace Http\Handler\Abstracts; use Http\Handler\Handler as CHl; +use Http\Message\ServerRequest; use Kiri\Core\Help; use Kiri\Kiri; use Psr\Http\Message\ResponseInterface; @@ -35,7 +36,7 @@ abstract class Handler implements RequestHandlerInterface protected function execute(ServerRequestInterface $request): ResponseInterface { if (empty($this->middlewares) || !isset($this->middlewares[$this->offset])) { - return $this->dispatcher(); + return $this->dispatcher($request); } $middleware = $this->middlewares[$this->offset]; @@ -50,10 +51,11 @@ abstract class Handler implements RequestHandlerInterface /** + * @param ServerRequestInterface $request * @return mixed * @throws \Exception */ - protected function dispatcher(): mixed + protected function dispatcher(ServerRequestInterface $request): mixed { if ($this->handler->callback instanceof \Closure) { $response = call_user_func($this->handler->callback, ...$this->handler->params); @@ -67,10 +69,27 @@ abstract class Handler implements RequestHandlerInterface if (!($response instanceof ResponseInterface)) { $response = $this->transferToResponse($response); } + $response->withHeader('Run-Time', $this->_runTime($request)); return $response; } + /** + * @param ServerRequest $request + * @return float + */ + private function _runTime(ServerRequestInterface $request): float + { + $float = microtime(true) - time(); + + $serverParams = $request->getServerParams(); + + $rTime = $serverParams['request_time_float'] - $serverParams['request_time']; + + return round($float - $rTime, 6); + } + + /** * @param mixed $responseData * @return \Server\Constrict\ResponseInterface diff --git a/http-server/Service/Http.php b/http-server/Service/Http.php index 03168423..092a0e92 100644 --- a/http-server/Service/Http.php +++ b/http-server/Service/Http.php @@ -4,12 +4,21 @@ namespace Server\Service; use Exception; +use Http\Context\Context; use Http\Exception\RequestException; +use Http\Handler\Abstracts\HandlerManager; +use Http\Handler\Dispatcher; +use Http\Handler\Handler; use Http\Handler\TestRequest; +use Http\Message\ServerRequest; +use Http\Message\Stream; +use Http\Route\MiddlewareManager; use Http\Route\Node; use Kiri\Core\Help; +use Psr\Http\Message\ServerRequestInterface; use Server\Constant; use Server\Constrict\Request as ScRequest; +use Server\Constrict\RequestInterface; use Server\Constrict\ResponseInterface; use Server\Events\OnAfterRequest; use Server\SInterface\OnClose; @@ -54,40 +63,87 @@ class Http extends \Server\Abstracts\Http implements OnClose, OnConnect */ public function onRequest(Request $request, Response $response): void { - $this->request->onRequest($request, $response); - return; - try { - if (!(($node = $this->router->radix_tree($Psr7Request = ScRequest::create($request))) instanceof Node)) { - throw new RequestException(Constant::STATUS_404_MESSAGE, 404); + [$PsrRequest, $PsrResponse] = $this->initRequestResponse($request); + /** @var Handler $handler */ + $handler = HandlerManager::get($request->server['request_uri'], $request->getMethod()); + if (is_integer($handler)) { + $PsrResponse->withStatus($handler)->withBody(new Stream('Allow Method[' . $request->getMethod() . '].')); + } else if (is_null($handler)) { + $PsrResponse->withStatus(404)->withBody(new Stream('Page not found.')); + } else { + $PsrResponse = $this->handler($handler, $PsrRequest); } - if (!(($psr7Response = $node->dispatch($Psr7Request)) instanceof ResponseInterface)) { - $psr7Response = $this->transferToResponse($psr7Response); - } - $psr7Response->withHeader('Run-Time', $this->_runTime($request)); - } catch (Error | \Throwable $exception) { - $psr7Response = $this->exceptionHandler->emit($exception, $this->response); + } catch (\Throwable $throwable) { + $PsrResponse = \response()->withStatus($throwable->getCode()) + ->withContentType(\Http\Message\Response::CONTENT_TYPE_HTML) + ->withBody(new Stream(jTraceEx($throwable, null, true))); } finally { - $this->responseEmitter->sender($response, $psr7Response); - $this->eventDispatch->dispatch(new OnAfterRequest()); + $this->response->sender($response, $PsrResponse); } } /** - * @param Request $request - * @return float + * @param Handler $handler + * @param $PsrRequest + * @return ResponseInterface + * @throws Exception */ - private function _runTime(Request $request): float + protected function handler(Handler $handler, $PsrRequest): \Psr\Http\Message\ResponseInterface { - $float = microtime(true) - time(); + $middlewares = MiddlewareManager::get($handler->callback); - $rTime = $request->server['request_time_float'] - $request->server['request_time']; + $dispatcher = new Dispatcher($handler, $middlewares); - return round($float - $rTime, 6); + return $dispatcher->handle($PsrRequest); } + /** + * @param Request $request + * @return array + * @throws Exception + */ + private function initRequestResponse(Request $request): array + { + $PsrResponse = Context::setContext(ResponseInterface::class, new \Http\Message\Response()); + + $PsrRequest = Context::setContext(RequestInterface::class, ServerRequest::createServerRequest($request)); + + return [$PsrRequest, $PsrResponse]; + } +// +// +// +// /** +// * @param Request $request +// * @param Response $response +// * @throws Exception +// */ +// public function onRequest(Request $request, Response $response): void +// { +// $this->request->onRequest($request, $response); +// return; +// +// try { +// if (!(($node = $this->router->radix_tree($Psr7Request = ScRequest::create($request))) instanceof Node)) { +// throw new RequestException(Constant::STATUS_404_MESSAGE, 404); +// } +// if (!(($psr7Response = $node->dispatch($Psr7Request)) instanceof ResponseInterface)) { +// $psr7Response = $this->transferToResponse($psr7Response); +// } +// $psr7Response->withHeader('Run-Time', $this->_runTime($request)); +// } catch (Error | \Throwable $exception) { +// $psr7Response = $this->exceptionHandler->emit($exception, $this->response); +// } finally { +// $this->responseEmitter->sender($response, $psr7Response); +// $this->eventDispatch->dispatch(new OnAfterRequest()); +// } +// } + + + /** * @param mixed $responseData * @return ResponseInterface