Skip to content

Commit 9968f2c

Browse files
committed
fix: consume response body on unexpected content type to prevent client hang
Fixes #2432
1 parent 5cbd259 commit 9968f2c

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

src/mcp/client/streamable_http.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ async def _handle_post_request(self, ctx: RequestContext) -> None:
295295
elif content_type.startswith("text/event-stream"):
296296
await self._handle_sse_response(response, ctx, is_initialization)
297297
else:
298+
await response.aread() # consume body to prevent stream hang
298299
logger.error(f"Unexpected content type: {content_type}")
299300
error_data = ErrorData(code=INVALID_REQUEST, message=f"Unexpected content type: {content_type}")
300301
error_msg = SessionMessage(JSONRPCError(jsonrpc="2.0", id=message.id, error=error_data))

tests/shared/test_streamable_http.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,3 +2318,22 @@ async def test_streamable_http_client_preserves_custom_with_mcp_headers(
23182318

23192319
assert "content-type" in headers_data
23202320
assert headers_data["content-type"] == "application/json"
2321+
2322+
2323+
@pytest.mark.anyio
2324+
async def test_unexpected_content_type_does_not_hang():
2325+
"""Test that client raises MCPError instead of hanging when server returns unexpected content type."""
2326+
2327+
def return_plain_text(request: httpx.Request) -> httpx.Response:
2328+
return httpx.Response(200, headers={"content-type": "text/plain"}, content=b"this is not json")
2329+
2330+
mock_client = httpx.AsyncClient(transport=httpx.MockTransport(return_plain_text))
2331+
2332+
async with streamable_http_client("http://test/mcp", http_client=mock_client) as (
2333+
read_stream,
2334+
write_stream,
2335+
):
2336+
async with ClientSession(read_stream, write_stream) as session:
2337+
with pytest.raises(MCPError, match="Unexpected content type"):
2338+
await session.initialize()
2339+

0 commit comments

Comments
 (0)