Skip to content

Commit

Permalink
fix(client): send content-length even with no body
Browse files Browse the repository at this point in the history
Most request methods define a payload. If hyper detects that no body has
been included, it will now include a `content-length: 0` header
automatically.

It will not do this for methods that don't have defined payloads (GET,
HEAD, and CONNECT).
  • Loading branch information
seanmonstar committed Apr 15, 2024
1 parent b79be91 commit 172fdfa
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
23 changes: 17 additions & 6 deletions src/proto/h1/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,13 @@ impl Client {
body
} else {
head.headers.remove(header::TRANSFER_ENCODING);
// If we know there's body coming, set a content-length.
// But only if the method normally has a body.
// GET, HEAD, and CONNECT are assumed empty.
if !is_method_assumed_empty(&head.subject.0) {
head.headers
.insert(header::CONTENT_LENGTH, HeaderValue::from_static("0"));
}
return Encoder::length(0);
};

Expand Down Expand Up @@ -1361,12 +1368,11 @@ impl Client {
// So instead of sending a "chunked" body with a 0-chunk,
// assume no body here. If you *must* send a body,
// set the headers explicitly.
match head.subject.0 {
Method::GET | Method::HEAD | Method::CONNECT => Some(Encoder::length(0)),
_ => {
te.insert(HeaderValue::from_static("chunked"));
Some(Encoder::chunked())
}
if is_method_assumed_empty(&head.subject.0) {
Some(Encoder::length(0))
} else {
te.insert(HeaderValue::from_static("chunked"));
Some(Encoder::chunked())
}
} else {
None
Expand Down Expand Up @@ -1468,6 +1474,11 @@ impl Client {
}
}

#[cfg(feature = "client")]
fn is_method_assumed_empty(method: &Method) -> bool {
matches!(method, &Method::GET | &Method::HEAD | &Method::CONNECT)
}

#[cfg(feature = "client")]
fn set_content_length(headers: &mut HeaderMap, len: u64) -> Encoder {
// At this point, there should not be a valid Content-Length
Expand Down
24 changes: 24 additions & 0 deletions tests/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,30 @@ test! {
body: None,
}

test! {
name: client_post_empty_auto_length,

server:
expected: "\
POST /empty HTTP/1.1\r\n\
host: {addr}\r\n\
content-length: 0\r\n\
\r\n\
",
reply: REPLY_OK,

client:
request: {
method: POST,
url: "http://{addr}/empty",
headers: {},
},
response:
status: OK,
headers: {},
body: None,
}

test! {
name: client_head_ignores_body,

Expand Down

1 comment on commit 172fdfa

@bagder
Copy link
Contributor

@bagder bagder commented on 172fdfa Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new surprise header breaks curl test cases: curl/curl#13380

Please sign in to comment.