From 3e53d339d42a4b6e1a95335956e6360eabddc395 Mon Sep 17 00:00:00 2001 From: Bastien Philippe Date: Fri, 1 Mar 2024 13:13:49 +0100 Subject: [PATCH] Give more priority for exact path against regex match --- src/Middleware.php | 23 +++++++++++++++++++---- tests/Fixtures/Test.v1.json | 30 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/Middleware.php b/src/Middleware.php index 9e49407..17f6435 100644 --- a/src/Middleware.php +++ b/src/Middleware.php @@ -125,21 +125,36 @@ protected function pathItem(Route $route, string $requestMethod): array $this->version = $openapi->openapi; + $pathMatches = false; + $partialMatch = null; + foreach ($openapi->paths as $path => $pathItem) { $resolvedPath = $this->resolvePath($path); - if (Str::match($route->getCompiled()->getRegex(), $resolvedPath) !== '') { - $methods = array_keys($pathItem->getOperations()); + $methods = array_keys($pathItem->getOperations()); + if ($resolvedPath === $requestPath) { + $pathMatches = true; // Check if the method exists for this path, and if so return the full PathItem if (in_array(strtolower($requestMethod), $methods, true)) { return [$resolvedPath, $pathItem]; } + } - throw new InvalidPathException("[{$requestMethod}] not a valid method for [{$requestPath}].", 405); + if (Str::match($route->getCompiled()->getRegex(), $resolvedPath) !== '') { + $pathMatches = true; + if (in_array(strtolower($requestMethod), $methods, true)) { + $partialMatch = [$resolvedPath, $pathItem]; + } } } - throw new InvalidPathException("Path [{$requestMethod} {$requestPath}] not found in spec.", 404); + if ($partialMatch !== null) { + return $partialMatch; + } + + throw $pathMatches + ? throw new InvalidPathException("[{$requestMethod}] not a valid method for [{$requestPath}].", 405) + : new InvalidPathException("Path [{$requestMethod} {$requestPath}] not found in spec.", 404); } protected function resolvePath(string $path): string diff --git a/tests/Fixtures/Test.v1.json b/tests/Fixtures/Test.v1.json index cc47409..0a6170c 100644 --- a/tests/Fixtures/Test.v1.json +++ b/tests/Fixtures/Test.v1.json @@ -239,6 +239,36 @@ "operationId": "get-users-user" } }, + "/users/me": { + "get": { + "summary": "Get current user", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } + } + }, + "operationId": "get-users-user" + } + }, "/users-by-id/{user}": { "parameters": [ {