Set chunked Transfer-Encoding when using send

Previously, using `.send()` on `Request` would require to set either the
Transfer-Encoding or the Content-Length header.

In an effort to provide better ergonomics for this library and to avoid
making users fall in a not-so obvious pitfall, the library should build a
valid Request without asking the user to mess around with the headers.

This commit attempts to fix this issue: if the user use `.send()` to
provide an unknown sized reader, the chunked Transfer-Encoding will be
used. Of course, there are prior checks to ensure we do not override the
user wish, like if the user already set a Content-Length or a
Transfer-Encoding.

This commit fix an edge case where the Content-Length would not be
automatically set if the Transfer-Encoding is set but not chunked.
This commit is contained in:
Deluvi
2020-06-23 20:42:10 +02:00
committed by Martin Algesten
parent db0c6fb1b0
commit e224a6d126
4 changed files with 21 additions and 9 deletions

View File

@@ -35,12 +35,12 @@ impl Unit {
pub(crate) fn new(req: &Request, url: &Url, mix_queries: bool, body: &SizedReader) -> Self {
//
let is_chunked = req
let (is_transfer_encoding_set, mut is_chunked) = req
.header("transfer-encoding")
// if the user has set an encoding header, obey that.
.map(|enc| !enc.is_empty())
.map(|enc| (!enc.is_empty(), enc == "chunked"))
// otherwise, no chunking.
.unwrap_or(false);
.unwrap_or((false, false));
let query_string = combine_query(&url, &req.query, mix_queries);
@@ -52,8 +52,19 @@ impl Unit {
// chunking and Content-Length headers are mutually exclusive
// also don't write this if the user has set it themselves
if !is_chunked && !req.has("content-length") {
// if the payload is of known size (everything beside an unsized reader), set
// Content-Length,
// otherwise, use the chunked Transfer-Encoding (only if no other Transfer-Encoding
// has been set
if let Some(size) = body.size {
extra.push(Header::new("Content-Length", &format!("{}", size)));
if size != 0 {
extra.push(Header::new("Content-Length", &format!("{}", size)));
}
} else {
if !is_transfer_encoding_set {
extra.push(Header::new("Transfer-Encoding", "chunked"));
is_chunked = true;
}
}
}