Repository navigation
fix(transport): match reqwest response media types exactly - #1390
theamodhshetty wants to merge 1 commit into
Conversation
|
@DaleSeo (assignment failed) is on triage rotation this week and is the reviewer for this one. Labels come from the PR labeler. Please review the change. Automated triage. Labels are a first pass and the assigned maintainer has the final say. |
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
jokemanfire
left a comment
There was a problem hiding this comment.
Verified at ab6e5df instead of reading the diff:
cargo test -p rmcp --lib --features "client reqwest transport-streamable-http-client-reqwest" -- media_types→ 24 passed (8get_response_media_types, 14post_response_media_types, 2 byte-level essence cases).- Red check: restoring the three old call sites (
ct.as_bytes().starts_with(...)) while keeping the new tests → 12 failed, 10 passed. That reproduces the body's "12 fail on2a401c4, 10 passing controls" exactly. cargo fmt --checkclean.
The matcher looks right to me: splitting on the first ; before decoding is safe (a quoted parameter containing ; can only occur after the essence), suffix and list forms are rejected, and trim_matches([' ', '\t']) matches the OWS cases in the test matrix. I did not run the full lib suite or the feature-matrix CI locally.
Two follow-ups this PR does not have to take, but which should be recorded:
-
The same prefix comparison survives in the Unix-socket backend —
crates/rmcp/src/transport/common/unix_socket.rs:312,:317,:497-498, with identical semantics, soApplication/JSONis still rejected there. The body scopes the patch to reqwest, which is honest, butmedia_type_isis private to the reqwest module (crates/rmcp/src/transport/common/reqwest/streamable_http_client.rs:53), so the follow-up has to duplicate it. Moving it next toJSON_MIME_TYPEincommon/http_header.rswould make each remaining call site a one-line change; aTODOpointing at an issue is enough if shared code is out of scope here. -
Server-side request admission is still a prefix match —
crates/rmcp/src/transport/streamable_http_server/tower.rs:2008usesheader.starts_with(JSON_MIME_TYPE)on the incomingContent-Type. That is what #1382 covers, so out of scope, but the two sides of the same header now disagree aboutApplication/JSON; worth a note on #1382 rather than a change here.
Nothing blocks the fix as scoped.
|
Thanks for running the green/red checks and checking the scope. Recorded the Unix-socket follow-up in #1443 after confirming those prefix comparisons remain on current main. That issue tracks transport regressions and moving the matcher to The server admission fix in #1382 merged on October 30 at |
Motivation and Context
The reqwest Streamable HTTP client rejects valid
Application/JSONandText/Event-Streamresponses, while admitting different types such asapplication/jsonxandtext/event-streaming. On a JSON 503 response, the case mismatch also loses the original JSON-RPC error.Fixes #1389. This is separate from #1382, which changes server request validation.
Use one private matcher for the complete response media-type essence across GET admission, POST JSON/SSE dispatch and JSON error classification. Compare type/subtype case-insensitively, preserve parameter tolerance, and reject suffixes and comma-joined essences. Parameter bytes are left opaque. The existing accepted media types and body-free 429 policy are unchanged. No API or dependency changes.
How Has This Been Tested?
On macOS arm64 with Rust 1.96.1:
2a401c4, with 10 passing controls. All pass with this fix.The wire tests exercise GET, POST JSON/SSE, parameters, absent headers, case variants, suffix/list rejection, JSON 503 preservation and 429 status handling. No live external service or credentials are used.
Breaking Changes
Previously misclassified response types such as
application/jsonxnow return the existing unexpected-content-type error on success responses. They are not JSON/SSE media types. Valid response types remain accepted, with added case-insensitive support.Types of changes
Additional context
Ready for review following the merge of #1387. Issue #1389 records the scope discussion. Hosted CI passes at
ab6e5df, including tests, Clippy, MSRV, conformance and public API checks. Maintainer review is pending. This patch is scoped to the reqwest backend; Unix-socket response handling is unchanged. Developed with Codex assistance. Local checks and hosted CI are reported separately.