wreq-rb 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.lock +257 -102
- data/ext/wreq_rb/Cargo.toml +4 -4
- data/ext/wreq_rb/src/client.rs +1 -1
- data/lib/wreq-rb/version.rb +1 -1
- data/patches/0001-add-transfer-size-tracking.patch +11 -15
- data/vendor/wreq/Cargo.toml +9 -8
- data/vendor/wreq/README.md +5 -5
- data/vendor/wreq/bench/support/bench.rs +6 -2
- data/vendor/wreq/bench/support/client.rs +88 -1
- data/vendor/wreq/bench/support/exec.rs +0 -0
- data/vendor/wreq/bench/support/rt.rs +34 -0
- data/vendor/wreq/bench/support/server.rs +1 -1
- data/vendor/wreq/bench/support.rs +1 -15
- data/vendor/wreq/examples/cert_store.rs +13 -13
- data/vendor/wreq/examples/request_with_emulate.rs +1 -1
- data/vendor/wreq/examples/tcp_linger.rs +22 -0
- data/vendor/wreq/src/client/layer/client/pool.rs +17 -17
- data/vendor/wreq/src/client/layer/client.rs +2 -0
- data/vendor/wreq/src/client/layer/decoder.rs +71 -17
- data/vendor/wreq/src/client/layer/redirect/future.rs +49 -63
- data/vendor/wreq/src/client/layer/redirect/policy.rs +2 -26
- data/vendor/wreq/src/client/layer/redirect.rs +48 -60
- data/vendor/wreq/src/client/layer/retry.rs +12 -15
- data/vendor/wreq/src/client/layer/timeout/body.rs +27 -21
- data/vendor/wreq/src/client/layer/timeout/future.rs +33 -58
- data/vendor/wreq/src/client/layer/timeout.rs +8 -14
- data/vendor/wreq/src/client/request.rs +4 -0
- data/vendor/wreq/src/client.rs +53 -31
- data/vendor/wreq/src/conn/connector.rs +99 -129
- data/vendor/wreq/src/conn/http.rs +25 -18
- data/vendor/wreq/src/conn/net/tcp.rs +601 -107
- data/vendor/wreq/src/conn/proxy/socks.rs +6 -6
- data/vendor/wreq/src/conn/timeout.rs +166 -0
- data/vendor/wreq/src/conn.rs +5 -4
- data/vendor/wreq/src/cookie/jar.rs +1225 -0
- data/vendor/wreq/src/cookie/store.rs +321 -0
- data/vendor/wreq/src/cookie.rs +108 -612
- data/vendor/wreq/src/dns/resolve.rs +8 -2
- data/vendor/wreq/src/dns.rs +4 -4
- data/vendor/wreq/src/error.rs +53 -20
- data/vendor/wreq/src/lib.rs +1 -0
- data/vendor/wreq/src/proxy/matcher.rs +26 -12
- data/vendor/wreq/src/proxy/win.rs +39 -9
- data/vendor/wreq/src/redirect.rs +515 -100
- data/vendor/wreq/src/tls/conn.rs +3 -11
- data/vendor/wreq/src/tls/session.rs +7 -8
- data/vendor/wreq/src/tls/trust/store.rs +4 -4
- data/vendor/wreq/src/util.rs +23 -0
- data/vendor/wreq/tests/badssl.rs +72 -7
- data/vendor/wreq/tests/brotli.rs +1 -1
- data/vendor/wreq/tests/client.rs +24 -0
- data/vendor/wreq/tests/connector_layers.rs +8 -4
- data/vendor/wreq/tests/cookie.rs +59 -0
- data/vendor/wreq/tests/deflate.rs +1 -1
- data/vendor/wreq/tests/gzip.rs +53 -1
- data/vendor/wreq/tests/layers.rs +8 -4
- data/vendor/wreq/tests/redirect.rs +180 -97
- data/vendor/wreq/tests/timeouts.rs +47 -12
- data/vendor/wreq/tests/zstd.rs +1 -1
- metadata +7 -1
|
@@ -57,33 +57,33 @@ pin_project! {
|
|
|
57
57
|
/// The timeout resets after every successful read. If a single read
|
|
58
58
|
/// takes longer than the specified duration, an error is returned.
|
|
59
59
|
pub struct ReadTimeoutBody<B> {
|
|
60
|
-
timeout: Duration,
|
|
61
|
-
#[pin]
|
|
62
|
-
sleep: Option<Pin<Box<dyn Sleep>>>,
|
|
63
60
|
#[pin]
|
|
64
61
|
body: B,
|
|
62
|
+
#[pin]
|
|
63
|
+
sleep: Option<Pin<Box<dyn Sleep>>>,
|
|
64
|
+
timeout: Duration,
|
|
65
65
|
timer: Timer,
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
// ===== impl TimeoutBody =====
|
|
70
|
+
|
|
70
71
|
impl<B> TimeoutBody<B> {
|
|
71
|
-
///
|
|
72
|
+
/// Wraps a body with the active total timeout and an optional read timeout.
|
|
72
73
|
pub fn new(
|
|
74
|
+
body: B,
|
|
73
75
|
timer: Timer,
|
|
74
|
-
deadline: Option<Duration>,
|
|
75
76
|
read_timeout: Option<Duration>,
|
|
76
|
-
|
|
77
|
+
total_timeout: Option<Pin<Box<dyn Sleep>>>,
|
|
77
78
|
) -> Self {
|
|
78
|
-
|
|
79
|
-
match (deadline, read_timeout) {
|
|
79
|
+
match (total_timeout, read_timeout) {
|
|
80
80
|
(Some(total_timeout), Some(read_timeout)) => TimeoutBody::CombinedTimeout {
|
|
81
81
|
body: TotalTimeoutBody {
|
|
82
82
|
timeout: total_timeout,
|
|
83
83
|
body: ReadTimeoutBody {
|
|
84
|
-
timeout: read_timeout,
|
|
85
|
-
sleep: None,
|
|
86
84
|
body,
|
|
85
|
+
sleep: None,
|
|
86
|
+
timeout: read_timeout,
|
|
87
87
|
timer,
|
|
88
88
|
},
|
|
89
89
|
},
|
|
@@ -160,7 +160,8 @@ where
|
|
|
160
160
|
)
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
//
|
|
163
|
+
// ===== impl TotalTimeoutBody =====
|
|
164
|
+
|
|
164
165
|
impl<B> Body for TotalTimeoutBody<B>
|
|
165
166
|
where
|
|
166
167
|
B: Body,
|
|
@@ -191,7 +192,8 @@ where
|
|
|
191
192
|
}
|
|
192
193
|
}
|
|
193
194
|
|
|
194
|
-
|
|
195
|
+
// ===== impl ReadTimeoutBody =====
|
|
196
|
+
|
|
195
197
|
impl<B> Body for ReadTimeoutBody<B>
|
|
196
198
|
where
|
|
197
199
|
B: Body,
|
|
@@ -206,23 +208,27 @@ where
|
|
|
206
208
|
) -> Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>> {
|
|
207
209
|
let mut this = self.project();
|
|
208
210
|
|
|
209
|
-
//
|
|
211
|
+
// Start the timeout on the first poll.
|
|
210
212
|
if this.sleep.is_none() {
|
|
211
|
-
this.
|
|
213
|
+
let deadline = this.timer.now() + *this.timeout;
|
|
214
|
+
this.sleep.set(Some(this.timer.sleep_until(deadline)));
|
|
212
215
|
}
|
|
213
216
|
|
|
214
217
|
// Error if the timeout has expired.
|
|
215
|
-
if let Some(sleep) = this.sleep.as_mut().as_pin_mut()
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
218
|
+
if let Some(sleep) = this.sleep.as_mut().as_pin_mut()
|
|
219
|
+
&& sleep.poll(cx).is_ready()
|
|
220
|
+
{
|
|
221
|
+
return Poll::Ready(Some(Err(Error::body(TimedOut).into())));
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
// Poll the actual body
|
|
222
225
|
match ready!(this.body.poll_frame(cx)) {
|
|
223
226
|
Some(Ok(frame)) => {
|
|
224
|
-
//
|
|
225
|
-
this.sleep.
|
|
227
|
+
// Reuse the sleep to avoid allocating and registering a new timer for every frame.
|
|
228
|
+
if let Some(sleep) = this.sleep.as_mut().as_pin_mut() {
|
|
229
|
+
let deadline = this.timer.now() + *this.timeout;
|
|
230
|
+
this.timer.reset(sleep.get_mut(), deadline);
|
|
231
|
+
}
|
|
226
232
|
Poll::Ready(Some(Ok(frame)))
|
|
227
233
|
}
|
|
228
234
|
Some(Err(err)) => Poll::Ready(Some(Err(err.into()))),
|
|
@@ -16,80 +16,55 @@ use crate::{
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
pin_project! {
|
|
19
|
-
///
|
|
19
|
+
/// Waits for response headers, then moves the total timeout into the response body.
|
|
20
20
|
pub struct ResponseFuture<Fut> {
|
|
21
21
|
#[pin]
|
|
22
|
-
pub(
|
|
23
|
-
pub(
|
|
24
|
-
pub(
|
|
22
|
+
pub(super) fut: Fut,
|
|
23
|
+
pub(super) timer: Timer,
|
|
24
|
+
pub(super) read_timeout: Option<Duration>,
|
|
25
|
+
pub(super) read_timeout_fut: Option<Pin<Box<dyn Sleep>>>,
|
|
26
|
+
pub(super) total_timeout_fut: Option<Pin<Box<dyn Sleep>>>,
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
impl<
|
|
30
|
+
impl<Fut, ResBody, E> Future for ResponseFuture<Fut>
|
|
29
31
|
where
|
|
30
|
-
|
|
32
|
+
Fut: Future<Output = Result<Response<ResBody>, E>>,
|
|
31
33
|
E: Into<BoxError>,
|
|
32
34
|
{
|
|
33
|
-
type Output = Result<
|
|
35
|
+
type Output = Result<Response<TimeoutBody<ResBody>>, BoxError>;
|
|
34
36
|
|
|
35
37
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
36
38
|
let this = self.project();
|
|
37
39
|
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// Helper closure for polling a timeout and returning a TimedOut error
|
|
45
|
-
let mut check_timeout = |sleep: Option<&mut Pin<Box<dyn Sleep>>>| {
|
|
46
|
-
if let Some(sleep) = sleep {
|
|
47
|
-
if sleep.as_mut().poll(cx).is_ready() {
|
|
48
|
-
return Some(Poll::Ready(Err(Error::request(TimedOut).into())));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
None
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// Check total timeout first
|
|
55
|
-
if let Some(poll) = check_timeout(this.total_timeout.as_mut()) {
|
|
56
|
-
return poll;
|
|
40
|
+
// The total timer covers response headers and body. Poll it first so an
|
|
41
|
+
// expired timeout wins, then move it into `TimeoutBody` below.
|
|
42
|
+
if let Some(timeout) = this.total_timeout_fut.as_mut()
|
|
43
|
+
&& timeout.as_mut().poll(cx).is_ready()
|
|
44
|
+
{
|
|
45
|
+
return Poll::Ready(Err(Error::request(TimedOut).into()));
|
|
57
46
|
}
|
|
58
47
|
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
// Before headers arrive, the read timer limits that wait. The body starts
|
|
49
|
+
// and resets its own read timer after each successful frame.
|
|
50
|
+
if let Some(timeout) = this.read_timeout_fut.as_mut()
|
|
51
|
+
&& timeout.as_mut().poll(cx).is_ready()
|
|
52
|
+
{
|
|
53
|
+
return Poll::Ready(Err(Error::request(TimedOut).into()));
|
|
62
54
|
}
|
|
63
55
|
|
|
64
|
-
Poll
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
// Poll the request after both timers so every pending future registers the
|
|
57
|
+
// current waker before `ready!` returns.
|
|
58
|
+
let response = ready!(this.fut.poll(cx)).map_err(Into::into)?;
|
|
67
59
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
impl<Fut, ResBody, E> Future for ResponseBodyTimeoutFuture<Fut>
|
|
81
|
-
where
|
|
82
|
-
Fut: Future<Output = Result<Response<ResBody>, E>>,
|
|
83
|
-
{
|
|
84
|
-
type Output = Result<Response<TimeoutBody<ResBody>>, E>;
|
|
85
|
-
|
|
86
|
-
#[inline(always)]
|
|
87
|
-
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
88
|
-
let timer = self.timer.clone();
|
|
89
|
-
let total_timeout = self.total_timeout;
|
|
90
|
-
let read_timeout = self.read_timeout;
|
|
91
|
-
let res = ready!(self.project().fut.poll(cx))?
|
|
92
|
-
.map(|body| TimeoutBody::new(timer, total_timeout, read_timeout, body));
|
|
93
|
-
Poll::Ready(Ok(res))
|
|
60
|
+
// Moving the running total timer preserves the original deadline.
|
|
61
|
+
Poll::Ready(Ok(response.map(|body| {
|
|
62
|
+
TimeoutBody::new(
|
|
63
|
+
body,
|
|
64
|
+
this.timer.clone(),
|
|
65
|
+
*this.read_timeout,
|
|
66
|
+
this.total_timeout_fut.take(),
|
|
67
|
+
)
|
|
68
|
+
})))
|
|
94
69
|
}
|
|
95
70
|
}
|
|
@@ -12,17 +12,14 @@ use http::{Request, Response};
|
|
|
12
12
|
use tower::{BoxError, Layer, Service};
|
|
13
13
|
use wreq_proto::rt::Timer as _;
|
|
14
14
|
|
|
15
|
-
use self::{
|
|
16
|
-
body::TimeoutBody,
|
|
17
|
-
future::{ResponseBodyTimeoutFuture, ResponseFuture},
|
|
18
|
-
};
|
|
15
|
+
use self::{body::TimeoutBody, future::ResponseFuture};
|
|
19
16
|
use crate::{config::RequestConfig, rt::Timer};
|
|
20
17
|
|
|
21
18
|
/// Options for configuring timeouts.
|
|
22
19
|
#[derive(Clone, Copy, Default)]
|
|
23
20
|
pub struct TimeoutOptions {
|
|
24
|
-
total_timeout: Option<Duration>,
|
|
25
21
|
read_timeout: Option<Duration>,
|
|
22
|
+
total_timeout: Option<Duration>,
|
|
26
23
|
}
|
|
27
24
|
|
|
28
25
|
impl TimeoutOptions {
|
|
@@ -88,7 +85,7 @@ where
|
|
|
88
85
|
{
|
|
89
86
|
type Response = Response<TimeoutBody<ResBody>>;
|
|
90
87
|
type Error = BoxError;
|
|
91
|
-
type Future = ResponseFuture<
|
|
88
|
+
type Future = ResponseFuture<S::Future>;
|
|
92
89
|
|
|
93
90
|
#[inline(always)]
|
|
94
91
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
@@ -99,14 +96,11 @@ where
|
|
|
99
96
|
fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
|
|
100
97
|
let (total_timeout, read_timeout) = fetch_timeout_options(&self.timeout, req.extensions());
|
|
101
98
|
ResponseFuture {
|
|
102
|
-
fut:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
},
|
|
108
|
-
total_timeout: total_timeout.map(|timeout| self.timer.sleep(timeout)),
|
|
109
|
-
read_timeout: read_timeout.map(|timeout| self.timer.sleep(timeout)),
|
|
99
|
+
fut: self.inner.call(req),
|
|
100
|
+
timer: self.timer.clone(),
|
|
101
|
+
read_timeout,
|
|
102
|
+
read_timeout_fut: read_timeout.map(|timeout| self.timer.sleep(timeout)),
|
|
103
|
+
total_timeout_fut: total_timeout.map(|timeout| self.timer.sleep(timeout)),
|
|
110
104
|
}
|
|
111
105
|
}
|
|
112
106
|
}
|
|
@@ -473,6 +473,10 @@ impl RequestBuilder {
|
|
|
473
473
|
|
|
474
474
|
/// Send a JSON body.
|
|
475
475
|
///
|
|
476
|
+
/// Serializes the value as JSON and sets the resulting bytes as the request body.
|
|
477
|
+
///
|
|
478
|
+
/// Sets `Content-Type` to `application/json` unless it is already set.
|
|
479
|
+
///
|
|
476
480
|
/// # Optional
|
|
477
481
|
///
|
|
478
482
|
/// This requires the optional `json` feature enabled.
|
data/vendor/wreq/src/client.rs
CHANGED
|
@@ -60,8 +60,10 @@ use crate::dns::hickory::HickoryDnsResolver;
|
|
|
60
60
|
use crate::{
|
|
61
61
|
IntoUri, Method, Proxy,
|
|
62
62
|
conn::{
|
|
63
|
-
BoxedConnectorLayer,
|
|
64
|
-
|
|
63
|
+
BoxedConnectorLayer, BoxedTransportConnector, Conn, Unnameable,
|
|
64
|
+
connector::{Connector, ConnectorBuilder},
|
|
65
|
+
http::HttpConnect,
|
|
66
|
+
net::SocketBindOptions,
|
|
65
67
|
},
|
|
66
68
|
dns::{DnsResolverWithOverrides, DynResolver, GaiResolver, IntoResolve, Resolve},
|
|
67
69
|
error::{self, Error},
|
|
@@ -114,9 +116,7 @@ type MaybeDecompressionBody<T> = tower_http::decompression::DecompressionBody<T>
|
|
|
114
116
|
|
|
115
117
|
type ClientService = Timeout<
|
|
116
118
|
ConfigService<
|
|
117
|
-
MaybeDecompression<
|
|
118
|
-
Retry<RetryPolicy, FollowRedirect<HttpClient<Connector, Body>, FollowRedirectPolicy>>,
|
|
119
|
-
>,
|
|
119
|
+
MaybeDecompression<Retry<RetryPolicy, FollowRedirect<HttpClient<Connector, Body>>>>,
|
|
120
120
|
>,
|
|
121
121
|
>;
|
|
122
122
|
|
|
@@ -185,6 +185,7 @@ struct Config {
|
|
|
185
185
|
pool_max_size: Option<NonZeroUsize>,
|
|
186
186
|
tcp_nodelay: bool,
|
|
187
187
|
tcp_reuse_address: bool,
|
|
188
|
+
tcp_linger: Option<Duration>,
|
|
188
189
|
tcp_keepalive: Option<Duration>,
|
|
189
190
|
tcp_keepalive_interval: Option<Duration>,
|
|
190
191
|
tcp_keepalive_retries: Option<u32>,
|
|
@@ -276,6 +277,7 @@ impl Client {
|
|
|
276
277
|
tcp_user_timeout: Some(Duration::from_secs(30)),
|
|
277
278
|
tcp_nodelay: true,
|
|
278
279
|
tcp_reuse_address: false,
|
|
280
|
+
tcp_linger: None,
|
|
279
281
|
tcp_send_buffer_size: None,
|
|
280
282
|
tcp_recv_buffer_size: None,
|
|
281
283
|
tcp_happy_eyeballs_timeout: Some(Duration::from_millis(300)),
|
|
@@ -502,7 +504,8 @@ impl ClientBuilder {
|
|
|
502
504
|
DynResolver::new(resolver)
|
|
503
505
|
};
|
|
504
506
|
|
|
505
|
-
let connector =
|
|
507
|
+
let connector = ConnectorBuilder::new(config.proxies, resolver)
|
|
508
|
+
.timer(config.timer.clone())
|
|
506
509
|
.timeout(config.connect_timeout)
|
|
507
510
|
.tls_info(config.tls_info)
|
|
508
511
|
.tcp_nodelay(config.tcp_nodelay)
|
|
@@ -529,6 +532,7 @@ impl ClientBuilder {
|
|
|
529
532
|
http.set_keepalive_interval(config.tcp_keepalive_interval);
|
|
530
533
|
http.set_keepalive_retries(config.tcp_keepalive_retries);
|
|
531
534
|
http.set_reuse_address(config.tcp_reuse_address);
|
|
535
|
+
http.set_linger(config.tcp_linger);
|
|
532
536
|
http.set_connect_timeout(config.connect_timeout);
|
|
533
537
|
http.set_nodelay(config.tcp_nodelay);
|
|
534
538
|
http.set_send_buffer_size(config.tcp_send_buffer_size);
|
|
@@ -788,9 +792,8 @@ impl ClientBuilder {
|
|
|
788
792
|
///
|
|
789
793
|
/// If auto gzip decompression is turned on:
|
|
790
794
|
///
|
|
791
|
-
/// -
|
|
792
|
-
/// `
|
|
793
|
-
/// The request body is **not** automatically compressed.
|
|
795
|
+
/// - Requests without `Accept-Encoding` advertise `gzip`. Range requests use `Accept-Encoding:
|
|
796
|
+
/// identity` instead. The request body is **not** automatically compressed.
|
|
794
797
|
/// - When receiving a response, if its headers contain a `Content-Encoding` value of `gzip`,
|
|
795
798
|
/// both `Content-Encoding` and `Content-Length` are removed from the headers' set. The
|
|
796
799
|
/// response body is automatically decompressed.
|
|
@@ -812,9 +815,8 @@ impl ClientBuilder {
|
|
|
812
815
|
///
|
|
813
816
|
/// If auto brotli decompression is turned on:
|
|
814
817
|
///
|
|
815
|
-
/// -
|
|
816
|
-
/// `
|
|
817
|
-
/// request body is **not** automatically compressed.
|
|
818
|
+
/// - Requests without `Accept-Encoding` advertise `br`. Range requests use `Accept-Encoding:
|
|
819
|
+
/// identity` instead. The request body is **not** automatically compressed.
|
|
818
820
|
/// - When receiving a response, if its headers contain a `Content-Encoding` value of `br`, both
|
|
819
821
|
/// `Content-Encoding` and `Content-Length` are removed from the headers' set. The response
|
|
820
822
|
/// body is automatically decompressed.
|
|
@@ -836,9 +838,8 @@ impl ClientBuilder {
|
|
|
836
838
|
///
|
|
837
839
|
/// If auto zstd decompression is turned on:
|
|
838
840
|
///
|
|
839
|
-
/// -
|
|
840
|
-
/// `
|
|
841
|
-
/// The request body is **not** automatically compressed.
|
|
841
|
+
/// - Requests without `Accept-Encoding` advertise `zstd`. Range requests use `Accept-Encoding:
|
|
842
|
+
/// identity` instead. The request body is **not** automatically compressed.
|
|
842
843
|
/// - When receiving a response, if its headers contain a `Content-Encoding` value of `zstd`,
|
|
843
844
|
/// both `Content-Encoding` and `Content-Length` are removed from the headers' set. The
|
|
844
845
|
/// response body is automatically decompressed.
|
|
@@ -860,9 +861,8 @@ impl ClientBuilder {
|
|
|
860
861
|
///
|
|
861
862
|
/// If auto deflate decompression is turned on:
|
|
862
863
|
///
|
|
863
|
-
/// -
|
|
864
|
-
/// `Accept-Encoding
|
|
865
|
-
/// `deflate`. The request body is **not** automatically compressed.
|
|
864
|
+
/// - Requests without `Accept-Encoding` advertise `deflate`. Range requests use
|
|
865
|
+
/// `Accept-Encoding: identity` instead. The request body is **not** automatically compressed.
|
|
866
866
|
/// - When receiving a response, if it's headers contain a `Content-Encoding` value that equals
|
|
867
867
|
/// to `deflate`, both values `Content-Encoding` and `Content-Length` are removed from the
|
|
868
868
|
/// headers' set. The response body is automatically decompressed.
|
|
@@ -963,7 +963,11 @@ impl ClientBuilder {
|
|
|
963
963
|
self
|
|
964
964
|
}
|
|
965
965
|
|
|
966
|
-
/// Enable or disable automatic
|
|
966
|
+
/// Enable or disable automatic `Referer` management during redirects.
|
|
967
|
+
///
|
|
968
|
+
/// When enabled, redirect responses can control how an existing `Referer`
|
|
969
|
+
/// is forwarded through `Referrer-Policy`. No header is added when the
|
|
970
|
+
/// request has none.
|
|
967
971
|
///
|
|
968
972
|
/// Default is `true`.
|
|
969
973
|
#[inline]
|
|
@@ -1041,12 +1045,10 @@ impl ClientBuilder {
|
|
|
1041
1045
|
|
|
1042
1046
|
/// Set a timeout for only the connect phase of a `Client`.
|
|
1043
1047
|
///
|
|
1044
|
-
///
|
|
1045
|
-
///
|
|
1046
|
-
/// # Note
|
|
1048
|
+
/// The timeout covers DNS resolution, the complete TCP address race,
|
|
1049
|
+
/// proxy tunneling, and the TLS handshake.
|
|
1047
1050
|
///
|
|
1048
|
-
///
|
|
1049
|
-
/// a tokio timer enabled.
|
|
1051
|
+
/// Default is `None`.
|
|
1050
1052
|
#[inline]
|
|
1051
1053
|
pub fn connect_timeout(mut self, timeout: Duration) -> ClientBuilder {
|
|
1052
1054
|
self.config.connect_timeout = Some(timeout);
|
|
@@ -1220,6 +1222,27 @@ impl ClientBuilder {
|
|
|
1220
1222
|
self
|
|
1221
1223
|
}
|
|
1222
1224
|
|
|
1225
|
+
/// Set that all sockets have `SO_LINGER` set with the supplied duration.
|
|
1226
|
+
///
|
|
1227
|
+
/// This option controls how long the socket lingers on close while data
|
|
1228
|
+
/// remains unsent. A duration of zero aborts the connection on close: unsent
|
|
1229
|
+
/// data is discarded, the connection is reset (`RST`) rather than going
|
|
1230
|
+
/// through the normal `FIN` termination sequence, and the socket does not
|
|
1231
|
+
/// enter `TIME_WAIT`.
|
|
1232
|
+
///
|
|
1233
|
+
/// If `None`, the option will not be set and the operating system default
|
|
1234
|
+
/// applies.
|
|
1235
|
+
///
|
|
1236
|
+
/// Default is `None`.
|
|
1237
|
+
#[inline]
|
|
1238
|
+
pub fn tcp_linger<D>(mut self, val: D) -> ClientBuilder
|
|
1239
|
+
where
|
|
1240
|
+
D: Into<Option<Duration>>,
|
|
1241
|
+
{
|
|
1242
|
+
self.config.tcp_linger = val.into();
|
|
1243
|
+
self
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1223
1246
|
/// Sets the size of the TCP send buffer on this client socket.
|
|
1224
1247
|
///
|
|
1225
1248
|
/// On most operating systems, this sets the `SO_SNDBUF` socket option.
|
|
@@ -1244,18 +1267,17 @@ impl ClientBuilder {
|
|
|
1244
1267
|
self
|
|
1245
1268
|
}
|
|
1246
1269
|
|
|
1247
|
-
/// Set
|
|
1270
|
+
/// Set the delay between connection attempts for
|
|
1271
|
+
/// [RFC 8305 (Happy Eyeballs v2)][RFC 8305].
|
|
1248
1272
|
///
|
|
1249
|
-
///
|
|
1250
|
-
///
|
|
1251
|
-
/// elapses, then connector will in parallel attempt connection using other
|
|
1252
|
-
/// address family.
|
|
1273
|
+
/// The first address is attempted immediately. Later addresses are started
|
|
1274
|
+
/// after this delay without waiting for the previous attempt to finish.
|
|
1253
1275
|
///
|
|
1254
1276
|
/// If `None`, parallel connection attempts are disabled.
|
|
1255
1277
|
///
|
|
1256
1278
|
/// Default is 300 milliseconds.
|
|
1257
1279
|
///
|
|
1258
|
-
/// [RFC
|
|
1280
|
+
/// [RFC 8305]: https://www.rfc-editor.org/rfc/rfc8305.html#section-5
|
|
1259
1281
|
#[inline]
|
|
1260
1282
|
pub fn tcp_happy_eyeballs_timeout<D>(mut self, val: D) -> ClientBuilder
|
|
1261
1283
|
where
|
|
@@ -1631,7 +1653,7 @@ impl ClientBuilder {
|
|
|
1631
1653
|
#[inline]
|
|
1632
1654
|
pub fn connector_layer<L>(mut self, layer: L) -> ClientBuilder
|
|
1633
1655
|
where
|
|
1634
|
-
L: Layer<
|
|
1656
|
+
L: Layer<BoxedTransportConnector> + Clone + Send + Sync + 'static,
|
|
1635
1657
|
L::Service:
|
|
1636
1658
|
Service<Unnameable, Response = Conn, Error = BoxError> + Clone + Send + Sync + 'static,
|
|
1637
1659
|
<L::Service as Service<Unnameable>>::Future: Send + 'static,
|