Skip to content

Commit b7c3712

Browse files
authored
Use decompression from tower-http (#2840)
Closes #2575
1 parent 74e6f84 commit b7c3712

File tree

8 files changed

+121
-812
lines changed

8 files changed

+121
-812
lines changed

Cargo.toml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ charset = ["dep:encoding_rs", "dep:mime"]
6464

6565
cookies = ["dep:cookie_crate", "dep:cookie_store"]
6666

67-
gzip = ["dep:async-compression", "async-compression?/gzip", "dep:futures-util", "dep:tokio-util"]
67+
gzip = ["tower-http/decompression-gzip"]
6868

69-
brotli = ["dep:async-compression", "async-compression?/brotli", "dep:futures-util", "dep:tokio-util"]
69+
brotli = ["tower-http/decompression-br"]
7070

71-
zstd = ["dep:async-compression", "async-compression?/zstd", "dep:futures-util", "dep:tokio-util"]
71+
zstd = ["tower-http/decompression-zstd"]
7272

73-
deflate = ["dep:async-compression", "async-compression?/zlib", "dep:futures-util", "dep:tokio-util"]
73+
deflate = ["tower-http/decompression-deflate"]
7474

7575
json = ["dep:serde_json"]
7676

@@ -135,7 +135,7 @@ percent-encoding = "2.3"
135135
tokio = { version = "1.0", default-features = false, features = ["net", "time"] }
136136
tower = { version = "0.5.2", default-features = false, features = ["retry", "timeout", "util"] }
137137
tower-service = "0.3"
138-
tower-http = { version = "0.6.5", default-features = false, features = ["follow-redirect"] }
138+
tower-http = { version = "0.6.8", default-features = false, features = ["follow-redirect"] }
139139
pin-project-lite = "0.2.11"
140140

141141
# Optional deps...
@@ -159,7 +159,6 @@ cookie_crate = { version = "0.18.0", package = "cookie", optional = true }
159159
cookie_store = { version = "0.21.0", optional = true }
160160

161161
## compression
162-
async-compression = { version = "0.4.0", default-features = false, features = ["tokio"], optional = true }
163162
tokio-util = { version = "0.7.9", default-features = false, features = ["codec", "io"], optional = true }
164163

165164
## hickory-dns

src/async_impl/body.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pin_project! {
4747
}
4848

4949
/// Converts any `impl Body` into a `impl Stream` of just its DATA frames.
50-
#[cfg(any(feature = "stream", feature = "multipart",))]
50+
#[cfg(any(feature = "stream", feature = "multipart", feature = "blocking"))]
5151
pub(crate) struct DataStream<B>(pub(crate) B);
5252

5353
impl Body {
@@ -161,7 +161,7 @@ impl Body {
161161
}
162162
}
163163

164-
#[cfg(feature = "multipart")]
164+
#[cfg(any(feature = "multipart", feature = "blocking"))]
165165
pub(crate) fn into_stream(self) -> DataStream<Body> {
166166
DataStream(self)
167167
}
@@ -423,7 +423,7 @@ where
423423

424424
// ===== impl DataStream =====
425425

426-
#[cfg(any(feature = "stream", feature = "multipart",))]
426+
#[cfg(any(feature = "stream", feature = "multipart", feature = "blocking",))]
427427
impl<B> futures_core::Stream for DataStream<B>
428428
where
429429
B: HttpBody<Data = Bytes> + Unpin,

src/async_impl/client.rs

Lines changed: 93 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use std::time::Duration;
99
use std::{collections::HashMap, convert::TryInto, net::SocketAddr};
1010
use std::{fmt, str};
1111

12-
use super::decoder::Accepts;
1312
use super::request::{Request, RequestBuilder};
1413
use super::response::Response;
1514
use super::Body;
@@ -45,9 +44,7 @@ use crate::Certificate;
4544
use crate::Identity;
4645
use crate::{IntoUrl, Method, Proxy, Url};
4746

48-
use http::header::{
49-
Entry, HeaderMap, HeaderValue, ACCEPT, ACCEPT_ENCODING, PROXY_AUTHORIZATION, RANGE, USER_AGENT,
50-
};
47+
use http::header::{Entry, HeaderMap, HeaderValue, ACCEPT, PROXY_AUTHORIZATION, USER_AGENT};
5148
use http::uri::Scheme;
5249
use http::Uri;
5350
use hyper_util::client::legacy::connect::HttpConnector;
@@ -61,6 +58,13 @@ use quinn::VarInt;
6158
use tokio::time::Sleep;
6259
use tower::util::BoxCloneSyncServiceLayer;
6360
use tower::{Layer, Service};
61+
#[cfg(any(
62+
feature = "gzip",
63+
feature = "brotli",
64+
feature = "zstd",
65+
feature = "deflate"
66+
))]
67+
use tower_http::decompression::Decompression;
6468
use tower_http::follow_redirect::FollowRedirect;
6569

6670
/// An asynchronous `Client` to make Requests with.
@@ -103,6 +107,33 @@ enum HttpVersionPref {
103107
All,
104108
}
105109

110+
#[derive(Clone, Copy, Debug)]
111+
struct Accepts {
112+
#[cfg(feature = "gzip")]
113+
gzip: bool,
114+
#[cfg(feature = "brotli")]
115+
brotli: bool,
116+
#[cfg(feature = "zstd")]
117+
zstd: bool,
118+
#[cfg(feature = "deflate")]
119+
deflate: bool,
120+
}
121+
122+
impl Default for Accepts {
123+
fn default() -> Accepts {
124+
Accepts {
125+
#[cfg(feature = "gzip")]
126+
gzip: true,
127+
#[cfg(feature = "brotli")]
128+
brotli: true,
129+
#[cfg(feature = "zstd")]
130+
zstd: true,
131+
#[cfg(feature = "deflate")]
132+
deflate: true,
133+
}
134+
}
135+
}
136+
106137
#[derive(Clone)]
107138
struct HyperService {
108139
hyper: HyperClient,
@@ -985,6 +1016,21 @@ impl ClientBuilder {
9851016
#[cfg(feature = "cookies")]
9861017
let svc = CookieService::new(svc, config.cookie_store.clone());
9871018
let hyper = FollowRedirect::with_policy(svc, redirect_policy.clone());
1019+
#[cfg(any(
1020+
feature = "gzip",
1021+
feature = "brotli",
1022+
feature = "zstd",
1023+
feature = "deflate"
1024+
))]
1025+
let hyper = Decompression::new(hyper);
1026+
#[cfg(feature = "gzip")]
1027+
let hyper = hyper.gzip(config.accepts.gzip);
1028+
#[cfg(feature = "brotli")]
1029+
let hyper = hyper.br(config.accepts.brotli);
1030+
#[cfg(feature = "zstd")]
1031+
let hyper = hyper.zstd(config.accepts.zstd);
1032+
#[cfg(feature = "deflate")]
1033+
let hyper = hyper.deflate(config.accepts.deflate);
9881034

9891035
Ok(Client {
9901036
inner: Arc::new(ClientRef {
@@ -1000,7 +1046,23 @@ impl ClientBuilder {
10001046
let svc = tower::retry::Retry::new(retry_policy, h3_service);
10011047
#[cfg(feature = "cookies")]
10021048
let svc = CookieService::new(svc, config.cookie_store);
1003-
Some(FollowRedirect::with_policy(svc, redirect_policy))
1049+
let svc = FollowRedirect::with_policy(svc, redirect_policy);
1050+
#[cfg(any(
1051+
feature = "gzip",
1052+
feature = "brotli",
1053+
feature = "zstd",
1054+
feature = "deflate"
1055+
))]
1056+
let svc = Decompression::new(svc);
1057+
#[cfg(feature = "gzip")]
1058+
let svc = svc.gzip(config.accepts.gzip);
1059+
#[cfg(feature = "brotli")]
1060+
let svc = svc.br(config.accepts.brotli);
1061+
#[cfg(feature = "zstd")]
1062+
let svc = svc.zstd(config.accepts.zstd);
1063+
#[cfg(feature = "deflate")]
1064+
let svc = svc.deflate(config.accepts.deflate);
1065+
Some(svc)
10041066
}
10051067
None => None,
10061068
},
@@ -2493,14 +2555,6 @@ impl Client {
24932555
}
24942556
}
24952557

2496-
let accept_encoding = self.inner.accepts.as_str();
2497-
2498-
if let Some(accept_encoding) = accept_encoding {
2499-
if !headers.contains_key(ACCEPT_ENCODING) && !headers.contains_key(RANGE) {
2500-
headers.insert(ACCEPT_ENCODING, HeaderValue::from_static(accept_encoding));
2501-
}
2502-
}
2503-
25042558
let uri = match try_uri(&url) {
25052559
Ok(uri) => uri,
25062560
_ => return Pending::new_err(error::url_invalid_uri(url)),
@@ -2785,12 +2839,32 @@ impl Config {
27852839
}
27862840

27872841
#[cfg(not(feature = "cookies"))]
2788-
type LayeredService<T> =
2789-
FollowRedirect<tower::retry::Retry<crate::retry::Policy, T>, TowerRedirectPolicy>;
2842+
type MaybeCookieService<T> = T;
2843+
27902844
#[cfg(feature = "cookies")]
2791-
type LayeredService<T> = FollowRedirect<
2792-
CookieService<tower::retry::Retry<crate::retry::Policy, T>>,
2793-
TowerRedirectPolicy,
2845+
type MaybeCookieService<T> = CookieService<T>;
2846+
2847+
#[cfg(not(any(
2848+
feature = "gzip",
2849+
feature = "brotli",
2850+
feature = "zstd",
2851+
feature = "deflate"
2852+
)))]
2853+
type MaybeDecompression<T> = T;
2854+
2855+
#[cfg(any(
2856+
feature = "gzip",
2857+
feature = "brotli",
2858+
feature = "zstd",
2859+
feature = "deflate"
2860+
))]
2861+
type MaybeDecompression<T> = Decompression<T>;
2862+
2863+
type LayeredService<T> = MaybeDecompression<
2864+
FollowRedirect<
2865+
MaybeCookieService<tower::retry::Retry<crate::retry::Policy, T>>,
2866+
TowerRedirectPolicy,
2867+
>,
27942868
>;
27952869
type LayeredFuture<T> = <LayeredService<T> as Service<http::Request<Body>>>::Future;
27962870

@@ -2956,7 +3030,7 @@ impl Future for PendingRequest {
29563030
Err(e) => {
29573031
return Poll::Ready(Err(crate::error::request(e).with_url(self.url.clone())));
29583032
}
2959-
Ok(res) => res,
3033+
Ok(res) => res.map(super::body::boxed),
29603034
},
29613035
};
29623036

@@ -2973,7 +3047,6 @@ impl Future for PendingRequest {
29733047
let res = Response::new(
29743048
res,
29753049
self.url.clone(),
2976-
self.client.accepts,
29773050
self.total_timeout.take(),
29783051
self.read_timeout,
29793052
);

0 commit comments

Comments
 (0)