mcp: fix SSEClientTransport to report HTTP errors properly (#740)
Fix SSEClientTransport.Connect to check HTTP status code before attempting to parse SSE events. Fixes #714
This commit is contained in:
parent
1d5938cad4
commit
27b3354f80
2 changed files with 63 additions and 0 deletions
|
|
@ -351,6 +351,14 @@ func (c *SSEClientTransport) Connect(ctx context.Context) (Connection, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Check HTTP status code before attempting to parse SSE events.
|
||||
// This ensures proper error reporting for authentication failures (401),
|
||||
// authorization failures (403), and other HTTP errors.
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
resp.Body.Close()
|
||||
return nil, fmt.Errorf("failed to connect: %s", http.StatusText(resp.StatusCode))
|
||||
}
|
||||
|
||||
msgEndpoint, err := func() (*url.URL, error) {
|
||||
var evt Event
|
||||
for evt, err = range scanEvents(resp.Body) {
|
||||
|
|
|
|||
|
|
@ -131,3 +131,58 @@ type roundTripperFunc func(*http.Request) (*http.Response, error)
|
|||
func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return f(req)
|
||||
}
|
||||
|
||||
func TestSSEClientTransport_HTTPErrors(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
statusCode int
|
||||
wantErrContain string
|
||||
}{
|
||||
{
|
||||
name: "401 Unauthorized",
|
||||
statusCode: http.StatusUnauthorized,
|
||||
wantErrContain: "Unauthorized",
|
||||
},
|
||||
{
|
||||
name: "403 Forbidden",
|
||||
statusCode: http.StatusForbidden,
|
||||
wantErrContain: "Forbidden",
|
||||
},
|
||||
{
|
||||
name: "404 Not Found",
|
||||
statusCode: http.StatusNotFound,
|
||||
wantErrContain: "Not Found",
|
||||
},
|
||||
{
|
||||
name: "500 Internal Server Error",
|
||||
statusCode: http.StatusInternalServerError,
|
||||
wantErrContain: "Internal Server Error",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a test server that returns the specified status code
|
||||
httpServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, http.StatusText(tt.statusCode), tt.statusCode)
|
||||
}))
|
||||
defer httpServer.Close()
|
||||
|
||||
clientTransport := &SSEClientTransport{
|
||||
Endpoint: httpServer.URL,
|
||||
}
|
||||
|
||||
c := NewClient(testImpl, nil)
|
||||
_, err := c.Connect(context.Background(), clientTransport, nil)
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got nil")
|
||||
}
|
||||
|
||||
errStr := err.Error()
|
||||
if !bytes.Contains([]byte(errStr), []byte(tt.wantErrContain)) {
|
||||
t.Errorf("error message %q does not contain %q", errStr, tt.wantErrContain)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue