fix(streamable-http-server): map handler-generated HeaderMismatch to HTTP 400 (#1259)
`jsonrpc_http_status` maps several protocol errors (unsupported protocol version, missing required client capability, invalid params) to HTTP 400 on the modern per-request Streamable HTTP path, but fell through to the default HTTP 200 for `ErrorCode::HEADER_MISMATCH`. When a `ServerHandler` returns `Err(ErrorData::header_mismatch(...))`, RMCP serialized the correct JSON-RPC -32020 error but sent it with HTTP 200. The legacy/transport-generated header validation path (SEP-2243 Mcp-Method/Mcp-Name/Mcp-Param-* mismatches) was unaffected, since `header_mismatch_jsonrpc_response` constructs an HTTP 400 response directly rather than going through `jsonrpc_http_status`. Only handler-generated HeaderMismatch errors on the modern path hit the bug. Add `ErrorCode::HEADER_MISMATCH` to the existing `BAD_REQUEST` match arm, matching the Streamable HTTP server-validation rules in the 2026-07-28 spec. Added unit tests covering the mapper directly (header-mismatch to 400, method-not-found to 404, an unmapped code defaulting to 200). Closes #1225 Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e27c5d1c24
commit
b86995aebd
1 changed files with 41 additions and 1 deletions
|
|
@ -644,12 +644,52 @@ fn jsonrpc_http_status(message: &ServerJsonRpcMessage) -> http::StatusCode {
|
|||
match error.error.code {
|
||||
ErrorCode::UNSUPPORTED_PROTOCOL_VERSION
|
||||
| ErrorCode::MISSING_REQUIRED_CLIENT_CAPABILITY
|
||||
| ErrorCode::INVALID_PARAMS => http::StatusCode::BAD_REQUEST,
|
||||
| ErrorCode::INVALID_PARAMS
|
||||
| ErrorCode::HEADER_MISMATCH => http::StatusCode::BAD_REQUEST,
|
||||
ErrorCode::METHOD_NOT_FOUND => http::StatusCode::NOT_FOUND,
|
||||
_ => http::StatusCode::OK,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod jsonrpc_http_status_tests {
|
||||
use super::*;
|
||||
|
||||
fn error_message(code: ErrorCode) -> ServerJsonRpcMessage {
|
||||
ServerJsonRpcMessage::Error(JsonRpcError::new(
|
||||
Some(RequestId::Number(1)),
|
||||
ErrorData::new(code, "test error", None),
|
||||
))
|
||||
}
|
||||
|
||||
/// A handler returning `ErrorData::header_mismatch(..)` on the modern per-request path
|
||||
/// must map to HTTP 400, not the default HTTP 200. Regression test for
|
||||
/// https://github.com/modelcontextprotocol/rust-sdk/issues/1225
|
||||
#[test]
|
||||
fn header_mismatch_maps_to_bad_request() {
|
||||
assert_eq!(
|
||||
jsonrpc_http_status(&error_message(ErrorCode::HEADER_MISMATCH)),
|
||||
http::StatusCode::BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn method_not_found_maps_to_not_found() {
|
||||
assert_eq!(
|
||||
jsonrpc_http_status(&error_message(ErrorCode::METHOD_NOT_FOUND)),
|
||||
http::StatusCode::NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unmapped_error_defaults_to_ok() {
|
||||
assert_eq!(
|
||||
jsonrpc_http_status(&error_message(ErrorCode::INTERNAL_ERROR)),
|
||||
http::StatusCode::OK
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn jsonrpc_message_response(
|
||||
message: ServerJsonRpcMessage,
|
||||
map_protocol_status: bool,
|
||||
|
|
|
|||
Loading…
Reference in a new issue