You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vibed/pages/.beans/pages-adl9--page-content-se...

28 lines
1.7 KiB
Markdown

---
# 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.