Skip to content

http: fix empty UI page caused by the CSP nonce changing the body length - #32170

Open
alviss7 wants to merge 2 commits into
hashicorp:mainfrom
alviss7:fix-ui-nonce-content-length
Open

alviss7 wants to merge 2 commits into
hashicorp:mainfrom
alviss7:fix-ui-nonce-content-length

Conversation

@alviss7

@alviss7 alviss7 commented Oct 19, 2026

Copy link
Copy Markdown

Fixes #32169.

Since 2.2.0, /ui/ and every UI route without a dot answer 200 with the headers only: the browser gets an empty body and the web UI does not load.

handleUI wraps those requests in nonceResponseWriter to add the CSP nonce meta tag to index.html. The wrapper buffered the body but passed WriteHeader through immediately, after http.FileServer had set Content-Length to the size of the file. The rewritten page is longer than that, so net/http rejected the single write in flush() with ErrContentLength and nothing was sent.

Changes:

  • nonceResponseWriter keeps the status code and sends it from flush(), after setting Content-Length to the length of the rewritten page. Responses that are not rewritten (empty body, HEAD, 304) keep their headers as they are.
  • Range is removed from wrapped requests. Without that, ServeContent answered 206 with a byte range of the file on disk, and the nonce was injected into that partial content.

TestHandleUI_NonceContentLength goes through httptest.NewServer, since httptest.ResponseRecorder does not enforce Content-Length and does not show the bug. On the current main code it fails with unexpected EOF for the full page and a 206 for the range request; with this change both cases return the whole page with the nonce and a matching Content-Length.

I could not run the test from the repository itself: building ./http needs github.com/hashicorp/releases-api, which is private (#32164). I ran it against handleUI and nonceResponseWriter copied into a standalone module, before and after the change, with Go 1.27.2.

… CSP nonce

nonceResponseWriter forwarded WriteHeader to the client right away, while
http.FileServer had already set Content-Length to the size of index.html.
The nonce meta tag then made the page longer than announced, net/http
refused the write with ErrContentLength and the browser got an empty body.

The status and headers are now held until flush, which sets Content-Length
to the rewritten page. Range is dropped from wrapped requests, since a byte
range of the file on disk does not match the rewritten page.
@alviss7
alviss7 requested a review from a team as a code owner October 19, 2026 07:00
@alviss7
alviss7 requested a review from JMGoldsmith October 19, 2026 07:00
@hashicorp-cla-app

hashicorp-cla-app Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UI: /ui/ returns an empty body in 2.2.0 (nonceResponseWriter keeps the original Content-Length)

1 participant