--- # pages-adl9 title: Page content serving from R2 status: completed type: feature priority: normal created_at: 2026-07-13T02:09:09Z updated_at: 2026-07-13T17:11:23Z parent: pages-77lk blocked_by: - pages-kns6 --- Implement design doc §4.7. src/routes/serve.rs (wasm-only): GET /:slug -> 301 /:slug/; GET /:slug/ -> R2 slug/index.html; GET /:slug/*path -> R2 slug/path, on miss retry slug/path/index.html, else minimal 404 HTML page. Invalid/reserved slugs 404. Every user-content response gets headers from core::headers: CSP sandbox (no allow-same-origin), X-Content-Type-Options nosniff, Referrer-Policy no-referrer, Cache-Control public max-age=300, Access-Control-Allow-Origin *, Content-Type from core::mime by extension. Route registration must not shadow /, /api, /auth. Path normalization logic (join, index fallback candidates) in core as pure function with native tests. - [x] serve.rs handlers + router wiring (fallback route) - [x] pure path-resolution helper in core + native tests - [x] all §4.7 headers on every response incl. 404s for slugs - [x] full validation suite passes ## Summary of Changes R2 page serving by a Sonnet agent; Opus review APPROVE (no blockers, nits were doc-only and applied). - src/core/serve_path.rs: pure candidate resolver (exact -> dir-index fallback) with traversal/length/shape rejection, 19 native tests. - src/routes/serve.rs: /{slug} 301, /{slug}/ index, /{slug}/{*rest} assets; single apply_user_content_headers choke point puts CSP sandbox, nosniff, no-referrer, cache-control, ACAO * on every 200/301/404/500. - core/headers.rs gained the ACAO constant. Route precedence verified against matchit semantics; reserved slugs are a second 404 layer. 142 unit tests + 17 doctests green.