fix(api): accept slashless api urls
This commit is contained in:
@@ -9,6 +9,7 @@ import threading
|
||||
import uuid
|
||||
|
||||
from django.middleware.csrf import CsrfViewMiddleware
|
||||
from django.urls import Resolver404, resolve
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -28,6 +29,34 @@ class ApiCsrfExemptMiddleware(CsrfViewMiddleware):
|
||||
return super().process_view(request, callback, callback_args, callback_kwargs)
|
||||
|
||||
|
||||
class ApiSlashlessRouteMiddleware(MiddlewareMixin):
|
||||
"""Route slashless API URLs to existing slash URLs without POST redirects."""
|
||||
|
||||
api_prefixes = ("/api/",)
|
||||
|
||||
def process_request(self, request):
|
||||
path_info = request.path_info
|
||||
if not path_info.startswith(self.api_prefixes) or path_info.endswith("/"):
|
||||
return None
|
||||
|
||||
try:
|
||||
resolve(path_info)
|
||||
return None
|
||||
except Resolver404:
|
||||
pass
|
||||
|
||||
slash_path_info = f"{path_info}/"
|
||||
try:
|
||||
resolve(slash_path_info)
|
||||
except Resolver404:
|
||||
return None
|
||||
|
||||
request.path_info = slash_path_info
|
||||
request.path = f"{request.path}/"
|
||||
request.META["PATH_INFO"] = slash_path_info
|
||||
return None
|
||||
|
||||
|
||||
def get_request_id() -> str | None:
|
||||
"""Get current request ID from thread-local storage."""
|
||||
return getattr(_request_context, "request_id", None)
|
||||
|
||||
@@ -166,6 +166,7 @@ MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"whitenoise.middleware.WhiteNoiseMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"apps.core.middleware.ApiSlashlessRouteMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"apps.core.middleware.ApiCsrfExemptMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
|
||||
Reference in New Issue
Block a user