Keep /media/ reachable during maintenance, so the club logo still loads

The maintenance page is deliberately rendered through the club's own
skin so it can show the club's logo -- but MaintenanceMiddleware closed
every path on a club subdomain unconditionally, including /media/. The
logo's <img> then pointed at a URL that itself returned the maintenance
page (503, text/html) instead of the image, so it rendered as broken.

/media/ moves into ALWAYS_OPEN, checked before the club-vs-platform
branch, so it now stays reachable on every host during a lock-down --
matching what OPEN_PREFIXES already granted the base domain, just never
extended to a club subdomain.
This commit is contained in:
2026-07-27 11:56:10 +02:00
parent febde41214
commit 5bea8a4a6c
2 changed files with 15 additions and 4 deletions

View File

@@ -22,13 +22,15 @@ OPEN_PREFIXES = (
"/accounts/", # ...which you cannot reach without signing in
"/admin/",
"/static/",
"/media/",
"/__reload__/", # dev only; absent outside DEBUG
)
#: Reachable on every host, always. The health check must answer or the load balancer will
#: take the node out of rotation and the control panel with it.
ALWAYS_OPEN = ("/healthz",)
#: take the node out of rotation and the control panel with it. /media/ has to stay open too:
#: the club maintenance page is rendered through the tenant's own skin specifically so it can
#: show the club's logo, and that logo is itself a /media/ file — closing it outright would
#: serve the maintenance page over the top of its own image.
ALWAYS_OPEN = ("/healthz", "/media/")
RETRY_AFTER_SECONDS = 3600
@@ -57,7 +59,8 @@ class MaintenanceMiddleware:
if not Maintenance.is_on():
return False
# A club subdomain is closed outright — no login, no shop, nothing.
# A club subdomain is closed outright — no login, no shop, nothing (besides the
# /media/ exemption above, which its own maintenance page needs to render).
if getattr(request, "club", None) is not None:
return True

View File

@@ -151,6 +151,14 @@ class MaintenanceModeTests(TestCase):
self.assertEqual(self.platform_get("/accounts/login/").status_code, 200)
def test_the_club_logo_still_loads_on_the_maintenance_page(self):
# The maintenance page is rendered through the club's own skin specifically to show
# its logo -- closing /media/ on the club subdomain too would serve the maintenance
# page itself in place of that logo, making it look like the logo vanished.
Maintenance.start()
self.assertEqual(self.club_get("/media/clubs/ajax-united/crest.png").status_code, 404)
def test_the_health_check_still_answers(self):
# Close it and the load balancer decides the node is dead and stops routing to it —
# taking the control panel down with everything else.