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
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from app.config import settings as env
|
|
||||||
|
|
||||||
|
|
||||||
def serve() -> None:
|
def serve() -> None:
|
||||||
"""Start the Daphne ASGI server on 0.0.0.0:8080."""
|
"""Start the Daphne ASGI server on 0.0.0.0:8080."""
|
||||||
daphne_path = str(Path(sys.path[0]) / "daphne")
|
daphne_path = str(Path(sys.path[0]) / "daphne")
|
||||||
args = [
|
subprocess.run( # noqa: S603
|
||||||
daphne_path,
|
[
|
||||||
"-b",
|
daphne_path,
|
||||||
"0.0.0.0", # noqa: S104
|
"-b",
|
||||||
"-p",
|
"0.0.0.0", # noqa: S104
|
||||||
"8080",
|
"-p",
|
||||||
]
|
"8080",
|
||||||
# FORCE_SCRIPT_NAME is a WSGI-only setting; under ASGI Django derives the URL
|
"app.routing:application",
|
||||||
# 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.
|
check=True,
|
||||||
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
|
|
||||||
|
|||||||
@ -42,6 +42,7 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
|||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"whitenoise.middleware.WhiteNoiseMiddleware",
|
"whitenoise.middleware.WhiteNoiseMiddleware",
|
||||||
|
"app.middleware.ScriptPrefixPathMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
"django.middleware.csrf.CsrfViewMiddleware",
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user