fix(discord-bridge): dashboard-ul ramanea gol la /claude — lipsea <base href>
Simptom: pagina se incarca prin tailscale, dar niciun API nu era cerut; in dashboard.log se vedea doar GET / si nimic altceva. Cauza: --set-path taie prefixul, deci /claude si /claude/ ajung la server identic, ca "/". Fara slash final, URL-urile relative se rezolvau la radacina hostului (https://host/api/status), unde proxy-ul nu trimite nimic incoace. Cererile nici nu ajungeau la noi, iar pagina ramanea goala fara nicio eroare. Redirectul 301 adaugat anterior nu putea ajuta: serverul nu vede forma originala a adresei. Paginile se servesc acum printr-un handler propriu care pune <base href> din DASHBOARD_PREFIX, plus Cache-Control: no-store, fiindca HTML-ul poarta de acum configuratie si o copie veche ar trimite cererile aiurea. Patru teste noi. Verificat in browser pe cazul reprodus (pagina servita pe radacina, ca prin proxy): toate cererile pleaca cu /claude/ si datele se incarca. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
This commit is contained in:
@@ -426,9 +426,43 @@ class Handler(SimpleHTTPRequestHandler):
|
||||
self.send_header("Content-Length", "0")
|
||||
self.end_headers()
|
||||
return
|
||||
self.path = "/index.html" if path == "/" else path
|
||||
if path in ("/", "/index.html"):
|
||||
return self.send_html("index.html")
|
||||
if path == "/login.html":
|
||||
return self.send_html("login.html")
|
||||
self.path = path
|
||||
return super().do_GET()
|
||||
|
||||
def send_html(self, name: str):
|
||||
"""Trimite o pagina, cu `<base href>` pus la servire.
|
||||
|
||||
De ce e nevoie: `tailscale serve --set-path /claude` TAIE prefixul, deci
|
||||
serverul nu poate sti daca browserul e la `/claude` sau la `/claude/` —
|
||||
ambele ajung aici ca `/`. Fara slash final, un URL relativ (`api/status`)
|
||||
se rezolva la radacina hostului, unde proxy-ul nu mai trimite nimic
|
||||
incoace: pagina se incarca si ramane goala, fara nicio eroare vizibila.
|
||||
`<base href="/claude/">` fixeaza rezolvarea indiferent de forma adresei.
|
||||
"""
|
||||
try:
|
||||
body = (_DASH / name).read_text(encoding="utf-8")
|
||||
except OSError:
|
||||
return self.send_error(404)
|
||||
pfx = mount_prefix()
|
||||
if pfx:
|
||||
body = body.replace("<head>", f'<head>\n<base href="{pfx}/">', 1)
|
||||
data = body.encode("utf-8")
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "text/html; charset=utf-8")
|
||||
self.send_header("Content-Length", str(len(data)))
|
||||
# no-store: paginile poarta acum si configuratia (base href), deci o
|
||||
# copie veche din cache ar trimite cererile in alta parte.
|
||||
self.send_header("Cache-Control", "no-store")
|
||||
self.end_headers()
|
||||
try:
|
||||
self.wfile.write(data)
|
||||
except (BrokenPipeError, ConnectionResetError):
|
||||
pass
|
||||
|
||||
def route_get(self, path: str):
|
||||
qs = parse_qs(urlparse(self.path).query)
|
||||
if path == "/api/status":
|
||||
|
||||
@@ -381,3 +381,29 @@ def test_static_servit_si_sub_prefix(server_cu_prefix):
|
||||
server_cu_prefix.login()
|
||||
status, data, _ = server_cu_prefix.call("/claude/static/app.css")
|
||||
assert status == 200 and ".card" in data["_html"]
|
||||
|
||||
|
||||
def test_base_href_pus_cand_exista_prefix(server_cu_prefix):
|
||||
"""Proxy-ul taie prefixul, deci serverul nu poate sti daca browserul e la
|
||||
`/claude` sau `/claude/`. `<base href>` face rezolvarea determinista."""
|
||||
server_cu_prefix.login()
|
||||
_, data, _ = server_cu_prefix.call("/")
|
||||
assert '<base href="/claude/">' in data["_html"]
|
||||
|
||||
|
||||
def test_base_href_si_pe_pagina_de_login(server_cu_prefix):
|
||||
_, data, _ = server_cu_prefix.call("/login.html")
|
||||
assert '<base href="/claude/">' in data["_html"]
|
||||
|
||||
|
||||
def test_fara_prefix_nu_se_pune_base(server):
|
||||
server.login()
|
||||
_, data, _ = server.call("/")
|
||||
assert "<base" not in data["_html"]
|
||||
|
||||
|
||||
def test_paginile_nu_se_pun_in_cache(server_cu_prefix):
|
||||
"""O copie veche ar purta un `base href` gresit si ar trimite cererile aiurea."""
|
||||
server_cu_prefix.login()
|
||||
_, _, resp = server_cu_prefix.call("/")
|
||||
assert resp.headers.get("Cache-Control") == "no-store"
|
||||
|
||||
Reference in New Issue
Block a user