fix(web): serve /images/<path> from disk so thumbnails+originals render instead of grey placeholders
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+24
-2
@@ -1,14 +1,36 @@
|
|||||||
"""Serves the built Vue SPA from frontend/dist/ with history-mode fallback."""
|
"""Serves the built Vue SPA from frontend/dist/ with history-mode fallback,
|
||||||
|
and the on-disk image library + thumbnails from /images.
|
||||||
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from quart import Blueprint, send_from_directory
|
from quart import Blueprint, abort, send_from_directory
|
||||||
|
|
||||||
FRONTEND_DIST = Path(__file__).resolve().parent.parent.parent / "frontend" / "dist"
|
FRONTEND_DIST = Path(__file__).resolve().parent.parent.parent / "frontend" / "dist"
|
||||||
|
IMAGES_ROOT = Path("/images")
|
||||||
|
|
||||||
frontend_bp = Blueprint("frontend", __name__)
|
frontend_bp = Blueprint("frontend", __name__)
|
||||||
|
|
||||||
|
|
||||||
|
@frontend_bp.route("/images/<path:subpath>")
|
||||||
|
async def serve_image(subpath: str):
|
||||||
|
"""Serve a file from the /images volume (originals + thumbnails).
|
||||||
|
|
||||||
|
Without this route the SPA catch-all below would swallow image
|
||||||
|
requests and return index.html, leaving the browser to render the
|
||||||
|
aspect-ratio-shaped grey placeholder.
|
||||||
|
"""
|
||||||
|
target = (IMAGES_ROOT / subpath).resolve()
|
||||||
|
# Defend against path-traversal: refuse anything that escapes /images.
|
||||||
|
try:
|
||||||
|
target.relative_to(IMAGES_ROOT)
|
||||||
|
except ValueError:
|
||||||
|
abort(404)
|
||||||
|
if not target.is_file():
|
||||||
|
abort(404)
|
||||||
|
return await send_from_directory(IMAGES_ROOT, subpath)
|
||||||
|
|
||||||
|
|
||||||
@frontend_bp.route("/")
|
@frontend_bp.route("/")
|
||||||
@frontend_bp.route("/<path:subpath>")
|
@frontend_bp.route("/<path:subpath>")
|
||||||
async def serve_spa(subpath: str = ""):
|
async def serve_spa(subpath: str = ""):
|
||||||
|
|||||||
Reference in New Issue
Block a user