diff --git a/fastapi/applications.py b/fastapi/applications.py index d6148b9d5..f44f52ed3 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -979,15 +979,18 @@ class FastAPI(Starlette): if ignore_trailing_slash: - def ignore_trailing_whitespace_middleware(app): - async def ignore_trailing_whitespace_wrapper(scope, receive, send): + class _IgnoreTrailingWhitespaceMiddleware: + def __init__(self, app: ASGIApp): + self.app = app + + async def __call__( + self, scope: Scope, receive: Receive, send: Send + ) -> None: if scope["type"] in {"http", "websocket"}: scope["path"] = scope["path"].rstrip("/") - await app(scope, receive, send) - - return ignore_trailing_whitespace_wrapper + await self.app(scope, receive, send) - self.add_middleware(ignore_trailing_whitespace_middleware) + self.add_middleware(_IgnoreTrailingWhitespaceMiddleware) self.setup() diff --git a/fastapi/routing.py b/fastapi/routing.py index 0935a29f2..b06704574 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -1293,10 +1293,10 @@ class APIRouter(routing.Router): if responses is None: responses = {} for route in router.routes: - path = route.path - if self.ignore_trailing_slash: - path = path.rstrip("/") if isinstance(route, APIRoute): + path = route.path + if self.ignore_trailing_slash: + path = path.rstrip("/") combined_responses = {**responses, **route.responses} use_response_class = get_value_or_default( route.response_class, @@ -1356,6 +1356,9 @@ class APIRouter(routing.Router): generate_unique_id_function=current_generate_unique_id, ) elif isinstance(route, routing.Route): + path = route.path + if self.ignore_trailing_slash: + path = path.rstrip("/") methods = list(route.methods or []) self.add_route( prefix + path, @@ -1365,6 +1368,9 @@ class APIRouter(routing.Router): name=route.name, ) elif isinstance(route, APIWebSocketRoute): + path = route.path + if self.ignore_trailing_slash: + path = path.rstrip("/") current_dependencies = [] if dependencies: current_dependencies.extend(dependencies) @@ -1377,6 +1383,9 @@ class APIRouter(routing.Router): name=route.name, ) elif isinstance(route, routing.WebSocketRoute): + path = route.path + if self.ignore_trailing_slash: + path = path.rstrip("/") self.add_websocket_route(prefix + path, route.endpoint, name=route.name) for handler in router.on_startup: self.add_event_handler("startup", handler)