package web import ( "net/http" "path" "strings" ) // ── the service worker's cache policy (A5, SPEC-009 §6) ────────────────────── // // THE RULE: the service worker may cache STATIC ASSETS — and nothing else. It // must never cache an authenticated response and never a /{GUID} page (A5), so // it does not intercept such a request at all. // // StaticCachePrefixes is the ONE source of truth for "static". The embedded // service worker (static/sw.js) declares the same list; a test asserts the two // agree, so the policy cannot drift (AC-5). // StaticCachePrefixes are the only request-path prefixes the service worker may // cache. Authenticated responses and /{GUID} pages are never in it. var StaticCachePrefixes = []string{StaticPath} // CacheablePath reports whether a same-origin request may be cached by the // service worker (A5): a GET of a static asset, and nothing else. The path is // CLEANED first, so "/static/../{GUID}" is judged as "/{GUID}" — a traversal // cannot smuggle an authenticated path into the cache. // // It is the policy the embedded worker implements (static/sw.js) and the shape // its test asserts; no caching decision is taken anywhere else. func CacheablePath(method, requestPath string) bool { if method != http.MethodGet { return false } p := requestPath if !strings.HasPrefix(p, "/") { p = "/" + p } clean := path.Clean(p) for _, prefix := range StaticCachePrefixes { if strings.HasPrefix(clean, prefix) { return true } } return false }