@@ -641,6 +641,60 @@ func TestStreamableServerDisconnect(t *testing.T) {
641641 }
642642}
643643
644+ func TestStreamableHTTPHandlerClose (t * testing.T ) {
645+ server := NewServer (testImpl , nil )
646+ handler := NewStreamableHTTPHandler (func (* http.Request ) * Server { return server }, nil )
647+ httpServer := httptest .NewServer (mustNotPanic (t , handler ))
648+ defer httpServer .Close ()
649+
650+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
651+ defer cancel ()
652+
653+ client := NewClient (testImpl , nil )
654+ // Pin a pre-SEP-2575 protocol version so Connect performs a single
655+ // legacy initialize handshake (one session). Under the modern protocol the
656+ // client first issues a stateless server/discover probe, which—when the
657+ // server falls back to the legacy handshake—transiently leaves an extra
658+ // session and would make the exact count below nondeterministic. This test
659+ // exercises Close, not protocol negotiation.
660+ clientSession , err := client .Connect (ctx , & StreamableClientTransport {Endpoint : httpServer .URL }, & ClientSessionOptions {protocolVersion : protocolVersion20251125 })
661+ if err != nil {
662+ t .Fatalf ("client.Connect() failed: %v" , err )
663+ }
664+ t .Cleanup (func () { _ = clientSession .Close () })
665+
666+ handler .mu .Lock ()
667+ if len (handler .sessions ) != 1 {
668+ t .Fatalf ("want 1 session before Close, got %d" , len (handler .sessions ))
669+ }
670+ handler .mu .Unlock ()
671+
672+ if err := handler .Close (); err != nil {
673+ t .Fatalf ("Close() failed: %v" , err )
674+ }
675+ if err := handler .Close (); err != nil {
676+ t .Fatalf ("second Close() failed: %v" , err )
677+ }
678+
679+ handler .mu .Lock ()
680+ if len (handler .sessions ) != 0 {
681+ t .Fatalf ("want 0 sessions after Close, got %d" , len (handler .sessions ))
682+ }
683+ if ! handler .closed {
684+ t .Fatal ("want handler.closed true after Close" )
685+ }
686+ handler .mu .Unlock ()
687+
688+ resp , err := http .Get (httpServer .URL )
689+ if err != nil {
690+ t .Fatalf ("http.Get after Close failed: %v" , err )
691+ }
692+ defer resp .Body .Close ()
693+ if resp .StatusCode != http .StatusServiceUnavailable {
694+ t .Fatalf ("got status %d after Close, want %d" , resp .StatusCode , http .StatusServiceUnavailable )
695+ }
696+ }
697+
644698func TestServerTransportCleanup (t * testing.T ) {
645699 nClient := 3
646700
0 commit comments