Skip to content

Commit b90be92

Browse files
committed
Fix BaseHTTPMiddleware, which has a known bug in newer Starlette versions. Make proper ASGI middleware class
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
1 parent 27d90fb commit b90be92

1 file changed

Lines changed: 33 additions & 16 deletions

File tree

api/main.py

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,19 +2345,36 @@ def traceback_exception_handler(request: Request, exc: Exception):
23452345
)
23462346

23472347

2348-
@versioned_app.middleware("http")
2349-
async def redirect_http_requests(request: Request, call_next):
2350-
"""Redirect request with version prefix when no version is provided"""
2351-
response = None
2352-
path = request.scope["path"]
2353-
match = re.match(r"^/(v[\d.]+)", path)
2354-
if match:
2355-
prefix = match.group(1)
2356-
if prefix not in API_VERSIONS:
2357-
response = PlainTextResponse(
2358-
f"Unsupported API version: {prefix}",
2359-
status_code=status.HTTP_400_BAD_REQUEST,
2360-
)
2361-
elif not path.startswith("/latest"):
2362-
request.scope["path"] = "/latest" + path
2363-
return response or await call_next(request)
2348+
class VersionRedirectMiddleware:
2349+
"""Pure ASGI middleware to redirect requests with version prefix.
2350+
2351+
Avoids BaseHTTPMiddleware which can corrupt the request scope
2352+
(fastapi_inner_astack not found in request scope).
2353+
"""
2354+
2355+
def __init__(self, app):
2356+
self.app = app
2357+
2358+
async def __call__(self, scope, receive, send):
2359+
if scope["type"] != "http":
2360+
await self.app(scope, receive, send)
2361+
return
2362+
2363+
path = scope["path"]
2364+
match = re.match(r"^/(v[\d.]+)", path)
2365+
if match:
2366+
prefix = match.group(1)
2367+
if prefix not in API_VERSIONS:
2368+
response = PlainTextResponse(
2369+
f"Unsupported API version: {prefix}",
2370+
status_code=status.HTTP_400_BAD_REQUEST,
2371+
)
2372+
await response(scope, receive, send)
2373+
return
2374+
elif not path.startswith("/latest"):
2375+
scope["path"] = "/latest" + path
2376+
2377+
await self.app(scope, receive, send)
2378+
2379+
2380+
versioned_app.add_middleware(VersionRedirectMiddleware)

0 commit comments

Comments
 (0)