Spaces:
Running
Running
File size: 1,869 Bytes
4d5727a 12a6c9a 4d5727a 12a6c9a 4d5727a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | """
Viewer HTML rendering helpers.
Separated from app.py so the factory stays under 150 lines.
"""
import os
import secrets
import base64
from flask import make_response
def make_viewer_response(base_dir: str):
"""
Read src/viewer/index.html, inject nonce + version + token, set CSP headers.
Returns a Flask Response object ready to send to the client.
Raises an exception if the template file is missing.
"""
template_path = os.path.join(base_dir, "viewer", "index.html")
with open(template_path, "r", encoding="utf-8") as f:
template = f.read()
nonce = base64.urlsafe_b64encode(secrets.token_bytes(16)).decode("utf-8").rstrip("=")
# D2.2: Never embed the raw AGENTCACHE_SECRET in page source.
# Replace the placeholder with an empty string — the viewer authenticates
# via the Authorization header set programmatically after load.
html = (
template
.replace("__AGENTCACHE_VIEWER_NONCE__", nonce)
.replace("__AGENTCACHE_VERSION__", "0.9.8")
.replace("__AGENTCACHE_AUTO_TOKEN__", "")
)
csp = "; ".join([
"default-src 'none'",
"base-uri 'none'",
"frame-ancestors 'self' https://huggingface.co https://*.hf.space",
"object-src 'none'",
"form-action 'none'",
f"script-src 'nonce-{nonce}'",
"script-src-attr 'none'",
"style-src 'unsafe-inline'",
(
"connect-src 'self' https: http://localhost:* http://127.0.0.1:* "
"wss: ws://localhost:* ws://127.0.0.1:* wss://localhost:* wss://127.0.0.1:*"
),
"img-src 'self' data:",
"font-src 'self'",
])
res = make_response(html)
res.headers["Content-Type"] = "text/html; charset=utf-8"
res.headers["Content-Security-Policy"] = csp
res.headers["Cache-Control"] = "no-cache"
return res
|