From 7435cc3399895643062f4e399fae6d5b20b049a1 Mon Sep 17 00:00:00 2001 From: Jonathan Murray Date: Tue, 30 Nov 2021 17:58:50 +0100 Subject: [PATCH] fix(server): use case-insensitive comparison for Expect: 100-continue (#2709) According to rfc2616#section-14.20 the header value is case-insensitive. Certain clients send the expectation as `100-Continue` and this should be handled by the server. Closes #2708 --- src/proto/h1/role.rs | 5 ++++- tests/server.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) 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();