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
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
use std::{
|
|
2
2
|
borrow::Cow,
|
|
3
|
-
future::Future,
|
|
4
|
-
pin::Pin,
|
|
5
3
|
sync::Arc,
|
|
6
4
|
task::{Context, Poll},
|
|
7
5
|
time::Duration,
|
|
8
6
|
};
|
|
9
7
|
|
|
8
|
+
use futures_util::future::BoxFuture;
|
|
10
9
|
use tokio_btls::SslStream;
|
|
11
10
|
use tower::{
|
|
12
|
-
BoxError, Service, ServiceBuilder, ServiceExt,
|
|
13
|
-
|
|
14
|
-
util::{BoxCloneSyncService, MapRequestLayer},
|
|
11
|
+
BoxError, Layer, Service, ServiceBuilder, ServiceExt,
|
|
12
|
+
util::{BoxCloneSyncService, Either, MapRequest, MapRequestLayer},
|
|
15
13
|
};
|
|
16
14
|
|
|
17
15
|
#[cfg(unix)]
|
|
18
16
|
use super::net::UnixConnector;
|
|
19
17
|
use super::{
|
|
20
|
-
AsyncConnWithInfo, BoxedConnectorLayer,
|
|
21
|
-
TlsConn, TlsInfoFactory, Unnameable,
|
|
22
|
-
|
|
18
|
+
AsyncConnWithInfo, BoxedConnectorLayer, BoxedTransportConnector, Conn, Connection,
|
|
19
|
+
HttpConnector, TlsConn, TlsInfoFactory, Unnameable,
|
|
20
|
+
descriptor::ConnectionDescriptor,
|
|
21
|
+
http::HttpConnect,
|
|
22
|
+
net::TcpConnector,
|
|
23
|
+
proxy,
|
|
24
|
+
timeout::{Timeout, TimeoutLayer},
|
|
25
|
+
verbose::Verbose,
|
|
23
26
|
};
|
|
24
27
|
use crate::{
|
|
25
28
|
dns::DynResolver,
|
|
26
|
-
error::{ProxyConnect,
|
|
29
|
+
error::{ProxyConnect, map_timeout_to_connector_error},
|
|
27
30
|
ext::UriExt,
|
|
28
31
|
proxy::{Intercepted, Matcher as ProxyMatcher, matcher::Intercept},
|
|
32
|
+
rt::Timer,
|
|
29
33
|
tls::{
|
|
30
34
|
TlsOptions,
|
|
31
35
|
conn::{
|
|
@@ -34,41 +38,51 @@ use crate::{
|
|
|
34
38
|
},
|
|
35
39
|
};
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
///
|
|
41
|
+
/// Client-wide connection settings retained by each transport connector.
|
|
42
|
+
///
|
|
43
|
+
/// These defaults control proxy selection, socket behavior, stream instrumentation, and TLS
|
|
44
|
+
/// metadata. Settings that can vary per request remain in [`ConnectionDescriptor`] and are
|
|
45
|
+
/// applied when a connection starts.
|
|
40
46
|
#[derive(Clone)]
|
|
41
47
|
struct Config {
|
|
42
48
|
proxies: Arc<Vec<ProxyMatcher>>,
|
|
43
49
|
verbose: Verbose,
|
|
44
50
|
nodelay: bool,
|
|
45
51
|
tls_info: bool,
|
|
46
|
-
/// When there is a single timeout layer and no other layers,
|
|
47
|
-
/// we embed it directly inside our base Service::call().
|
|
48
|
-
/// This lets us avoid an extra `Box::pin` indirection layer
|
|
49
|
-
/// since `tokio::time::Timeout` is `Unpin`
|
|
50
|
-
timeout: Option<Duration>,
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
///
|
|
54
|
+
/// Assembles the transport service graph used by a client.
|
|
55
|
+
///
|
|
56
|
+
/// The builder owns DNS, TCP, TLS, and timeout configuration until [`ConnectorBuilder::build`]
|
|
57
|
+
/// places the timeout around the concrete connector and any user-provided layers.
|
|
54
58
|
pub struct ConnectorBuilder {
|
|
55
59
|
config: Config,
|
|
60
|
+
timer: Timer,
|
|
61
|
+
timeout: Option<Duration>,
|
|
56
62
|
#[cfg(feature = "socks")]
|
|
57
63
|
resolver: DynResolver,
|
|
58
64
|
http: HttpConnector,
|
|
59
65
|
builder: TlsConnectorBuilder,
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
///
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
/// Client-owned transport service selected when the connector graph is assembled.
|
|
69
|
+
///
|
|
70
|
+
/// The left branch keeps the graph concrete when no custom layers are present. The right branch
|
|
71
|
+
/// wraps the type-erased custom-layer graph so it also accepts [`ConnectionDescriptor`]. Both
|
|
72
|
+
/// branches remain with the client and create a separately timed future for each connection
|
|
73
|
+
/// attempt.
|
|
74
|
+
pub type Connector = Either<
|
|
75
|
+
Timeout<TransportConnector>,
|
|
76
|
+
MapRequest<BoxedTransportConnector, fn(ConnectionDescriptor) -> Unnameable>,
|
|
77
|
+
>;
|
|
78
|
+
|
|
79
|
+
/// Establishes the transport consumed by the HTTP protocol layer.
|
|
80
|
+
///
|
|
81
|
+
/// Each call selects the proxy path, applies request-specific socket and TLS settings, and returns
|
|
82
|
+
/// an established [`Conn`]. The service is cloned into each in-flight connection future, while its
|
|
83
|
+
/// immutable TLS builder is shared across those attempts.
|
|
70
84
|
#[derive(Clone)]
|
|
71
|
-
pub struct
|
|
85
|
+
pub struct TransportConnector {
|
|
72
86
|
config: Config,
|
|
73
87
|
#[cfg(feature = "socks")]
|
|
74
88
|
resolver: DynResolver,
|
|
@@ -80,6 +94,24 @@ pub struct ConnectorService {
|
|
|
80
94
|
// ===== impl ConnectorBuilder =====
|
|
81
95
|
|
|
82
96
|
impl ConnectorBuilder {
|
|
97
|
+
/// Creates a builder with the client's proxy and DNS configuration.
|
|
98
|
+
pub(crate) fn new(proxies: Vec<ProxyMatcher>, resolver: DynResolver) -> Self {
|
|
99
|
+
Self {
|
|
100
|
+
config: Config {
|
|
101
|
+
proxies: Arc::new(proxies),
|
|
102
|
+
verbose: Verbose::OFF,
|
|
103
|
+
nodelay: true,
|
|
104
|
+
tls_info: false,
|
|
105
|
+
},
|
|
106
|
+
timer: Timer::default(),
|
|
107
|
+
timeout: None,
|
|
108
|
+
#[cfg(feature = "socks")]
|
|
109
|
+
resolver: resolver.clone(),
|
|
110
|
+
http: HttpConnector::new(resolver, TcpConnector::new()),
|
|
111
|
+
builder: TlsConnector::builder(),
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
83
115
|
/// Set the HTTP connector to use.
|
|
84
116
|
#[inline]
|
|
85
117
|
pub fn with_http<F>(mut self, call: F) -> ConnectorBuilder
|
|
@@ -101,12 +133,16 @@ impl ConnectorBuilder {
|
|
|
101
133
|
}
|
|
102
134
|
|
|
103
135
|
/// Set the connect timeout.
|
|
104
|
-
///
|
|
105
|
-
/// If a domain resolves to multiple IP addresses, the timeout will be
|
|
106
|
-
/// evenly divided across them.
|
|
107
136
|
#[inline]
|
|
108
137
|
pub fn timeout(mut self, timeout: Option<Duration>) -> ConnectorBuilder {
|
|
109
|
-
self.
|
|
138
|
+
self.timeout = timeout;
|
|
139
|
+
self
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/// Set the timer used to drive the connect timeout.
|
|
143
|
+
#[inline]
|
|
144
|
+
pub fn timer(mut self, timer: Timer) -> ConnectorBuilder {
|
|
145
|
+
self.timer = timer;
|
|
110
146
|
self
|
|
111
147
|
}
|
|
112
148
|
|
|
@@ -137,7 +173,8 @@ impl ConnectorBuilder {
|
|
|
137
173
|
tls_options: Option<TlsOptions>,
|
|
138
174
|
layers: Vec<BoxedConnectorLayer>,
|
|
139
175
|
) -> crate::Result<Connector> {
|
|
140
|
-
let
|
|
176
|
+
let timeout = TimeoutLayer::new(self.timer, self.timeout);
|
|
177
|
+
let service = TransportConnector {
|
|
141
178
|
config: self.config,
|
|
142
179
|
#[cfg(feature = "socks")]
|
|
143
180
|
resolver: self.resolver.clone(),
|
|
@@ -150,12 +187,9 @@ impl ConnectorBuilder {
|
|
|
150
187
|
|
|
151
188
|
// we have no user-provided layers, only use concrete types
|
|
152
189
|
if layers.is_empty() {
|
|
153
|
-
return Ok(
|
|
190
|
+
return Ok(Either::Left(timeout.layer(service)));
|
|
154
191
|
}
|
|
155
192
|
|
|
156
|
-
// user-provided layers exist, the timeout will be applied as an additional layer.
|
|
157
|
-
let timeout = service.config.timeout.take();
|
|
158
|
-
|
|
159
193
|
// otherwise we have user provided layers
|
|
160
194
|
// so we need type erasure all the way through
|
|
161
195
|
// as well as mapping the unnameable type of the layers back to ConnectionDescriptor for the
|
|
@@ -169,78 +203,25 @@ impl ConnectorBuilder {
|
|
|
169
203
|
|service, layer| ServiceBuilder::new().layer(layer).service(service),
|
|
170
204
|
);
|
|
171
205
|
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
.layer(TimeoutLayer::new(timeout))
|
|
179
|
-
.service(service)
|
|
180
|
-
.map_err(map_timeout_to_connector_error);
|
|
181
|
-
|
|
182
|
-
Ok(Connector::WithLayers(BoxCloneSyncService::new(service)))
|
|
183
|
-
}
|
|
184
|
-
None => {
|
|
185
|
-
// no timeout, but still map err
|
|
186
|
-
// no named timeout layer but we still map errors since
|
|
187
|
-
// we might have user-provided timeout layer
|
|
188
|
-
let service = ServiceBuilder::new()
|
|
189
|
-
.service(service)
|
|
190
|
-
.map_err(map_timeout_to_connector_error);
|
|
191
|
-
|
|
192
|
-
Ok(Connector::WithLayers(BoxCloneSyncService::new(service)))
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// ===== impl Connector =====
|
|
199
|
-
|
|
200
|
-
impl Connector {
|
|
201
|
-
/// Creates a new [`Connector`] with the provided configuration and optional layers.
|
|
202
|
-
pub(crate) fn builder(proxies: Vec<ProxyMatcher>, resolver: DynResolver) -> ConnectorBuilder {
|
|
203
|
-
ConnectorBuilder {
|
|
204
|
-
config: Config {
|
|
205
|
-
proxies: Arc::new(proxies),
|
|
206
|
-
verbose: Verbose::OFF,
|
|
207
|
-
nodelay: true,
|
|
208
|
-
tls_info: false,
|
|
209
|
-
timeout: None,
|
|
210
|
-
},
|
|
211
|
-
#[cfg(feature = "socks")]
|
|
212
|
-
resolver: resolver.clone(),
|
|
213
|
-
http: HttpConnector::new(resolver, TcpConnector::new()),
|
|
214
|
-
builder: TlsConnector::builder(),
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
206
|
+
// Keep the built-in timeout outside user layers so it covers their work too.
|
|
207
|
+
// The final mapping also handles a tower timeout supplied by the caller.
|
|
208
|
+
let service = ServiceBuilder::new()
|
|
209
|
+
.layer(timeout)
|
|
210
|
+
.service(service)
|
|
211
|
+
.map_err(map_timeout_to_connector_error);
|
|
218
212
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
#[inline]
|
|
225
|
-
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
226
|
-
match self {
|
|
227
|
-
Connector::Simple(service) => service.poll_ready(cx),
|
|
228
|
-
Connector::WithLayers(service) => service.poll_ready(cx),
|
|
229
|
-
}
|
|
230
|
-
}
|
|
213
|
+
let service = MapRequest::new(
|
|
214
|
+
BoxCloneSyncService::new(service),
|
|
215
|
+
Unnameable as fn(ConnectionDescriptor) -> Unnameable,
|
|
216
|
+
);
|
|
231
217
|
|
|
232
|
-
|
|
233
|
-
fn call(&mut self, descriptor: ConnectionDescriptor) -> Self::Future {
|
|
234
|
-
match self {
|
|
235
|
-
Connector::Simple(service) => service.call(descriptor),
|
|
236
|
-
Connector::WithLayers(service) => service.call(Unnameable(descriptor)),
|
|
237
|
-
}
|
|
218
|
+
Ok(Either::Right(service))
|
|
238
219
|
}
|
|
239
220
|
}
|
|
240
221
|
|
|
241
|
-
// ===== impl
|
|
222
|
+
// ===== impl TransportConnector =====
|
|
242
223
|
|
|
243
|
-
impl
|
|
224
|
+
impl TransportConnector {
|
|
244
225
|
fn build_https_connector(
|
|
245
226
|
&self,
|
|
246
227
|
https: bool,
|
|
@@ -503,41 +484,30 @@ impl ConnectorService {
|
|
|
503
484
|
async fn connect_auto(self, req: ConnectionDescriptor) -> Result<Conn, BoxError> {
|
|
504
485
|
debug!("starting new connection: {:?}", req.uri());
|
|
505
486
|
|
|
506
|
-
let timeout = self.config.timeout;
|
|
507
|
-
|
|
508
487
|
// Determine if a proxy should be used for this request.
|
|
509
|
-
let
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
.
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
self.connect_via_proxy(req, intercepted).await
|
|
523
|
-
} else {
|
|
524
|
-
self.connect_auto_proxy(req, None).await
|
|
525
|
-
}
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
// Apply timeout if configured.
|
|
529
|
-
if let Some(to) = timeout {
|
|
530
|
-
tokio::time::timeout(to, fut).await.map_err(|_| TimedOut)?
|
|
488
|
+
let intercepted = req
|
|
489
|
+
.proxy()
|
|
490
|
+
.and_then(|prox| prox.intercept(req.uri()))
|
|
491
|
+
.or_else(|| {
|
|
492
|
+
self.config
|
|
493
|
+
.proxies
|
|
494
|
+
.iter()
|
|
495
|
+
.find_map(|prox| prox.intercept(req.uri()))
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
// If a proxy is matched, connect via proxy; otherwise, connect directly.
|
|
499
|
+
if let Some(intercepted) = intercepted {
|
|
500
|
+
self.connect_via_proxy(req, intercepted).await
|
|
531
501
|
} else {
|
|
532
|
-
|
|
502
|
+
self.connect_auto_proxy(req, None).await
|
|
533
503
|
}
|
|
534
504
|
}
|
|
535
505
|
}
|
|
536
506
|
|
|
537
|
-
impl Service<ConnectionDescriptor> for
|
|
507
|
+
impl Service<ConnectionDescriptor> for TransportConnector {
|
|
538
508
|
type Response = Conn;
|
|
539
509
|
type Error = BoxError;
|
|
540
|
-
type Future =
|
|
510
|
+
type Future = BoxFuture<'static, Result<Conn, BoxError>>;
|
|
541
511
|
|
|
542
512
|
#[inline]
|
|
543
513
|
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
@@ -20,7 +20,7 @@ use super::{
|
|
|
20
20
|
tcp::{ConnectError, ConnectingTcp, TcpConnector, TcpKeepaliveOptions, TcpOptions},
|
|
21
21
|
},
|
|
22
22
|
};
|
|
23
|
-
use crate::dns::{self,
|
|
23
|
+
use crate::dns::{self, DnsResolver};
|
|
24
24
|
|
|
25
25
|
static INVALID_NOT_HTTP: &str = "invalid URI, scheme is not http";
|
|
26
26
|
static INVALID_MISSING_SCHEME: &str = "invalid URI, scheme is missing";
|
|
@@ -56,16 +56,19 @@ where
|
|
|
56
56
|
/// Set that all socket have `SO_REUSEADDR` set to the supplied value `reuse_address`.
|
|
57
57
|
fn set_reuse_address(&mut self, reuse: bool);
|
|
58
58
|
|
|
59
|
+
/// Sets the value of the `SO_LINGER` option on the socket.
|
|
60
|
+
fn set_linger(&mut self, linger: Option<Duration>);
|
|
61
|
+
|
|
59
62
|
/// Sets the value of the `TCP_USER_TIMEOUT` option on the socket.
|
|
60
63
|
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
|
61
64
|
fn set_tcp_user_timeout(&mut self, time: Option<Duration>);
|
|
62
65
|
|
|
63
|
-
/// Set the
|
|
66
|
+
/// Set the timeout for the complete TCP connection race.
|
|
64
67
|
fn set_connect_timeout(&mut self, dur: Option<Duration>);
|
|
65
68
|
|
|
66
|
-
/// Set
|
|
69
|
+
/// Set the delay between connection attempts for [RFC 8305 (Happy Eyeballs v2)][RFC 8305].
|
|
67
70
|
///
|
|
68
|
-
/// [RFC
|
|
71
|
+
/// [RFC 8305]: https://www.rfc-editor.org/rfc/rfc8305.html#section-5
|
|
69
72
|
fn set_happy_eyeballs_timeout(&mut self, dur: Option<Duration>);
|
|
70
73
|
|
|
71
74
|
/// Set that all sockets have `SO_KEEPALIVE` set with the supplied duration
|
|
@@ -156,6 +159,7 @@ impl<R, S> HttpConnector<R, S> {
|
|
|
156
159
|
happy_eyeballs_timeout: Some(Duration::from_millis(300)),
|
|
157
160
|
nodelay: false,
|
|
158
161
|
reuse_address: false,
|
|
162
|
+
linger: None,
|
|
159
163
|
send_buffer_size: None,
|
|
160
164
|
recv_buffer_size: None,
|
|
161
165
|
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
|
@@ -178,7 +182,7 @@ impl<R, S> HttpConnector<R, S> {
|
|
|
178
182
|
|
|
179
183
|
impl<R, S> HttpConnect for HttpConnector<R, S>
|
|
180
184
|
where
|
|
181
|
-
R:
|
|
185
|
+
R: DnsResolver + Clone + Send + Sync + 'static,
|
|
182
186
|
R::Future: Send,
|
|
183
187
|
S: TcpConnector,
|
|
184
188
|
{
|
|
@@ -218,6 +222,14 @@ where
|
|
|
218
222
|
self.config_mut().reuse_address = reuse_address;
|
|
219
223
|
}
|
|
220
224
|
|
|
225
|
+
/// Sets the value of the SO_LINGER option on the socket.
|
|
226
|
+
///
|
|
227
|
+
/// Default is `None`, which leaves the option untouched.
|
|
228
|
+
#[inline]
|
|
229
|
+
fn set_linger(&mut self, linger: Option<Duration>) {
|
|
230
|
+
self.config_mut().linger = linger;
|
|
231
|
+
}
|
|
232
|
+
|
|
221
233
|
/// Sets the value of the TCP_USER_TIMEOUT option on the socket.
|
|
222
234
|
#[inline]
|
|
223
235
|
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
|
@@ -225,10 +237,7 @@ where
|
|
|
225
237
|
self.config_mut().tcp_user_timeout = time;
|
|
226
238
|
}
|
|
227
239
|
|
|
228
|
-
/// Set the
|
|
229
|
-
///
|
|
230
|
-
/// If a domain resolves to multiple IP addresses, the timeout will be
|
|
231
|
-
/// evenly divided across them.
|
|
240
|
+
/// Set the timeout for the complete TCP connection race.
|
|
232
241
|
///
|
|
233
242
|
/// Default is `None`.
|
|
234
243
|
#[inline]
|
|
@@ -236,18 +245,16 @@ where
|
|
|
236
245
|
self.config_mut().connect_timeout = dur;
|
|
237
246
|
}
|
|
238
247
|
|
|
239
|
-
/// Set
|
|
248
|
+
/// Set the delay between connection attempts for [RFC 8305 (Happy Eyeballs v2)][RFC 8305].
|
|
240
249
|
///
|
|
241
|
-
///
|
|
242
|
-
///
|
|
243
|
-
/// elapses, then connector will in parallel attempt connection using other
|
|
244
|
-
/// address family.
|
|
250
|
+
/// The first address is attempted immediately. Later addresses are started
|
|
251
|
+
/// after this delay without waiting for the previous attempt to finish.
|
|
245
252
|
///
|
|
246
253
|
/// If `None`, parallel connection attempts are disabled.
|
|
247
254
|
///
|
|
248
255
|
/// Default is 300 milliseconds.
|
|
249
256
|
///
|
|
250
|
-
/// [RFC
|
|
257
|
+
/// [RFC 8305]: https://www.rfc-editor.org/rfc/rfc8305.html#section-5
|
|
251
258
|
#[inline]
|
|
252
259
|
fn set_happy_eyeballs_timeout(&mut self, dur: Option<Duration>) {
|
|
253
260
|
self.config_mut().happy_eyeballs_timeout = dur;
|
|
@@ -337,7 +344,7 @@ where
|
|
|
337
344
|
|
|
338
345
|
impl<R, S> Service<Uri> for HttpConnector<R, S>
|
|
339
346
|
where
|
|
340
|
-
R:
|
|
347
|
+
R: DnsResolver + Clone + Send + Sync + 'static,
|
|
341
348
|
R::Future: Send,
|
|
342
349
|
S: TcpConnector,
|
|
343
350
|
S::TcpStream: From<socket2::Socket>,
|
|
@@ -358,7 +365,7 @@ where
|
|
|
358
365
|
let options = &this.options;
|
|
359
366
|
|
|
360
367
|
let (host, port) = get_host_port(options, &dst)?;
|
|
361
|
-
let host = host
|
|
368
|
+
let host = crate::util::strip_ipv6_brackets(host);
|
|
362
369
|
|
|
363
370
|
let addrs = if let Some(addrs) = dns::SocketAddrs::try_parse(host, port) {
|
|
364
371
|
addrs
|
|
@@ -472,7 +479,7 @@ pin_project! {
|
|
|
472
479
|
|
|
473
480
|
impl<R, S> Future for HttpConnecting<R, S>
|
|
474
481
|
where
|
|
475
|
-
R:
|
|
482
|
+
R: DnsResolver,
|
|
476
483
|
S: TcpConnector,
|
|
477
484
|
{
|
|
478
485
|
type Output = ConnectResult<S>;
|