not bad
This commit is contained in:
parent
e2a60e71a3
commit
003f38ea60
36 changed files with 1543 additions and 1287 deletions
|
|
@ -5,14 +5,16 @@ from __future__ import annotations
|
|||
import json
|
||||
import os
|
||||
from contextlib import asynccontextmanager
|
||||
from html import escape
|
||||
from pathlib import Path
|
||||
from typing import AsyncGenerator
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
|
||||
import structlog
|
||||
from fastapi import FastAPI, HTTPException, Request, Response
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
|
||||
from slowapi import _rate_limit_exceeded_handler
|
||||
from slowapi.errors import RateLimitExceeded
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
|
|
@ -151,7 +153,44 @@ def _mount_static(app: FastAPI, static_dir: Path) -> None:
|
|||
r"[-.][A-Za-z0-9]{8,}\.(?:js|css|woff2?|png|jpe?g|svg|ico|map)$"
|
||||
)
|
||||
|
||||
def _serve_file(file_path: Path) -> FileResponse:
|
||||
def _absolute_meta_urls(request: Request) -> tuple[str, str]:
|
||||
configured_public_url = os.environ.get("LIFE_TOWERS_PUBLIC_URL", "").strip()
|
||||
if configured_public_url:
|
||||
public_root = configured_public_url.rstrip("/") + "/"
|
||||
return public_root, f"{public_root}og-image.png"
|
||||
|
||||
parts = urlsplit(str(request.url))
|
||||
canonical_url = urlunsplit((parts.scheme, parts.netloc, parts.path or "/", "", ""))
|
||||
|
||||
root_path = str(request.scope.get("root_path") or "").strip("/")
|
||||
og_image_path = f"/{root_path}/og-image.png" if root_path else "/og-image.png"
|
||||
og_image_url = urlunsplit((parts.scheme, parts.netloc, og_image_path, "", ""))
|
||||
return canonical_url, og_image_url
|
||||
|
||||
def _serve_index(file_path: Path, request: Request) -> HTMLResponse:
|
||||
canonical_url, og_image_url = _absolute_meta_urls(request)
|
||||
html = file_path.read_text(encoding="utf-8")
|
||||
html = html.replace(
|
||||
'href="/" data-dynamic-url="canonical"',
|
||||
f'href="{escape(canonical_url, quote=True)}" data-dynamic-url="canonical"',
|
||||
)
|
||||
html = html.replace(
|
||||
'content="/" data-dynamic-url="canonical"',
|
||||
f'content="{escape(canonical_url, quote=True)}" data-dynamic-url="canonical"',
|
||||
)
|
||||
html = html.replace(
|
||||
'content="/og-image.png" data-dynamic-url="og-image"',
|
||||
f'content="{escape(og_image_url, quote=True)}" data-dynamic-url="og-image"',
|
||||
)
|
||||
|
||||
resp = HTMLResponse(html)
|
||||
resp.headers["Cache-Control"] = "no-cache"
|
||||
return resp
|
||||
|
||||
def _serve_file(file_path: Path, request: Request) -> Response:
|
||||
if file_path.name == "index.html":
|
||||
return _serve_index(file_path, request)
|
||||
|
||||
resp = FileResponse(str(file_path))
|
||||
if HASHED_PATTERN.search(file_path.name):
|
||||
resp.headers["Cache-Control"] = "public, max-age=31536000, immutable"
|
||||
|
|
@ -160,7 +199,7 @@ def _mount_static(app: FastAPI, static_dir: Path) -> None:
|
|||
return resp
|
||||
|
||||
@app.get("/{full_path:path}", include_in_schema=False)
|
||||
async def spa_fallback(full_path: str) -> Response:
|
||||
async def spa_fallback(request: Request, full_path: str) -> Response:
|
||||
# API routes are handled by the API router (registered before this);
|
||||
# if execution reaches here for an /api/* path, it really is unknown.
|
||||
if full_path.startswith("api/"):
|
||||
|
|
@ -174,12 +213,12 @@ def _mount_static(app: FastAPI, static_dir: Path) -> None:
|
|||
except ValueError:
|
||||
raise HTTPException(status_code=404, detail="Not found")
|
||||
if candidate.is_file():
|
||||
return _serve_file(candidate)
|
||||
return _serve_file(candidate, request)
|
||||
|
||||
# SPA fallback to index.html.
|
||||
index = static_dir / "index.html"
|
||||
if index.is_file():
|
||||
return _serve_file(index)
|
||||
return _serve_file(index, request)
|
||||
|
||||
raise HTTPException(status_code=404, detail="Not found")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue