Fastapi: How do I handle multiple slashes in the URL path leading, mid-path or trailing, similar to non strict slashes in Flask.

Created on 25 Sep 2020  路  4Comments  路  Source: tiangolo/fastapi

First check

  • [x] I added a very descriptive title to this issue.
  • [x] I used the GitHub search to find a similar issue and didn't find it.
  • [x] I searched the FastAPI documentation, with the integrated search.
  • [x] I already searched in Google "How to X in FastAPI" and didn't find any information.
  • [x] I already read and followed all the tutorial in the docs and didn't find an answer.
  • [x] I already checked if it is not related to FastAPI but to Pydantic.
  • [x] I already checked if it is not related to FastAPI but to Swagger UI.
  • [x] I already checked if it is not related to FastAPI but to ReDoc.
  • [x] After submitting this, I commit to one of:

    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.

    • I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.

    • Implement a Pull Request for a confirmed bug.

Example

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"}

Description

curl http://localhost:8000/hello/x --> is OK
curl http://localhost:8000///hello///x --> throws 404
question

Most helpful comment

@NightMachinary

from fastapi import FastAPI

from someplace import HttpUrlRedirectMiddleware

app = FastAPI()
app.add_middleware(HttpUrlRedirectMiddleware)

All 4 comments

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.

Was this page helpful?
0 / 5 - 0 ratings