Here's a self-contained, minimal, reproducible, example with my use case:
from fastapi import FastAPI
app = FastAPI()
@app.get("/hello/x")
def read_root():
return {"Hello": "World"}
curl http://localhost:8000/hello/x --> is OK
curl http://localhost:8000///hello///x --> throws 404
I handled it using the following redirect middleware. Is there any downside to this?
import re
from starlette.datastructures import URL
from starlette.responses import RedirectResponse
from starlette.types import ASGIApp, Receive, Scope, Send
repeated_quotes = re.compile(r'//+')
class HttpUrlRedirectMiddleware:
"""
This http middleware redirects urls with repeated slashes to the cleaned up
versions of the urls
"""
def __init__(self, app: ASGIApp) -> None:
self.app = app
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
if scope["type"] == "http" and repeated_quotes.search(URL(scope=scope).path):
url = URL(scope=scope)
url = url.replace(path=repeated_quotes.sub('/', url.path))
response = RedirectResponse(url, status_code=307)
await response(scope, receive, send)
else:
await self.app(scope, receive, send)
@mehmetg commented on Sep 25, 2020, 11:36 PM GMT+3:30:
I handled it using the following redirect middleware. Is there any downside to this?
import re from starlette.datastructures import URL from starlette.responses import RedirectResponse from starlette.types import ASGIApp, Receive, Scope, Send repeated_quotes = re.compile(r'//+') class HttpUrlRedirectMiddleware: """ This http middleware redirects urls with repeated slashes to the cleaned up versions of the urls """ def __init__(self, app: ASGIApp) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] == "http" and repeated_quotes.search(URL(scope=scope).path): url = URL(scope=scope) url = url.replace(path=repeated_quotes.sub('/', url.path)) response = RedirectResponse(url, status_code=307) await response(scope, receive, send) else: await self.app(scope, receive, send)
How do you add this middleware to fastapi?
@NightMachinary
from fastapi import FastAPI
from someplace import HttpUrlRedirectMiddleware
app = FastAPI()
app.add_middleware(HttpUrlRedirectMiddleware)
I assume this is an acceptable way to handle this as there were no objections. I have been using it in production and have not received any complaints.
Closing.
Most helpful comment
@NightMachinary