gzip: examine Content-Length header before removing (#578)

Fixes #575.
This commit is contained in:
Jacob Hoffman-Andrews
2023-01-02 20:02:37 -08:00
committed by GitHub
parent 78ec3a4d75
commit 032bfb4b27
3 changed files with 41 additions and 2 deletions

View File

@@ -1,3 +1,8 @@
# 2.6.1
## Fixed
* gzip: examine Content-Length header before removing (#578)
# 2.6.0 # 2.6.0
## Added ## Added

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "ureq" name = "ureq"
version = "2.6.0" version = "2.6.1"
authors = ["Martin Algesten <martin@algesten.se>", "Jacob Hoffman-Andrews <ureq@hoffman-andrews.com>"] authors = ["Martin Algesten <martin@algesten.se>", "Jacob Hoffman-Andrews <ureq@hoffman-andrews.com>"]
description = "Simple, safe HTTP client" description = "Simple, safe HTTP client"
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"

View File

@@ -566,12 +566,13 @@ impl Response {
let compression = let compression =
get_header(&headers, "content-encoding").and_then(Compression::from_header_value); get_header(&headers, "content-encoding").and_then(Compression::from_header_value);
let body_type = Self::body_type(&unit.method, status, http_version, &headers);
// remove Content-Encoding and length due to automatic decompression // remove Content-Encoding and length due to automatic decompression
if compression.is_some() { if compression.is_some() {
headers.retain(|h| !h.is_name("content-encoding") && !h.is_name("content-length")); headers.retain(|h| !h.is_name("content-encoding") && !h.is_name("content-length"));
} }
let body_type = Self::body_type(&unit.method, status, http_version, &headers);
let reader = Self::stream_to_reader(stream, &unit, body_type, compression); let reader = Self::stream_to_reader(stream, &unit, body_type, compression);
let url = unit.url.clone(); let url = unit.url.clone();
@@ -1183,4 +1184,37 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!(agent2.state.pool.len(), 1); assert_eq!(agent2.state.pool.len(), 1);
} }
#[test]
#[cfg(feature = "gzip")]
fn gzip_content_length() {
use std::io::Cursor;
let response_bytes =
b"HTTP/1.1 200 OK\r\nContent-Encoding: gzip\r\nContent-Length: 23\r\n\r\n\
\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xcb\xc8\xe4\x02\x00\x7a\x7a\x6f\xed\x03\x00\x00\x00";
// Follow the response with an infinite stream of 0 bytes, so the content-length
// is important.
let reader = Cursor::new(response_bytes).chain(std::io::repeat(0u8));
let test_stream = crate::test::TestStream::new(reader, std::io::sink());
let agent = Agent::new();
let stream = Stream::new(
test_stream,
"1.1.1.1:4343".parse().unwrap(),
PoolReturner::none(),
);
let resp = Response::do_from_stream(
stream,
Unit::new(
&agent,
"GET",
&"https://example.com/".parse().unwrap(),
vec![],
&Payload::Empty.into_read(),
None,
),
)
.unwrap();
let body = resp.into_string().unwrap();
assert_eq!(body, "hi\n");
}
} }