mcp: close HTTP response body from DELETE request in streamableClientConn.Close (#929)

## Summary

The DELETE request that terminates a streamable HTTP session discards
the `*http.Response` without closing its body. Per the `net/http`
documentation, this prevents the underlying TCP connection from being
reused and leaks it.

## The bug

```go
// mcp/streamable.go:2239 (before)
} else if _, err := c.client.Do(req); err != nil {
    c.closeErr = err
}
```

On the success path (no error), the response is silently discarded. The
default client is `http.DefaultClient` with keep-alives enabled, so the
leaked connection stays open until GC or process exit.

## The fix

```go
// mcp/streamable.go:2239 (after)
} else if resp, err := c.client.Do(req); err != nil {
    c.closeErr = err
} else {
    resp.Body.Close()
}
```

All 10 other `client.Do` call sites in this file close the response
body. This one was missed.

## Test plan

- [x] `go build ./...` passes
- [x] `go test ./... -short` passes

Fixes #928
This commit is contained in:
Dayna Blackwell 2026-05-04 03:14:20 -07:00 • committed by GitHub
commit 8e45782dbd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2236,8 +2236,10 @@ func (c *streamableClientConn) Close() error {
} else {
if err := c.setMCPHeaders(req); err != nil {
c.closeErr = err
} else if _, err := c.client.Do(req); err != nil {
} else if resp, err := c.client.Do(req); err != nil {
c.closeErr = err
} else {
resp.Body.Close()
}
}
}