diff --git a/src/Response/HttpResponse.php b/src/Response/HttpResponse.php new file mode 100644 index 0000000..b6393cd --- /dev/null +++ b/src/Response/HttpResponse.php @@ -0,0 +1,109 @@ +request = $request; + $this->routeCollection = $routeCollection; + $this->appConfig = $appConfig; + $this->method = strtolower($requestMethod); + $this->parsedUrl = parse_url($requestUrl); + $this->rawUrl = $requestUrl; + } + + public function render(): void + { + $match = $this->routeCollection->match($this->method, $this->parsedUrl['path']); + if ($match === null) { + $this->render404(); + return; + } + + list($route, $params) = $match; + $this->request->setParsedRouteParams($params); + $handler = $route->getHandler(); + $controller = new $handler[0]($this->request); + + if ( + $controller instanceof IAuthenticationRequired && + $controller->isAuthenticationRequired() && + $this->request->user() === null + ) { + $this->redirectToLogin(); + return; + } + + if ( + $this->method === 'post' && + !in_array($this->parsedUrl['path'], $this->appConfig['antiCsrfTokenExceptions']) && + $this->request->post($this->appConfig['antiCsrfTokenName']) !== $this->request->session()->get($this->appConfig['antiCsrfTokenName']) + ) { + $this->renderAntiCsrfError(); + return; + } + + if ($controller instanceof ISecured && !$controller->authorize()) { + $this->render404(); + return; + } + + $response = call_user_func([$controller, $handler[1]]); + if ($response instanceof IContent) { + header('Content-Type: ' . $response->getContentType() . '; charset=UTF-8'); + $response->render(); + } elseif ($response instanceof IRedirect) { + header('Location: ' . $response->getUrl(), true, $response->getHttpCode()); + } else { + $this->render404(); + } + } + + private function redirectToLogin(): void + { + $this->request->session()->set('redirect_after_login', $this->rawUrl); + $response = new Redirect($this->routeCollection->getRoute($this->appConfig['loginRouteId'])->generateLink(), IRedirect::TEMPORARY); + header('Location: ' . $response->getUrl(), true, $response->getHttpCode()); + } + + private function renderAntiCsrfError(): void + { + $content = new JsonContent($this->appConfig['antiCsrfTokenErrorResponse']); + header('Content-Type: text/html; charset=UTF-8', true, 403); + $content->render(); + } + + private function render404(): void + { + $content = new HtmlContent($this->appConfig['error404View']); + header('Content-Type: text/html; charset=UTF-8', true, 404); + $content->render(); + } +}