Streamable HTTP server: Accept and Content-Type are matched case-sensitively and by substring/prefix
维护者通常 3 天内回复
评估
这个 Issue 还没有评估数据。
描述
Version: rmcp 3.6.0 (also 3.5.1), transport-streamable-http-server, StreamableHttpService.
What happens
The POST and GET handlers in crates/rmcp/src/transport/streamable_http_server/tower.rs check Accept and Content-Type with raw string matching:
// POST, Accept
header.contains(JSON_MIME_TYPE) && header.contains(EVENT_STREAM_MIME_TYPE)
// POST, Content-Type
header.starts_with(JSON_MIME_TYPE)
// GET, Accept
header.contains(EVENT_STREAM_MIME_TYPE)
That gives these results:
| Request | Result | Expected |
|---|---|---|
Content-Type: Application/JSON |
415 | accepted |
Accept: APPLICATION/JSON, TEXT/EVENT-STREAM |
406 | accepted |
Content-Type: application/jsonx |
accepted | 415 |
Accept: application/json-seq, text/event-stream |
accepted | 406 |
Accept: application/json;q=0, text/event-stream |
accepted | 406 (q=0 means "not acceptable") |
Accept split across two header lines (application/json and text/event-stream) |
406 (only the first value is read) | accepted |
Expected
RFC 9110 §8.3.1 says the type, subtype and parameter names are case-insensitive. §5.3 allows a list-valued field like Accept to be sent as several field lines, which are equivalent to one comma-joined line. §12.5.1 says q=0 marks a type as not acceptable. Comparing parsed media types would cover all of these. For example: split on , across every Accept value, take the part before ;, trim it, compare with eq_ignore_ascii_case, and skip entries whose q is 0.
Impact
Low. Mainstream clients send lowercase values on a single line, so they work. A proxy or client that normalises header case, or splits Accept into separate lines, gets refused. The prefix and substring matches also let a non-JSON Content-Type through to the JSON deserialiser. That then fails later, with a less useful error.
Repro
curl -i -X POST http://127.0.0.1:8000/mcp \
-H 'Content-Type: Application/JSON' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# HTTP/1.1 415 Unsupported Media Type
The check runs before the body is read, so the body and protocol headers don't matter.
AI disclosure: written with Claude Code. I reviewed it.
- 主要语言
- Rust
- 星标
- 4.1k
- 派生
- 694
- 平均合并
- 4 天 9 小时
- 30 天内合并 PR
- 41
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
modelcontextprotocol/rust-sdk 的其他 Issue
-
Support tool exposure modes (direct / deferred / codemode) and client-side aggregation.可能已有人在做 @jamadeo 今天认领。 未关闭enhancement P3 T-model T-service
modelcontextprotocol/rust-sdk#1437 · 1 条评论 · 已指派 1 人 ·
维护者通常 3 天内回复
-
Return MergedList<T> from list_all_* and drop the _with_cache_hint variants可能已有人在做 @DaleSeo 于 4 天前认领。 未关闭enhancement P3 ready for work T-service v4
modelcontextprotocol/rust-sdk#1430 · 已指派 1 人 ·
维护者通常 3 天内回复
-
Server logs a fabricated 'initialize' (with synthesized rmcp/3.8.0 peer identity) for no-initialize SEP-2567 requests, ignoring clientInfo from _meta可能已有人在做 @jamadeo 于 4 天前认领。 未关闭bug P2 ready for work T-service T-transport
modelcontextprotocol/rust-sdk#1425 · 2 条评论 · 已指派 1 人 ·
维护者通常 3 天内回复
-
OAuth discovery drops explicit default ports from advertised issuer identifiers可能已有人在做 @gocamille 于 6 天前认领。 未关闭bug P1 ready for work T-security T-transport
modelcontextprotocol/rust-sdk#1420 · 4 条评论 · 已指派 1 人 ·
维护者通常 3 天内回复
-
`register_client` drops `client_secret_expires_at` from the registration response可能已有人在做 @gocamille 于 8 天前认领。 未关闭bug P2 ready for work T-security
modelcontextprotocol/rust-sdk#1416 · 1 条评论 · 已指派 1 人 ·
维护者通常 3 天内回复
查看 modelcontextprotocol/rust-sdk 的全部 Issue
相似的 Issue
-
bug priority: low
难度 2/5 1-3 小时 新手友好度 78/100
storytold/photocraft#12183 · 1 条评论 ·
维护者通常 2 天内回复
-
area:render needs-triage
难度 2/5 1-3 小时 新手友好度 78/100
bherbruck/solvecraft#13138 ·
-
testing
难度 2/5 1-3 小时 新手友好度 65/100
-
难度 2/5 1-3 小时 新手友好度 86/100
ratatui/ratatui-textarea#39 ·
-
bug
难度 2/5 1-3 小时 新手友好度 68/100
transit-audio/transit#369 ·