diff --git a/module/Core/src/Action/RedirectMiddleware.php b/module/Core/src/Action/RedirectMiddleware.php index 5b1907ca..1afd2d01 100644 --- a/module/Core/src/Action/RedirectMiddleware.php +++ b/module/Core/src/Action/RedirectMiddleware.php @@ -67,8 +67,8 @@ class RedirectMiddleware implements MiddlewareInterface try { $longUrl = $this->urlShortener->shortCodeToUrl($shortCode); - // If provided shortCode does not belong to a valid long URL, dispatch next middleware, which is 404 - // middleware + // If provided shortCode does not belong to a valid long URL, dispatch next middleware, which will trigger + // a not-found error if (! isset($longUrl)) { return $out($request, $response); } diff --git a/module/Rest/config/middleware-pipeline.config.php b/module/Rest/config/middleware-pipeline.config.php index 4d908635..ba228bf1 100644 --- a/module/Rest/config/middleware-pipeline.config.php +++ b/module/Rest/config/middleware-pipeline.config.php @@ -13,13 +13,12 @@ return [ 'priority' => 5, ], - 'rest-error' => [ + 'rest-not-found' => [ 'path' => '/rest', 'middleware' => [ - Middleware\Error\ResponseTypeMiddleware::class, + Middleware\NotFoundMiddleware::class, ], - 'error' => true, - 'priority' => -10000, + 'priority' => -1, ], ], ]; diff --git a/module/Rest/config/routes.config.php b/module/Rest/config/routes.config.php index 24226840..528e3011 100644 --- a/module/Rest/config/routes.config.php +++ b/module/Rest/config/routes.config.php @@ -23,7 +23,7 @@ return [ 'allowed_methods' => ['GET', 'OPTIONS'], ], [ - 'name' => 'rest-lActionist-shortened-url', + 'name' => 'rest-list-shortened-url', 'path' => '/rest/short-codes', 'middleware' => Action\ListShortcodesMiddleware::class, 'allowed_methods' => ['GET'], diff --git a/module/Rest/config/services.config.php b/module/Rest/config/services.config.php index 44ce97f0..05a1afbe 100644 --- a/module/Rest/config/services.config.php +++ b/module/Rest/config/services.config.php @@ -19,8 +19,8 @@ return [ Middleware\CrossDomainMiddleware::class => InvokableFactory::class, Middleware\CheckAuthenticationMiddleware::class => AnnotatedFactory::class, - - Middleware\Error\ResponseTypeMiddleware::class => AnnotatedFactory::class, + Middleware\ResponseTypeMiddleware::class => AnnotatedFactory::class, + Middleware\NotFoundMiddleware::class => AnnotatedFactory::class, ], ], diff --git a/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php b/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php index f05c1b78..1ad53c4b 100644 --- a/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php +++ b/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php @@ -69,7 +69,9 @@ class CheckAuthenticationMiddleware implements MiddlewareInterface // If current route is the authenticate route or an OPTIONS request, continue to the next middleware /** @var RouteResult $routeResult */ $routeResult = $request->getAttribute(RouteResult::class); - if ((isset($routeResult) && $routeResult->getMatchedRouteName() === 'rest-authenticate') + if (! isset($routeResult) + || $routeResult->isFailure() + || $routeResult->getMatchedRouteName() === 'rest-authenticate' || $request->getMethod() === 'OPTIONS' ) { return $out($request, $response); diff --git a/module/Rest/src/Middleware/NotFoundMiddleware.php b/module/Rest/src/Middleware/NotFoundMiddleware.php new file mode 100644 index 00000000..720f39ca --- /dev/null +++ b/module/Rest/src/Middleware/NotFoundMiddleware.php @@ -0,0 +1,62 @@ +translator = $translator; + } + + /** + * Process an incoming request and/or response. + * + * Accepts a server-side request and a response instance, and does + * something with them. + * + * If the response is not complete and/or further processing would not + * interfere with the work done in the middleware, or if the middleware + * wants to delegate to another process, it can use the `$out` callable + * if present. + * + * If the middleware does not return a value, execution of the current + * request is considered complete, and the response instance provided will + * be considered the response to return. + * + * Alternately, the middleware may return a response instance. + * + * Often, middleware will `return $out();`, with the assumption that a + * later middleware will return a response. + * + * @param Request $request + * @param Response $response + * @param null|callable $out + * @return null|Response + */ + public function __invoke(Request $request, Response $response, callable $out = null) + { + return new JsonResponse([ + 'error' => RestUtils::NOT_FOUND_ERROR, + 'message' => $this->translator->translate('Requested route does not exist.'), + ], 404); + } +} diff --git a/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php b/module/Rest/src/Middleware/ResponseTypeMiddleware.php similarity index 77% rename from module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php rename to module/Rest/src/Middleware/ResponseTypeMiddleware.php index c6319caa..e32bef12 100644 --- a/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php +++ b/module/Rest/src/Middleware/ResponseTypeMiddleware.php @@ -1,15 +1,16 @@ getHeader('Accept'); if (! empty(array_intersect(['application/json', 'text/json', 'application/x-json'], $accept))) { - $status = $this->determineStatus($response); + $status = $this->determineStatus($request, $response); $errorData = $this->determineErrorCode($request, $status); return new JsonResponse($errorData, $status); } - return $out($request, $response, $error); + return $out($request, $response); } /** + * @param Request $request * @param Response $response * @return int */ - protected function determineStatus(Response $response) + protected function determineStatus(Request $request, Response $response) { + /** @var RouteResult $routeResult */ + $routeResult = $request->getAttribute(RouteResult::class); + if ($routeResult->isFailure()) { + return 404; + } + $status = $response->getStatusCode(); return $status >= 400 ? $status : 500; }