Skip to content

Commit 9b89620

Browse files
committed
Fix case-sensitive Accept header comparison
## Motivation and Context RFC 9110 defines media type comparison as case-insensitive, but `parse_accept_header` compared types without normalizing case. This caused `Application/JSON` or `TEXT/Event-Stream` to be rejected with 406 Not Acceptable. ## How Has This Been Tested? Added tests for mixed-case Accept headers: - `Accept: Application/JSON, Text/Event-Stream` succeeds for POST - `Accept: TEXT/EVENT-STREAM` succeeds for GET SSE ## Breaking Changes None. This is a bug fix bringing behavior into conformance with RFC 9110.
1 parent d17cc51 commit 9b89620

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

lib/mcp/server/transports/streamable_http_transport.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ def validate_accept_header(request, required_types)
504504

505505
def parse_accept_header(header)
506506
header.split(",").map do |part|
507-
part.split(";").first.strip
507+
part.split(";").first.strip.downcase
508508
end
509509
end
510510

test/mcp/server/transports/streamable_http_transport_test.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,6 +1465,45 @@ def string
14651465
assert_equal 200, response[0]
14661466
end
14671467

1468+
test "POST request with mixed-case Accept header succeeds" do
1469+
request = create_rack_request_without_accept(
1470+
"POST",
1471+
"/",
1472+
{
1473+
"CONTENT_TYPE" => "application/json",
1474+
"HTTP_ACCEPT" => "Application/JSON, Text/Event-Stream",
1475+
},
1476+
{ jsonrpc: "2.0", method: "initialize", id: "123" }.to_json,
1477+
)
1478+
1479+
response = @transport.handle_request(request)
1480+
assert_equal 200, response[0]
1481+
end
1482+
1483+
test "GET request with upper-case Accept header succeeds" do
1484+
init_request = create_rack_request(
1485+
"POST",
1486+
"/",
1487+
{ "CONTENT_TYPE" => "application/json" },
1488+
{ jsonrpc: "2.0", method: "initialize", id: "123" }.to_json,
1489+
)
1490+
init_response = @transport.handle_request(init_request)
1491+
session_id = init_response[1]["Mcp-Session-Id"]
1492+
1493+
request = create_rack_request_without_accept(
1494+
"GET",
1495+
"/",
1496+
{
1497+
"HTTP_ACCEPT" => "TEXT/EVENT-STREAM",
1498+
"HTTP_MCP_SESSION_ID" => session_id,
1499+
},
1500+
)
1501+
1502+
response = @transport.handle_request(request)
1503+
assert_equal 200, response[0]
1504+
assert_equal "text/event-stream", response[1]["Content-Type"]
1505+
end
1506+
14681507
test "GET request without Accept header returns 406" do
14691508
init_request = create_rack_request(
14701509
"POST",

0 commit comments

Comments
 (0)