server: serve static files from memory (macOS sendfile fix)#68
Conversation
http.ServeFile uses the sendfile fast path on darwin which truncates responses to the first TCP segment (~512 bytes) on some local setups, yielding a corrupt index.html in the browser. Read the file into memory and write it via w.Write so the response is portable across platforms. The static payload is tiny (HTML + a handful of icons), so the read-once cost is negligible. No behavior change for clients. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a701758. Configure here.
| // /<prefix>/*. Path traversal is rejected. | ||
| func staticDirHandler(baseDir string) http.HandlerFunc { | ||
| return func(w http.ResponseWriter, r *http.Request) { | ||
| rest := strings.TrimPrefix(r.URL.Path, "/static/") |
There was a problem hiding this comment.
Hardcoded URL prefix instead of chi wildcard param
Low Severity
staticDirHandler extracts the relative path via strings.TrimPrefix(r.URL.Path, "/static/"), hardcoding the /static/ URL prefix rather than using chi.URLParam(r, "*"). The rest of the codebase consistently uses chi.URLParam for route parameter extraction. This couples the handler's internals to the route registration string and will silently break if the route is ever moved to a sub-router (where chi rewrites r.URL.Path).
Reviewed by Cursor Bugbot for commit a701758. Configure here.


Summary
http.ServeFileuses thesendfile(2)fast path on darwin which truncates responses to the first TCP segment (~512 bytes) on some local setups, so the browser receives a corruptindex.html. Read the file into memory and write it withw.Writeso the response is portable across platforms.Tiny in scope:
serveStaticFile) for the index routestaticDirHandler) for the/static/*wildcard, with..path-traversal rejectionContent-Typederived from extension viamime.TypeByExtension, falling back tohttp.DetectContentTypeThe static payload is HTML + a handful of icons, so the read-on-every-request cost is negligible. No behavior change for clients.
Test plan
Made with Cursor
Note
Low Risk
Small static-only HTTP surface with basic path traversal rejection; no auth, API, or data-layer changes.
Overview
Replaces
http.ServeFilefor the root route with an in-memory handler that readsstatic/index.htmlon each request and writes the full body with explicitContent-TypeandContent-Length, avoiding Darwinsendfiletruncation that could corrupt HTML in local dev.Adds a
/static/*route backed bystaticDirHandler, which serves assets from thestaticdirectory the same way (read +w.Write), sets MIME type from the file extension (withhttp.DetectContentTypefallback), and returns 404 for empty paths or..traversal attempts.Reviewed by Cursor Bugbot for commit a701758. Bugbot is set up for automated code reviews on this repo. Configure here.