Remove Content-Encoding and length when decompressing

This should lower the chance of breakage. Probably also more proper for a client library.
This commit is contained in:
Malloc Voidstar
2021-10-05 09:46:31 -07:00
committed by Martin Algesten
parent 6281a0bea6
commit 598ebf4393
2 changed files with 23 additions and 8 deletions

View File

@@ -74,6 +74,11 @@ pub struct Response {
/// ///
/// If this response was not redirected, the history is empty. /// If this response was not redirected, the history is empty.
pub(crate) history: Vec<Url>, pub(crate) history: Vec<Url>,
/// The Content-Length value. The header itself may have been removed due to
/// the automatic decompression system.
length: Option<usize>,
/// The compression type of the response body.
compression: Option<Compression>,
} }
/// index into status_line where we split: HTTP/1.1 200 OK /// index into status_line where we split: HTTP/1.1 200 OK
@@ -283,15 +288,9 @@ impl Response {
// head requests never have a body // head requests never have a body
Some(0) Some(0)
} else { } else {
self.header("content-length") self.length
.and_then(|l| l.parse::<usize>().ok())
}; };
let compression = self
.header("content-encoding")
.map(Compression::from_header_value)
.flatten();
let stream = self.stream; let stream = self.stream;
let unit = self.unit; let unit = self.unit;
if let Some(unit) = &unit { if let Some(unit) = &unit {
@@ -311,7 +310,7 @@ impl Response {
(false, None) => Box::new(stream), (false, None) => Box::new(stream),
}; };
match compression { match self.compression {
None => body_reader, None => body_reader,
Some(c) => c.wrap_reader(body_reader), Some(c) => c.wrap_reader(body_reader),
} }
@@ -487,6 +486,16 @@ impl Response {
)); ));
} }
let length = get_header(&headers, "content-length").and_then(|v| v.parse::<usize>().ok());
let compression =
get_header(&headers, "content-encoding").and_then(Compression::from_header_value);
if compression.is_some() {
headers.retain(|h| h.name() != "content-encoding" && h.name() != "content-length");
// remove Content-Encoding and length due to automatic decompression
}
Ok(Response { Ok(Response {
url: None, url: None,
status_line, status_line,
@@ -496,6 +505,8 @@ impl Response {
unit: unit.map(Box::new), unit: unit.map(Box::new),
stream: Box::new(stream.into()), stream: Box::new(stream.into()),
history: vec![], history: vec![],
length,
compression,
}) })
} }

View File

@@ -101,6 +101,8 @@ fn gzip_text() {
// echo -n INPUT | gzip -9 -f | hexdump -ve '1/1 "0x%.2X,"' // echo -n INPUT | gzip -9 -f | hexdump -ve '1/1 "0x%.2X,"'
// INPUT is `hello world ` repeated 14 times, no trailing space // INPUT is `hello world ` repeated 14 times, no trailing space
let resp = get("test://host/gzip_text").call().unwrap(); let resp = get("test://host/gzip_text").call().unwrap();
assert_eq!(resp.header("content-encoding"), None);
assert_eq!(resp.header("content-length"), None);
let text = resp.into_string().unwrap(); let text = resp.into_string().unwrap();
assert_eq!(text, "hello world ".repeat(14).trim_end()); assert_eq!(text, "hello world ".repeat(14).trim_end());
} }
@@ -121,6 +123,8 @@ fn brotli_text() {
}); });
// echo -n INPUT | brotli -Z -f | hexdump -ve '1/1 "0x%.2X,"' // echo -n INPUT | brotli -Z -f | hexdump -ve '1/1 "0x%.2X,"'
let resp = get("test://host/brotli_text").call().unwrap(); let resp = get("test://host/brotli_text").call().unwrap();
assert_eq!(resp.header("content-encoding"), None);
assert_eq!(resp.header("content-length"), None);
let text = resp.into_string().unwrap(); let text = resp.into_string().unwrap();
assert_eq!(text, "hello world ".repeat(14).trim_end()); assert_eq!(text, "hello world ".repeat(14).trim_end());
} }