Skip to content

Commit

Permalink
fix(server): use case-insensitive comparison for Expect: 100-continue (
Browse files Browse the repository at this point in the history
…#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
  • Loading branch information
JonathanMurray committed Nov 30, 2021
1 parent 5f938ff commit 7435cc3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/proto/h1/role.rs
Expand Up @@ -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
Expand Down
33 changes: 33 additions & 0 deletions tests/server.rs
Expand Up @@ -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();
Expand Down

0 comments on commit 7435cc3

Please sign in to comment.