Skip to content

otelgin: copy MultipartForm back to original request so net/http cleans it up#8851

Open
SAY-5 wants to merge 1 commit intoopen-telemetry:mainfrom
SAY-5:fix/otelgin-multipart-form-leak-5946
Open

otelgin: copy MultipartForm back to original request so net/http cleans it up#8851
SAY-5 wants to merge 1 commit intoopen-telemetry:mainfrom
SAY-5:fix/otelgin-multipart-form-leak-5946

Conversation

@SAY-5
Copy link
Copy Markdown

@SAY-5 SAY-5 commented Apr 21, 2026

Summary

Fixes #5946.

otelgin.Middleware swaps c.Request for a context-carrying copy before running downstream handlers, then restores the original context on the shadow request. But net/http's finishRequest only cleans up MultipartForm temp files on the exact *http.Request it handed ServeHTTP, which is still the untouched original. The MultipartForm populated by c.FormFile / ParseMultipartForm during the request lives on the shadow request and is never reaped. For any multipart upload larger than MaxMultipartMemory, the uploaded bytes spill into multipart-* temp files that accumulate on disk.

Fix

Hold on to the original *http.Request, and in the deferred restore copy c.Request.MultipartForm back onto it before reassigning, so finishRequest finds the form to clean up. The span-context path (savedCtx) is unchanged.

Test plan

  • go build ./...
  • go test ./... -count=1
  • Added TestMiddlewarePropagatesMultipartFormBack - posts a multipart payload through the middleware and asserts the original request's MultipartForm is non-nil after ServeHTTP returns. The test fails on master (shadow-request leak) and passes with this patch.

…ns it up

Middleware swaps c.Request for a context-carrying copy before
running downstream handlers, then restores the original context
on the shadow request. net/http's finishRequest only cleans up
MultipartForm temp files on the exact *http.Request it handed
ServeHTTP, which is still the untouched original - the
MultipartForm populated by `c.FormFile` / ParseMultipartForm
during the request lives on the shadow request and is never
reaped. For any Content-Type: multipart/form-data upload larger
than MaxMultipartMemory, the uploaded bytes spill into
`multipart-*` temp files that accumulate on disk
(open-telemetry#5946).

Hold on to the original *http.Request, and in the deferred
restore copy c.Request.MultipartForm back onto it before
reassigning so finishRequest finds the form to clean up. The
spanContext path is unchanged (we already saved its ctx).

Added TestMiddlewarePropagatesMultipartFormBack which posts a
multipart payload through the middleware and asserts the
original request's MultipartForm is non-nil after ServeHTTP
returns; the test fails on the old shadow-request code path.

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>

Fixes open-telemetry#5946
@SAY-5 SAY-5 requested review from a team and flc1125 as code owners April 21, 2026 06:02
@github-actions github-actions Bot requested a review from akats7 April 21, 2026 06:02
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.

Using otelgin.Middleware will cause temporary MultipartForm files not to be destroyed.

1 participant