Skip to content

Commit 29a711c

Browse files
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.RoundTrip
1 parent e37b2f0 commit 29a711c

File tree

0 file changed

+0
-0
lines changed

    0 file changed

    +0
    -0
    lines changed

    0 commit comments

    Comments
     (0)