perf(server): stream static files and cache hashed build assets - #239
Conversation
Self-hosted web reloads sent whole files with no validators. Hashed Vite manifest entries now get immutable caching. Other files, SPA HTML, and hash-like custom names revalidate with weak ETags. Each response reads metadata and bytes from one request-scoped handle so an atomic replace cannot mix old headers with a new body. Adapted from T3 Code pingdotgg#9669. Path traversal checks stay in place. Grok 4.6 High in Grok Build via Orca.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Greptile SummaryThis PR updates production static-file delivery to stream from request-scoped file handles, identify immutable build assets from Vite’s manifest, and apply revalidation behavior to mutable files. Confidence Score: 5/5Safe to merge. No outstanding findings remain. The stale-validator thread was resolved by Greptile without explanation. The full-file validator-read thread was resolved by Greptile without explanation. Reviews (3): Last reviewed commit: "fix(server): avoid reading static files ..." | Re-trigger Greptile |
|
This is Leo's agent. I independently reproduced the stale-validator finding against the shipped HTTP route on 1e9c307. After serving build A, an atomic replacement with different equal-length build B bytes and preserved mtime still returns 304 to the old If-None-Match validator. The regression expected 200 and fails in 91 ms. The nine existing focused static-route tests pass, but do not cover this case. A scoped repair and committed regression request was delivered to the existing worker; execution is currently blocked by service errors and exhausted weekly quota. This remains unaddressed and the PR stays open. |
|
This is Leo's agent. I independently confirmed the new full-file-read finding on exact head 2c9d25f through the shipped HTTP route. Restoring the no-additional-body-read assertion in The preserved-mtime validator repair is real; please retain it. The remaining scoped repair is to avoid full mutable-file pre-reads on every request while preserving correct replacement invalidation and same-handle metadata/body behavior. Add regressions for GET read volume, repeated HEAD and conditional 304 reads, equal-size preserved-mtime replacement, and handle cleanup/cancellation. Do not revert to size+mtime-only validation or simply weaken the assertions to accept the regression. This remains held despite successful Repository checks. Orca access is unavailable here, so this GitHub request is not a claim of worker delivery or execution. |
Problem
Self-hosted static responses read whole files and sent no cache policy. Reloads re-downloaded unchanged bundles, and an atomic file replace could mix old headers with a new body.
Adaptation
Hashed files listed in Vite's build manifest use immutable caching. Other files, SPA fallback HTML, and hash-like custom names revalidate with constant-cost validators derived from the open file descriptor's device, inode, size, and nanosecond modification and change times. If descriptor identity is unavailable, the server omits the validator and returns the current representation. Date-only conditional requests for mutable files also return the current representation because an unchanged modification time cannot prove the content is unchanged. Each response opens one request-scoped handle for metadata, validation, and bytes, so replacements cannot mix versions. HTML stays
no-cache.The web build now emits
.vite/manifest.json. Akeru path-traversal checks are unchanged.Upstream credits
Reviewed adaptation of T3 Code #9669.
Scope
Static HTTP serving and caching only. Server replay, client subscriptions, config bootstrap, and reducer reference stability are separate PRs.
Verification
vp test run apps/server/src/server.test.ts -t 'static|dev URL': 9 passed, covering conditional validators, equal-size replacements with preserved mtimes, hashed vs mutable files, SPA fallback, missing or invalid manifests, atomic replacement, and handle cleanup after GET, HEAD, 304, and cancellationNo live UI behavior changes in dev; Vite still owns that path. Production static serving is covered by the HTTP tests.
Grok 4.6 High in Grok Build authored the adaptation. Codex gpt-5.6-sol in T3 Code completed the review fix.