Skip to content

fix(server): match Content-Type case-insensitively in StreamableHTTP#2916

Open
ly-wang19 wants to merge 1 commit into
modelcontextprotocol:mainfrom
ly-wang19:fix/streamable-http-content-type-case-insensitive
Open

fix(server): match Content-Type case-insensitively in StreamableHTTP#2916
ly-wang19 wants to merge 1 commit into
modelcontextprotocol:mainfrom
ly-wang19:fix/streamable-http-content-type-case-insensitive

Conversation

@ly-wang19

Copy link
Copy Markdown

Summary

StreamableHTTPServerTransport._check_content_type compared the request's Content-Type media type case-sensitively, so a spec-valid request with a mixed/upper-case type (e.g. Content-Type: Application/JSON) was rejected with 415 Unsupported Media Type.

Media types are case-insensitive (RFC 9110, §8.3.1), and the sibling _check_accept_headers already lowercases Accept media types before comparing — _check_content_type just didn't.

Fix

Lowercase the parsed Content-Type media type before comparing to CONTENT_TYPE_JSON, consistent with _check_accept_headers.

Test

Added test_check_content_type_is_case_insensitive (the _check_content_type rejection path was previously marked # pragma: no cover). It asserts application/json, Application/JSON, APPLICATION/JSON, and ; charset=utf-8 variants are accepted, and text/plain is still rejected.

Verified red→green: the new test fails on main (mixed-case rejected) and passes with the fix. uv run pytest tests/shared/test_streamable_http.py → 70 passed; ruff check / ruff format --check clean on both files.

Media types are case-insensitive (RFC 9110, section 8.3.1), and
StreamableHTTPServerTransport._check_accept_headers already lowercases the
Accept media types before comparing. _check_content_type did not, so a
spec-valid request with a mixed/upper-case Content-Type (e.g.
"Application/JSON") was rejected with 415 Unsupported Media Type.

Lowercase the parsed Content-Type media type before comparing to
CONTENT_TYPE_JSON, consistent with _check_accept_headers. Adds a unit test for
case-insensitive matching (the _check_content_type path was previously no-cover).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant