Skip to content

Commit edda393

Browse files
authored
fix potential risk of sending on closed channel (#194)
1 parent 6e000c3 commit edda393

File tree

1 file changed

+27
-23
lines changed

1 file changed

+27
-23
lines changed

client/transport/streamable_http.go

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -236,39 +236,43 @@ func (c *StreamableHTTP) handleSSEResponse(ctx context.Context, reader io.ReadCl
236236

237237
// Create a channel for this specific request
238238
responseChan := make(chan *JSONRPCResponse, 1)
239-
defer close(responseChan)
240239

241240
ctx, cancel := context.WithCancel(ctx)
242241
defer cancel()
243242

244243
// Start a goroutine to process the SSE stream
245-
go c.readSSE(ctx, reader, func(event, data string) {
246-
247-
// (unsupported: batching)
244+
go func() {
245+
// only close responseChan after readingSSE()
246+
defer close(responseChan)
248247

249-
var message JSONRPCResponse
250-
if err := json.Unmarshal([]byte(data), &message); err != nil {
251-
fmt.Printf("failed to unmarshal message: %v\n", err)
252-
return
253-
}
248+
c.readSSE(ctx, reader, func(event, data string) {
254249

255-
// Handle notification
256-
if message.ID == nil {
257-
var notification mcp.JSONRPCNotification
258-
if err := json.Unmarshal([]byte(data), &notification); err != nil {
259-
fmt.Printf("failed to unmarshal notification: %v\n", err)
250+
// (unsupported: batching)
251+
252+
var message JSONRPCResponse
253+
if err := json.Unmarshal([]byte(data), &message); err != nil {
254+
fmt.Printf("failed to unmarshal message: %v\n", err)
260255
return
261256
}
262-
c.notifyMu.RLock()
263-
if c.notificationHandler != nil {
264-
c.notificationHandler(notification)
257+
258+
// Handle notification
259+
if message.ID == nil {
260+
var notification mcp.JSONRPCNotification
261+
if err := json.Unmarshal([]byte(data), &notification); err != nil {
262+
fmt.Printf("failed to unmarshal notification: %v\n", err)
263+
return
264+
}
265+
c.notifyMu.RLock()
266+
if c.notificationHandler != nil {
267+
c.notificationHandler(notification)
268+
}
269+
c.notifyMu.RUnlock()
270+
return
265271
}
266-
c.notifyMu.RUnlock()
267-
return
268-
}
269-
270-
responseChan <- &message
271-
})
272+
273+
responseChan <- &message
274+
})
275+
}()
272276

273277
// Wait for the response or context cancellation
274278
select {

0 commit comments

Comments
 (0)