use super::wire;
type TestResult = Result<(), Box<dyn std::error::Error>>;
#[test]
fn content_length_is_required_unique_numeric_and_bounded() {
for (headers, cap, code) in [
("Host: example\r\n", 10, "mcp_http_length_required"),
(
"Host: example\r\nContent-Length: 1\r\nContent-Length: 1\r\n",
10,
"mcp_http_length_invalid",
),
(
"Host: example\r\nContent-Length: 11\r\n",
10,
"mcp_http_body_refused",
),
(
"Host: example\r\nContent-Length: +1\r\n",
10,
"mcp_http_headers_invalid",
),
(
"Host: example\r\nContent-Length: 1\r\nTransfer-Encoding: chunked\r\n",
10,
"mcp_http_transfer_encoding_refused",
),
] {
let request = format!("POST /mcp HTTP/1.1\r\n{headers}\r\n");
assert_eq!(
wire::parse(request.as_bytes(), cap)
.err()
.map(|error| error.code),
Some(code)
);
}
}
#[test]
fn challenge_uses_only_the_supplied_metadata_url() -> TestResult {
let error = super::error::Error::new(401, "mcp_sign_in_required", "Sign-in required");
let plain = wire::Response::refused(&error, None)?;
assert_eq!(plain.headers, [("WWW-Authenticate", "Bearer".to_owned())]);
let supplied = wire::Response::refused(&error, Some("https://identity.example/resource"))?;
assert_eq!(
supplied.headers,
[(
"WWW-Authenticate",
"Bearer resource_metadata=\"https://identity.example/resource\"".to_owned()
)]
);
Ok(())
}
#[test]
fn valid_headers_keep_duplicate_authorization_for_sign_in_refusal() -> TestResult {
let parsed = wire::parse(b"POST /mcp?unused=1 HTTP/1.1\r\nHost: example\r\nContent-Length: 0\r\nAuthorization: Bearer first\r\nAuthorization: Bearer second\r\n\r\n", 10)?;
assert_eq!(parsed.path, "/mcp");
assert_eq!(parsed.headers.get_all("authorization").iter().count(), 2);
assert_eq!(
super::headers::bearer(&parsed.headers)
.err()
.map(|error| error.code),
Some("mcp_sign_in_required")
);
Ok(())
}