fix: correct force script name?
This commit is contained in:
parent
bf65dc8be0
commit
03f1e8ea16
29
highscore/app/middleware.py
Normal file
29
highscore/app/middleware.py
Normal file
@ -0,0 +1,29 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
|
||||
class ScriptPrefixPathMiddleware:
|
||||
"""Re-add the ``FORCE_SCRIPT_NAME`` prefix to ``request.path`` under ASGI.
|
||||
|
||||
Django's ASGI handler sets ``request.path = scope["path"]`` verbatim (see
|
||||
``django/core/handlers/asgi.py``). When the reverse proxy strips the
|
||||
script-name prefix (e.g. ``/scores``) before forwarding, ``request.path`` —
|
||||
and therefore ``get_full_path()`` — loses the prefix, even though
|
||||
``reverse()`` still prepends it via the script prefix. The result is the
|
||||
admin login form posting to ``/admin/login/?next=/admin/`` instead of
|
||||
``/scores/admin/login/?next=/scores/admin/``.
|
||||
|
||||
URL resolution is unaffected (it uses ``path_info``), so we only need to
|
||||
realign the path-based URLs with the reverse()-based ones. The check is
|
||||
idempotent: if the proxy already forwards the prefix, this is a no-op.
|
||||
"""
|
||||
|
||||
def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]) -> None:
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request: HttpRequest) -> HttpResponse:
|
||||
script_name = request.META.get("SCRIPT_NAME", "").rstrip("/")
|
||||
if script_name and not request.path.startswith(f"{script_name}/"):
|
||||
request.path = f"{script_name}{request.path}"
|
||||
return self.get_response(request)
|
||||
@ -2,23 +2,18 @@ import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from app.config import settings as env
|
||||
|
||||
|
||||
def serve() -> None:
|
||||
"""Start the Daphne ASGI server on 0.0.0.0:8080."""
|
||||
daphne_path = str(Path(sys.path[0]) / "daphne")
|
||||
args = [
|
||||
subprocess.run( # noqa: S603
|
||||
[
|
||||
daphne_path,
|
||||
"-b",
|
||||
"0.0.0.0", # noqa: S104
|
||||
"-p",
|
||||
"8080",
|
||||
]
|
||||
# FORCE_SCRIPT_NAME is a WSGI-only setting; under ASGI Django derives the URL
|
||||
# script prefix from the scope's root_path. Pass the prefix to Daphne so that
|
||||
# reverse()/redirects (e.g. the admin post-login redirect) include it.
|
||||
if env.force_script_name:
|
||||
args += ["--root-path", env.force_script_name.rstrip("/")]
|
||||
args.append("app.routing:application")
|
||||
subprocess.run(args, check=True) # noqa: S603
|
||||
"app.routing:application",
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
|
||||
@ -42,6 +42,7 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
||||
MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"whitenoise.middleware.WhiteNoiseMiddleware",
|
||||
"app.middleware.ScriptPrefixPathMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user