2026-06-05 10:33:47 +02:00
|
|
|
import os
|
|
|
|
|
import re
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
from fastapi import HTTPException
|
|
|
|
|
|
2026-06-08 09:58:52 +02:00
|
|
|
from src.constants import GENERATED_IMAGES_DIR
|
2026-06-05 10:33:47 +02:00
|
|
|
|
2026-06-08 09:58:52 +02:00
|
|
|
|
|
|
|
|
GENERATED_IMAGE_DIR = Path(GENERATED_IMAGES_DIR)
|
2026-06-05 10:33:47 +02:00
|
|
|
GENERATED_IMAGE_RE = re.compile(
|
|
|
|
|
r"^[a-f0-9]{8,64}\.(png|jpg|jpeg|webp|gif|mp4|mov|webm|mkv|m4v)$"
|
|
|
|
|
)
|
|
|
|
|
GENERATED_IMAGE_HEADERS = {
|
|
|
|
|
"Cache-Control": "public, max-age=31536000, immutable",
|
|
|
|
|
"X-Content-Type-Options": "nosniff",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def resolve_generated_image_path(filename: str) -> Path:
|
|
|
|
|
if not isinstance(filename, str) or not GENERATED_IMAGE_RE.fullmatch(filename):
|
|
|
|
|
raise HTTPException(status_code=400, detail="Invalid filename")
|
|
|
|
|
root = GENERATED_IMAGE_DIR.resolve()
|
|
|
|
|
path = (GENERATED_IMAGE_DIR / filename).resolve()
|
|
|
|
|
try:
|
|
|
|
|
if os.path.commonpath([str(root), str(path)]) != str(root):
|
|
|
|
|
raise ValueError
|
|
|
|
|
except Exception:
|
|
|
|
|
raise HTTPException(status_code=400, detail="Invalid filename")
|
|
|
|
|
if not path.exists():
|
|
|
|
|
raise HTTPException(status_code=404, detail="Image not found")
|
|
|
|
|
return path
|