Stream non-HTML responses past the overlay injector (audit L-5) #147
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
qwc-open/asiakirjat!147
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/overlay-streaming"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Audit item L-5, filed as low urgency. Independent of #144, #145 and #146.
What it did
overlayRecorderbuffered the entire response into abytes.Buffer, then looked at the Content-Type to decide whether to inject the overlay. Non-HTML responses were collected in full and copied out unchanged — the buffering bought nothing.It matters more than "an HTML page is small" suggests, because
serveVersionDocroutes anything extension-less through here:A file named
downloadormanualinside someone's docs is served by that last clause and can be any size, so the buffer had no useful bound.What it does now
The recorder decides as soon as the handler commits to a status —
ServeContentsets Content-Type before writing — and from then on a non-injectable response goes straight to the client. HTML is still buffered; the overlay has to go in before</body>, so the page genuinely has to be held.Two smaller things came with it:
text/html. A 206 carries a byte range, and injecting an overlay into part of a file corrupts it — that was possible before. The visible change is that a 404 page served from a docs directory no longer gets the overlay; a broken link inside docs shows the project's own 404 rather than a framed one.Flushpasses through once streaming has started, so a slow large file isn't held by us. While buffering it stays a no-op, since nothing can be released before the overlay goes in.The old header-copying loop is gone:
Header()returns the embedded writer's own map, so it was copying a map onto itself.Tests
Three added to
internal/docs/overlay_test.go: a probe writer asserting a PDF's three writes arrive as three writes rather than one buffered copy, a 206 keeping its status and staying un-injected, and HTML still getting the overlay before</body>with the staleContent-Lengthdropped. The existing overlay tests — HTML injection, non-HTML passthrough, images, status preservation — pass unchanged.Go suite and the 8 frontend tests green.
Assisted by Claude Opus 5.