Skip to content

v0.1.65 — drain response bodies before close

Choose a tag to compare

@rromenskyi rromenskyi released this 02 Oct 08:20
· 71 commits to main since this release
0c90339

DLP/capture-M3 + Limits-M1 — response bodies weren't drained, blocking connection reuse

One underlying bug class, two independent occurrences, fixed together: both internal/dlp.ModelScan (on a non-2xx sidecar response) and internal/webhook's deliver (on every response, success or failure — it never read the body at all) closed the response body without reading it first. Go's http.Transport cannot safely reuse a connection whose body wasn't read to EOF, so a sidecar/webhook endpoint returning errors (or just responding normally) forced a fresh TCP connection — and over TLS, a fresh handshake — per call instead of pooling it. ModelScan runs on every message the BERT layer is enabled for; deliver runs on every DLP-incident webhook fan-out.

Fix: io.Copy(io.Discard, resp.Body) before Close in both places. webhook's fix is factored into a new doDeliver(hc, req) taking the client as a parameter, so the drain behavior is testable against a plain client — deliver itself still always uses the real SSRF-guarded client.

Test plan:

  • TestModelScanDrainsBodyOnNonSuccessStatus, TestDoDeliverDrainsBodyAllowingConnectionReuse: write a large (10MB) response body, make several sequential requests over a keep-alive client, count actual accepted TCP connections via the test server's ConnState hook
  • Verified load-bearing via surgical revert on both — both genuinely failed; reverted before committing
  • A genuine data race surfaced while writing these tests (caught by -race, not a false alarm): httptest.NewServer starts serving immediately, racing against setting Config.ConnState afterward. Fixed with NewUnstartedServer + manual Start(). Verified clean across 15+ repeated -race runs
  • Full gate green: gofmt, go build, go vet, full test suite

PRs: #133 (fix), #134 (chart bump)

Thirty-eighth of 62 confirmed findings — closes DLP/capture's third Minor finding and Limits/pricing's only Minor finding in one PR. Next up: DLP/capture-M4 (capture/store.go's scanRows silently discards JSON-unmarshal errors).

🤖 Generated with Claude Code