diff --git a/src/proto/h1/role.rs b/src/proto/h1/role.rs index 1902a774a3..333a85bcf9 100644 --- a/src/proto/h1/role.rs +++ b/src/proto/h1/role.rs @@ -271,7 +271,10 @@ impl Http1Transaction for Server { } } header::EXPECT => { - expect_continue = value.as_bytes() == b"100-continue"; + // According to https://datatracker.ietf.org/doc/html/rfc2616#section-14.20 + // Comparison of expectation values is case-insensitive for unquoted tokens + // (including the 100-continue token) + expect_continue = value.as_bytes().eq_ignore_ascii_case(b"100-continue"); } header::UPGRADE => { // Upgrades are only allowed with HTTP/1.1 diff --git a/tests/server.rs b/tests/server.rs index 13530a36c3..8a974fdd7c 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -831,6 +831,39 @@ fn expect_continue_sends_100() { assert_eq!(body, msg); } +#[test] +fn expect_continue_accepts_upper_cased_expectation() { + let server = serve(); + let mut req = connect(server.addr()); + server.reply(); + + req.write_all( + b"\ + POST /foo HTTP/1.1\r\n\ + Host: example.domain\r\n\ + Expect: 100-Continue\r\n\ + Content-Length: 5\r\n\ + Connection: Close\r\n\ + \r\n\ + ", + ) + .expect("write 1"); + + let msg = b"HTTP/1.1 100 Continue\r\n\r\n"; + let mut buf = vec![0; msg.len()]; + req.read_exact(&mut buf).expect("read 1"); + assert_eq!(buf, msg); + + let msg = b"hello"; + req.write_all(msg).expect("write 2"); + + let mut body = String::new(); + req.read_to_string(&mut body).expect("read 2"); + + let body = server.body(); + assert_eq!(body, msg); +} + #[test] fn expect_continue_but_no_body_is_ignored() { let server = serve();