Commit 29a711c
authored
fix: cancel context before closing body to prevent HTTP/2 hang (#769)
* fix: cancel context before closing body to prevent HTTP/2 hang
On HTTP/2, resp.Body.Close() blocks in a select waiting for stream cleanup
(cs.donec) or context cancellation (cs.ctx.Done()). When cc.wmu is contended,
cs.donec may never close, making ctx.Done() the only exit path.
The previous defer ordering (LIFO) ran Close() before cancel(), so ctx.Done()
never fired — causing an indefinite hang when the MCP server leaves the SSE
stream open after sending its response (allowed by the spec: SHOULD, not MUST).
Fix: call cancel() before resp.Body.Close() in all three locations:
- SendRequest
- SendNotification
- sendResponseToServer
Includes a deterministic reproduction test using a mock transport that
simulates the HTTP/2 Close() blocking behavior.
Fixes #768
Branch-Creation-Time: 2026-03-27T18:18:02+0000
* fix: address review feedback — nil-response error and goroutine leak in test
- Return descriptive error when resp is nil instead of wrapping a nil err
- Add done channel to blockingSSEReader so goroutines are cleanly unblocked
when h2BodySimulator.Close() is called, preventing leaks on test panics
* Add bug fixes and docstring updates from PR #769
* Revert commit 1a93b65
* fix: address coderabbit review — remove stray files and clean up test
- Delete path/to/your/file.go (placeholder that caused typecheck lint failure)
- Delete revert_commit.md (stray file)
- Remove unused t *testing.T field from mockH2Transport struct
- Add defer transport.Close() after Start() in regression test
* fix: handle json.Marshal error in mockH2Transport.RoundTrip1 parent e37b2f0 commit 29a711c
File tree
0 file changed
+0
-0
lines changed0 file changed
+0
-0
lines changed
0 commit comments