wreq-rb 0.5.0 → 0.5.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 +1922 -397
- data/LICENSE +203 -0
- data/README.md +19 -15
- data/ext/wreq_rb/Cargo.toml +4 -6
- data/ext/wreq_rb/src/client.rs +41 -48
- data/lib/wreq-rb/version.rb +1 -1
- data/patches/0001-add-transfer-size-tracking.patch +76 -67
- data/vendor/wreq/Cargo.toml +119 -71
- data/vendor/wreq/README.md +25 -20
- data/vendor/wreq/bench/http1.rs +25 -0
- data/vendor/wreq/bench/http1_over_tls.rs +25 -0
- data/vendor/wreq/bench/http2.rs +25 -0
- data/vendor/wreq/bench/http2_over_tls.rs +25 -0
- data/vendor/wreq/bench/support/bench.rs +91 -0
- data/vendor/wreq/bench/support/client.rs +217 -0
- data/vendor/wreq/bench/support/server.rs +188 -0
- data/vendor/wreq/bench/support.rs +56 -0
- data/vendor/wreq/examples/cert_store.rs +4 -4
- data/vendor/wreq/examples/{emulation.rs → emulate.rs} +2 -2
- data/vendor/wreq/examples/http2_websocket.rs +2 -2
- data/vendor/wreq/examples/keylog.rs +3 -3
- data/vendor/wreq/examples/{request_with_emulation.rs → request_with_emulate.rs} +2 -2
- data/vendor/wreq/examples/rt.rs +23 -0
- data/vendor/wreq/src/client/body.rs +23 -61
- data/vendor/wreq/src/client/emulate.rs +119 -0
- data/vendor/wreq/src/client/{http/future.rs → future.rs} +11 -32
- data/vendor/wreq/src/client/{http → layer}/client/pool.rs +66 -61
- data/vendor/wreq/src/client/{http → layer}/client.rs +416 -270
- data/vendor/wreq/src/client/layer/config.rs +27 -6
- data/vendor/wreq/src/client/layer/decoder.rs +9 -4
- data/vendor/wreq/src/client/layer/redirect/future.rs +6 -3
- data/vendor/wreq/src/client/layer/redirect.rs +4 -5
- data/vendor/wreq/src/client/layer/retry.rs +8 -5
- data/vendor/wreq/src/client/layer/timeout/body.rs +15 -6
- data/vendor/wreq/src/client/layer/timeout/future.rs +23 -18
- data/vendor/wreq/src/client/layer/timeout.rs +24 -74
- data/vendor/wreq/src/client/layer.rs +1 -2
- data/vendor/wreq/src/client/multipart.rs +137 -154
- data/vendor/wreq/src/client/request.rs +202 -118
- data/vendor/wreq/src/client/response.rs +46 -45
- data/vendor/wreq/src/client/upgrade.rs +15 -0
- data/vendor/wreq/src/client/ws.rs +73 -25
- data/vendor/wreq/src/client.rs +1655 -17
- data/vendor/wreq/src/config.rs +11 -11
- data/vendor/wreq/src/{client/conn → conn}/connector.rs +139 -137
- data/vendor/wreq/src/conn/descriptor.rs +143 -0
- data/vendor/wreq/src/conn/http.rs +484 -0
- data/vendor/wreq/src/conn/net/io.rs +75 -0
- data/vendor/wreq/src/conn/net/tcp/compio.rs +71 -0
- data/vendor/wreq/src/conn/net/tcp/tokio.rs +57 -0
- data/vendor/wreq/src/conn/net/tcp.rs +561 -0
- data/vendor/wreq/src/conn/net/uds/compio.rs +60 -0
- data/vendor/wreq/src/{client/conn/uds.rs → conn/net/uds/tokio.rs} +18 -12
- data/vendor/wreq/src/conn/net/uds.rs +11 -0
- data/vendor/wreq/src/conn/net.rs +130 -0
- data/vendor/wreq/src/{client/conn → conn}/proxy/socks.rs +2 -9
- data/vendor/wreq/src/{client/conn → conn}/proxy/tunnel.rs +21 -56
- data/vendor/wreq/src/conn/tls_info.rs +47 -0
- data/vendor/wreq/src/{client/conn.rs → conn.rs} +202 -54
- data/vendor/wreq/src/cookie.rs +302 -142
- data/vendor/wreq/src/dns/gai/compio.rs +77 -0
- data/vendor/wreq/src/dns/gai/tokio.rs +90 -0
- data/vendor/wreq/src/dns/gai.rs +14 -164
- data/vendor/wreq/src/dns/hickory.rs +16 -23
- data/vendor/wreq/src/dns/resolve.rs +7 -41
- data/vendor/wreq/src/dns.rs +90 -7
- data/vendor/wreq/src/error.rs +57 -31
- data/vendor/wreq/src/ext.rs +25 -0
- data/vendor/wreq/src/group.rs +211 -0
- data/vendor/wreq/src/header.rs +100 -112
- data/vendor/wreq/src/lib.rs +124 -73
- data/vendor/wreq/src/proxy.rs +6 -20
- data/vendor/wreq/src/redirect.rs +1 -1
- data/vendor/wreq/src/rt.rs +208 -0
- data/vendor/wreq/src/sync.rs +97 -98
- data/vendor/wreq/src/tls/compress.rs +124 -0
- data/vendor/wreq/src/tls/conn/ext.rs +54 -45
- data/vendor/wreq/src/tls/conn/service.rs +14 -18
- data/vendor/wreq/src/tls/conn.rs +169 -241
- data/vendor/wreq/src/tls/keylog.rs +68 -5
- data/vendor/wreq/src/tls/session.rs +205 -0
- data/vendor/wreq/src/tls/{x509 → trust}/identity.rs +4 -21
- data/vendor/wreq/src/tls/{x509/parser.rs → trust/parse.rs} +1 -1
- data/vendor/wreq/src/tls/{x509 → trust}/store.rs +42 -81
- data/vendor/wreq/src/tls/{x509.rs → trust.rs} +8 -2
- data/vendor/wreq/src/tls.rs +489 -25
- data/vendor/wreq/src/trace.rs +0 -12
- data/vendor/wreq/src/util.rs +1 -1
- data/vendor/wreq/tests/badssl.rs +10 -10
- data/vendor/wreq/tests/client.rs +3 -9
- data/vendor/wreq/tests/cookie.rs +6 -8
- data/vendor/wreq/tests/{emulation.rs → emulate.rs} +130 -22
- data/vendor/wreq/tests/multipart.rs +43 -1
- data/vendor/wreq/tests/proxy.rs +1 -1
- data/vendor/wreq/tests/support/layer.rs +1 -0
- metadata +49 -71
- data/patches/0002-add-cancel-connections.patch +0 -181
- data/vendor/wreq/src/client/conn/conn.rs +0 -231
- data/vendor/wreq/src/client/conn/http.rs +0 -1023
- data/vendor/wreq/src/client/conn/tls_info.rs +0 -98
- data/vendor/wreq/src/client/core/body/incoming.rs +0 -485
- data/vendor/wreq/src/client/core/body/length.rs +0 -118
- data/vendor/wreq/src/client/core/body.rs +0 -34
- data/vendor/wreq/src/client/core/common/buf.rs +0 -149
- data/vendor/wreq/src/client/core/common/rewind.rs +0 -141
- data/vendor/wreq/src/client/core/common/watch.rs +0 -76
- data/vendor/wreq/src/client/core/common.rs +0 -3
- data/vendor/wreq/src/client/core/conn/http1.rs +0 -342
- data/vendor/wreq/src/client/core/conn/http2.rs +0 -307
- data/vendor/wreq/src/client/core/conn.rs +0 -11
- data/vendor/wreq/src/client/core/dispatch.rs +0 -299
- data/vendor/wreq/src/client/core/error.rs +0 -435
- data/vendor/wreq/src/client/core/ext.rs +0 -201
- data/vendor/wreq/src/client/core/http1.rs +0 -178
- data/vendor/wreq/src/client/core/http2.rs +0 -483
- data/vendor/wreq/src/client/core/proto/h1/conn.rs +0 -988
- data/vendor/wreq/src/client/core/proto/h1/decode.rs +0 -1170
- data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +0 -684
- data/vendor/wreq/src/client/core/proto/h1/encode.rs +0 -580
- data/vendor/wreq/src/client/core/proto/h1/io.rs +0 -879
- data/vendor/wreq/src/client/core/proto/h1/role.rs +0 -694
- data/vendor/wreq/src/client/core/proto/h1.rs +0 -104
- data/vendor/wreq/src/client/core/proto/h2/client.rs +0 -650
- data/vendor/wreq/src/client/core/proto/h2/ping.rs +0 -539
- data/vendor/wreq/src/client/core/proto/h2.rs +0 -379
- data/vendor/wreq/src/client/core/proto/headers.rs +0 -138
- data/vendor/wreq/src/client/core/proto.rs +0 -58
- data/vendor/wreq/src/client/core/rt/bounds.rs +0 -57
- data/vendor/wreq/src/client/core/rt/timer.rs +0 -150
- data/vendor/wreq/src/client/core/rt/tokio.rs +0 -99
- data/vendor/wreq/src/client/core/rt.rs +0 -25
- data/vendor/wreq/src/client/core/upgrade.rs +0 -267
- data/vendor/wreq/src/client/core.rs +0 -16
- data/vendor/wreq/src/client/emulation.rs +0 -161
- data/vendor/wreq/src/client/http/client/error.rs +0 -142
- data/vendor/wreq/src/client/http/client/exec.rs +0 -29
- data/vendor/wreq/src/client/http/client/extra.rs +0 -77
- data/vendor/wreq/src/client/http/client/util.rs +0 -104
- data/vendor/wreq/src/client/http.rs +0 -1629
- data/vendor/wreq/src/client/layer/config/options.rs +0 -156
- data/vendor/wreq/src/client/layer/cookie.rs +0 -161
- data/vendor/wreq/src/hash.rs +0 -143
- data/vendor/wreq/src/tls/conn/cache.rs +0 -123
- data/vendor/wreq/src/tls/conn/cert_compression.rs +0 -125
- data/vendor/wreq/src/tls/keylog/handle.rs +0 -64
- data/vendor/wreq/src/tls/options.rs +0 -464
- /data/vendor/wreq/src/client/{http → layer}/client/lazy.rs +0 -0
- /data/vendor/wreq/src/{client/conn → conn}/proxy.rs +0 -0
- /data/vendor/wreq/src/{client/conn → conn}/verbose.rs +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// This module contains the `GaiResolver` implementation for the `tokio` runtime.
|
|
2
|
+
|
|
3
|
+
use std::{
|
|
4
|
+
future::Future,
|
|
5
|
+
io,
|
|
6
|
+
net::ToSocketAddrs,
|
|
7
|
+
pin::Pin,
|
|
8
|
+
task::{self, Poll},
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
use tower::Service;
|
|
12
|
+
|
|
13
|
+
use super::{GaiAddrs, GaiResolver};
|
|
14
|
+
use crate::dns::{Addrs, Name, Resolve, Resolving, SocketAddrs};
|
|
15
|
+
|
|
16
|
+
/// A future to resolve a name returned by `GaiResolver`.
|
|
17
|
+
pub struct GaiFuture {
|
|
18
|
+
inner: tokio::task::JoinHandle<Result<SocketAddrs, io::Error>>,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// ==== impl GaiResolver ====
|
|
22
|
+
|
|
23
|
+
impl GaiResolver {
|
|
24
|
+
/// Creates a new [`GaiResolver`].
|
|
25
|
+
pub fn new() -> Self {
|
|
26
|
+
GaiResolver { _priv: () }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
impl Service<Name> for GaiResolver {
|
|
31
|
+
type Response = GaiAddrs;
|
|
32
|
+
type Error = io::Error;
|
|
33
|
+
type Future = GaiFuture;
|
|
34
|
+
|
|
35
|
+
#[inline]
|
|
36
|
+
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {
|
|
37
|
+
Poll::Ready(Ok(()))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fn call(&mut self, name: Name) -> Self::Future {
|
|
41
|
+
let blocking = tokio::task::spawn_blocking(move || {
|
|
42
|
+
debug!("resolving {}", name);
|
|
43
|
+
(name.as_str(), 0)
|
|
44
|
+
.to_socket_addrs()
|
|
45
|
+
.map(|i| SocketAddrs { iter: i })
|
|
46
|
+
});
|
|
47
|
+
GaiFuture { inner: blocking }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
impl Resolve for GaiResolver {
|
|
52
|
+
fn resolve(&self, name: Name) -> Resolving {
|
|
53
|
+
let mut this = self.clone();
|
|
54
|
+
Box::pin(async move {
|
|
55
|
+
this.call(name)
|
|
56
|
+
.await
|
|
57
|
+
.map(|addrs| Box::new(addrs) as Addrs)
|
|
58
|
+
.map_err(Into::into)
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ==== impl GaiFuture ====
|
|
64
|
+
|
|
65
|
+
impl Future for GaiFuture {
|
|
66
|
+
type Output = Result<GaiAddrs, io::Error>;
|
|
67
|
+
|
|
68
|
+
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
|
|
69
|
+
Pin::new(&mut self.inner).poll(cx).map(|res| match res {
|
|
70
|
+
Ok(Ok(addrs)) => Ok(GaiAddrs { inner: addrs }),
|
|
71
|
+
Ok(Err(err)) => Err(err),
|
|
72
|
+
Err(join_err) => {
|
|
73
|
+
#[cfg(feature = "tokio-rt")]
|
|
74
|
+
if join_err.is_cancelled() {
|
|
75
|
+
return Err(io::Error::new(io::ErrorKind::Interrupted, join_err));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
Err(io::Error::other(format!(
|
|
79
|
+
"DNS resolution blocked task panicked: {join_err}"
|
|
80
|
+
)))
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
impl Drop for GaiFuture {
|
|
87
|
+
fn drop(&mut self) {
|
|
88
|
+
self.inner.abort();
|
|
89
|
+
}
|
|
90
|
+
}
|
data/vendor/wreq/src/dns/gai.rs
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
1
|
+
if_tokio_rt! {
|
|
2
|
+
mod tokio;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
if_compio_rt!(
|
|
6
|
+
mod compio;
|
|
7
|
+
);
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
if_all_rt!(
|
|
10
|
+
mod tokio;
|
|
11
|
+
);
|
|
12
12
|
|
|
13
|
-
use
|
|
13
|
+
use std::net::SocketAddr;
|
|
14
|
+
|
|
15
|
+
use crate::dns::SocketAddrs;
|
|
14
16
|
|
|
15
17
|
/// A resolver using blocking `getaddrinfo` calls in a threadpool.
|
|
16
18
|
#[derive(Clone, Default)]
|
|
@@ -23,86 +25,6 @@ pub struct GaiAddrs {
|
|
|
23
25
|
inner: SocketAddrs,
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
/// A future to resolve a name returned by `GaiResolver`.
|
|
27
|
-
pub struct GaiFuture {
|
|
28
|
-
inner: JoinHandle<Result<SocketAddrs, io::Error>>,
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/// A wrapper around `SocketAddrs` to implement the `Iterator` trait.
|
|
32
|
-
pub(crate) struct SocketAddrs {
|
|
33
|
-
iter: vec::IntoIter<SocketAddr>,
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// ==== impl GaiResolver ====
|
|
37
|
-
|
|
38
|
-
impl GaiResolver {
|
|
39
|
-
/// Creates a new [`GaiResolver`].
|
|
40
|
-
pub fn new() -> Self {
|
|
41
|
-
GaiResolver { _priv: () }
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
impl Service<Name> for GaiResolver {
|
|
46
|
-
type Response = GaiAddrs;
|
|
47
|
-
type Error = io::Error;
|
|
48
|
-
type Future = GaiFuture;
|
|
49
|
-
|
|
50
|
-
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {
|
|
51
|
-
Poll::Ready(Ok(()))
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
fn call(&mut self, name: Name) -> Self::Future {
|
|
55
|
-
let blocking = tokio::task::spawn_blocking(move || {
|
|
56
|
-
debug!("resolving {}", name);
|
|
57
|
-
(name.as_str(), 0)
|
|
58
|
-
.to_socket_addrs()
|
|
59
|
-
.map(|i| SocketAddrs { iter: i })
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
GaiFuture { inner: blocking }
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
impl Resolve for GaiResolver {
|
|
67
|
-
fn resolve(&self, name: Name) -> Resolving {
|
|
68
|
-
let mut this = self.clone();
|
|
69
|
-
Box::pin(async move {
|
|
70
|
-
this.call(name)
|
|
71
|
-
.await
|
|
72
|
-
.map(|addrs| Box::new(addrs) as Addrs)
|
|
73
|
-
.map_err(Into::into)
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// ==== impl GaiFuture ====
|
|
79
|
-
|
|
80
|
-
impl Future for GaiFuture {
|
|
81
|
-
type Output = Result<GaiAddrs, io::Error>;
|
|
82
|
-
|
|
83
|
-
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
|
|
84
|
-
Pin::new(&mut self.inner).poll(cx).map(|res| match res {
|
|
85
|
-
Ok(Ok(addrs)) => Ok(GaiAddrs { inner: addrs }),
|
|
86
|
-
Ok(Err(err)) => Err(err),
|
|
87
|
-
Err(join_err) => {
|
|
88
|
-
if join_err.is_cancelled() {
|
|
89
|
-
Err(io::Error::new(io::ErrorKind::Interrupted, join_err))
|
|
90
|
-
} else {
|
|
91
|
-
panic!("gai background task failed: {join_err:?}")
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
impl Drop for GaiFuture {
|
|
99
|
-
fn drop(&mut self) {
|
|
100
|
-
self.inner.abort();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// ==== impl GaiAddrs ====
|
|
105
|
-
|
|
106
28
|
impl Iterator for GaiAddrs {
|
|
107
29
|
type Item = SocketAddr;
|
|
108
30
|
|
|
@@ -111,83 +33,11 @@ impl Iterator for GaiAddrs {
|
|
|
111
33
|
}
|
|
112
34
|
}
|
|
113
35
|
|
|
114
|
-
// ==== impl SocketAddrs ====
|
|
115
|
-
|
|
116
|
-
impl SocketAddrs {
|
|
117
|
-
pub(crate) fn new(addrs: Vec<SocketAddr>) -> Self {
|
|
118
|
-
SocketAddrs {
|
|
119
|
-
iter: addrs.into_iter(),
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
pub(crate) fn try_parse(host: &str, port: u16) -> Option<SocketAddrs> {
|
|
124
|
-
if let Ok(addr) = host.parse::<Ipv4Addr>() {
|
|
125
|
-
let addr = SocketAddrV4::new(addr, port);
|
|
126
|
-
return Some(SocketAddrs {
|
|
127
|
-
iter: vec![SocketAddr::V4(addr)].into_iter(),
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
if let Ok(addr) = host.parse::<Ipv6Addr>() {
|
|
131
|
-
let addr = SocketAddrV6::new(addr, port, 0, 0);
|
|
132
|
-
return Some(SocketAddrs {
|
|
133
|
-
iter: vec![SocketAddr::V6(addr)].into_iter(),
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
None
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
#[inline]
|
|
140
|
-
fn filter(self, predicate: impl FnMut(&SocketAddr) -> bool) -> SocketAddrs {
|
|
141
|
-
SocketAddrs::new(self.iter.filter(predicate).collect())
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
pub(crate) fn split_by_preference(
|
|
145
|
-
self,
|
|
146
|
-
local_addr_ipv4: Option<Ipv4Addr>,
|
|
147
|
-
local_addr_ipv6: Option<Ipv6Addr>,
|
|
148
|
-
) -> (SocketAddrs, SocketAddrs) {
|
|
149
|
-
match (local_addr_ipv4, local_addr_ipv6) {
|
|
150
|
-
(Some(_), None) => (self.filter(SocketAddr::is_ipv4), SocketAddrs::new(vec![])),
|
|
151
|
-
(None, Some(_)) => (self.filter(SocketAddr::is_ipv6), SocketAddrs::new(vec![])),
|
|
152
|
-
_ => {
|
|
153
|
-
let preferring_v6 = self
|
|
154
|
-
.iter
|
|
155
|
-
.as_slice()
|
|
156
|
-
.first()
|
|
157
|
-
.map(SocketAddr::is_ipv6)
|
|
158
|
-
.unwrap_or(false);
|
|
159
|
-
|
|
160
|
-
let (preferred, fallback) = self
|
|
161
|
-
.iter
|
|
162
|
-
.partition::<Vec<_>, _>(|addr| addr.is_ipv6() == preferring_v6);
|
|
163
|
-
|
|
164
|
-
(SocketAddrs::new(preferred), SocketAddrs::new(fallback))
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
pub(crate) fn is_empty(&self) -> bool {
|
|
170
|
-
self.iter.as_slice().is_empty()
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
pub(crate) fn len(&self) -> usize {
|
|
174
|
-
self.iter.as_slice().len()
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
impl Iterator for SocketAddrs {
|
|
179
|
-
type Item = SocketAddr;
|
|
180
|
-
#[inline]
|
|
181
|
-
fn next(&mut self) -> Option<SocketAddr> {
|
|
182
|
-
self.iter.next()
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
36
|
#[cfg(test)]
|
|
187
37
|
mod tests {
|
|
188
38
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
|
189
39
|
|
|
190
|
-
use
|
|
40
|
+
use crate::dns::{Name, SocketAddrs};
|
|
191
41
|
|
|
192
42
|
#[test]
|
|
193
43
|
fn test_ip_addrs_split_by_preference() {
|
|
@@ -4,9 +4,8 @@ use std::{net::SocketAddr, sync::LazyLock};
|
|
|
4
4
|
|
|
5
5
|
use hickory_resolver::{
|
|
6
6
|
TokioResolver,
|
|
7
|
-
config::{LookupIpStrategy, ResolverConfig},
|
|
8
|
-
|
|
9
|
-
name_server::TokioConnectionProvider,
|
|
7
|
+
config::{self, LookupIpStrategy, ResolverConfig},
|
|
8
|
+
net::runtime::TokioRuntimeProvider,
|
|
10
9
|
};
|
|
11
10
|
|
|
12
11
|
use super::{Addrs, Name, Resolve, Resolving};
|
|
@@ -25,8 +24,10 @@ pub struct HickoryDnsResolver {
|
|
|
25
24
|
impl HickoryDnsResolver {
|
|
26
25
|
/// Create a new resolver with the default configuration,
|
|
27
26
|
/// which reads from `/etc/resolve.conf`. The options are
|
|
28
|
-
///
|
|
29
|
-
/// to
|
|
27
|
+
/// overridden to look up both IPv4 and IPv6 addresses
|
|
28
|
+
/// to support the "happy eyeballs" algorithm.
|
|
29
|
+
///
|
|
30
|
+
/// SAFETY: `build` only fails if DNS-over-TLS is enabled and default TLS config creation fails.
|
|
30
31
|
pub fn new() -> HickoryDnsResolver {
|
|
31
32
|
static RESOLVER: LazyLock<TokioResolver> = LazyLock::new(|| {
|
|
32
33
|
let mut builder = match TokioResolver::builder_tokio() {
|
|
@@ -37,13 +38,13 @@ impl HickoryDnsResolver {
|
|
|
37
38
|
Err(_err) => {
|
|
38
39
|
debug!("error reading DNS system conf: {}, using defaults", _err);
|
|
39
40
|
TokioResolver::builder_with_config(
|
|
40
|
-
ResolverConfig::
|
|
41
|
-
|
|
41
|
+
ResolverConfig::udp_and_tcp(&config::GOOGLE),
|
|
42
|
+
TokioRuntimeProvider::default(),
|
|
42
43
|
)
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
builder.options_mut().ip_strategy = LookupIpStrategy::Ipv4AndIpv6;
|
|
46
|
-
builder.build()
|
|
47
|
+
builder.build().expect("failed to create DNS resolver")
|
|
47
48
|
});
|
|
48
49
|
|
|
49
50
|
HickoryDnsResolver {
|
|
@@ -52,27 +53,19 @@ impl HickoryDnsResolver {
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
struct SocketAddrs {
|
|
56
|
-
iter: LookupIpIntoIter,
|
|
57
|
-
}
|
|
58
|
-
|
|
59
56
|
impl Resolve for HickoryDnsResolver {
|
|
60
57
|
fn resolve(&self, name: Name) -> Resolving {
|
|
61
58
|
let resolver = self.clone();
|
|
62
59
|
Box::pin(async move {
|
|
63
60
|
let lookup = resolver.resolver.lookup_ip(name.as_str()).await?;
|
|
64
|
-
let addrs: Addrs = Box::new(
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
let addrs: Addrs = Box::new(
|
|
62
|
+
lookup
|
|
63
|
+
.iter()
|
|
64
|
+
.map(|ip_addr| SocketAddr::new(ip_addr, 0))
|
|
65
|
+
.collect::<Vec<_>>()
|
|
66
|
+
.into_iter(),
|
|
67
|
+
);
|
|
67
68
|
Ok(addrs)
|
|
68
69
|
})
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
-
impl Iterator for SocketAddrs {
|
|
73
|
-
type Item = SocketAddr;
|
|
74
|
-
|
|
75
|
-
fn next(&mut self) -> Option<Self::Item> {
|
|
76
|
-
self.iter.next().map(|ip_addr| SocketAddr::new(ip_addr, 0))
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -9,9 +9,7 @@ use std::{
|
|
|
9
9
|
task::{Context, Poll},
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
use tower::Service;
|
|
13
|
-
|
|
14
|
-
use crate::error::BoxError;
|
|
12
|
+
use tower::{BoxError, Service};
|
|
15
13
|
|
|
16
14
|
/// A domain name to resolve into IP addresses.
|
|
17
15
|
#[derive(Clone, Hash, Eq, PartialEq)]
|
|
@@ -74,45 +72,13 @@ pub trait Resolve: Send + Sync {
|
|
|
74
72
|
fn resolve(&self, name: Name) -> Resolving;
|
|
75
73
|
}
|
|
76
74
|
|
|
77
|
-
|
|
78
|
-
///
|
|
79
|
-
/// Implemented for any [`Resolve`] type, [`Arc<T>`] where `T: Resolve`, and [`Arc<dyn Resolve>`].
|
|
80
|
-
/// Enables ergonomic conversion to a trait object for use in APIs without manual Arc wrapping.
|
|
81
|
-
pub trait IntoResolve {
|
|
82
|
-
/// Converts the implementor into an [`Arc<dyn Resolve>`].
|
|
75
|
+
impl_into_shared!(
|
|
76
|
+
/// Trait for converting types into a shared DNS resolver ([`Arc<dyn Resolve>`]).
|
|
83
77
|
///
|
|
84
|
-
///
|
|
85
|
-
///
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
impl IntoResolve for Arc<dyn Resolve> {
|
|
91
|
-
#[inline]
|
|
92
|
-
fn into_resolve(self) -> Arc<dyn Resolve> {
|
|
93
|
-
self
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
impl<R> IntoResolve for Arc<R>
|
|
98
|
-
where
|
|
99
|
-
R: Resolve + 'static,
|
|
100
|
-
{
|
|
101
|
-
#[inline]
|
|
102
|
-
fn into_resolve(self) -> Arc<dyn Resolve> {
|
|
103
|
-
self
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
impl<R> IntoResolve for R
|
|
108
|
-
where
|
|
109
|
-
R: Resolve + 'static,
|
|
110
|
-
{
|
|
111
|
-
#[inline]
|
|
112
|
-
fn into_resolve(self) -> Arc<dyn Resolve> {
|
|
113
|
-
Arc::new(self)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
78
|
+
/// Implemented for any [`Resolve`] type, [`Arc<T>`] where `T: Resolve`, and [`Arc<dyn Resolve>`].
|
|
79
|
+
/// Enables ergonomic conversion to a trait object for use in APIs without manual Arc wrapping.
|
|
80
|
+
pub trait IntoResolve => Resolve
|
|
81
|
+
);
|
|
116
82
|
|
|
117
83
|
/// Adapter that wraps a [`Resolve`] trait object to work with Tower's `Service` trait.
|
|
118
84
|
///
|
data/vendor/wreq/src/dns.rs
CHANGED
|
@@ -1,18 +1,102 @@
|
|
|
1
1
|
//! DNS resolution
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
use std::{
|
|
4
|
+
net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
|
|
5
|
+
vec,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
mod gai;
|
|
9
|
+
mod resolve;
|
|
10
|
+
|
|
4
11
|
#[cfg(feature = "hickory-dns")]
|
|
5
12
|
pub(crate) mod hickory;
|
|
6
|
-
pub(crate) mod resolve;
|
|
7
|
-
|
|
8
|
-
pub use resolve::{Addrs, IntoResolve, Name, Resolve, Resolving};
|
|
9
13
|
|
|
14
|
+
pub use self::{
|
|
15
|
+
gai::GaiResolver,
|
|
16
|
+
resolve::{Addrs, IntoResolve, Name, Resolve, Resolving},
|
|
17
|
+
};
|
|
10
18
|
pub(crate) use self::{
|
|
11
|
-
gai::{GaiResolver, SocketAddrs},
|
|
12
19
|
resolve::{DnsResolverWithOverrides, DynResolver},
|
|
13
20
|
sealed::{InternalResolve, resolve},
|
|
14
21
|
};
|
|
15
22
|
|
|
23
|
+
/// A wrapper around `Vec<SocketAddr>` to implement the `Iterator` trait.
|
|
24
|
+
pub(crate) struct SocketAddrs {
|
|
25
|
+
iter: vec::IntoIter<SocketAddr>,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
impl SocketAddrs {
|
|
29
|
+
pub(crate) fn new(addrs: Vec<SocketAddr>) -> Self {
|
|
30
|
+
SocketAddrs {
|
|
31
|
+
iter: addrs.into_iter(),
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
pub(crate) fn try_parse(host: &str, port: u16) -> Option<SocketAddrs> {
|
|
36
|
+
if let Ok(addr) = host.parse::<Ipv4Addr>() {
|
|
37
|
+
let addr = SocketAddrV4::new(addr, port);
|
|
38
|
+
return Some(SocketAddrs {
|
|
39
|
+
iter: vec![SocketAddr::V4(addr)].into_iter(),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if let Ok(addr) = host.parse::<Ipv6Addr>() {
|
|
43
|
+
let addr = SocketAddrV6::new(addr, port, 0, 0);
|
|
44
|
+
return Some(SocketAddrs {
|
|
45
|
+
iter: vec![SocketAddr::V6(addr)].into_iter(),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
None
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
pub(crate) fn split_by_preference(
|
|
52
|
+
self,
|
|
53
|
+
local_addr_ipv4: Option<Ipv4Addr>,
|
|
54
|
+
local_addr_ipv6: Option<Ipv6Addr>,
|
|
55
|
+
) -> (SocketAddrs, SocketAddrs) {
|
|
56
|
+
match (local_addr_ipv4, local_addr_ipv6) {
|
|
57
|
+
(Some(_), None) => (self.filter(SocketAddr::is_ipv4), SocketAddrs::new(vec![])),
|
|
58
|
+
(None, Some(_)) => (self.filter(SocketAddr::is_ipv6), SocketAddrs::new(vec![])),
|
|
59
|
+
_ => {
|
|
60
|
+
let preferring_v6 = self
|
|
61
|
+
.iter
|
|
62
|
+
.as_slice()
|
|
63
|
+
.first()
|
|
64
|
+
.map(SocketAddr::is_ipv6)
|
|
65
|
+
.unwrap_or(false);
|
|
66
|
+
|
|
67
|
+
let (preferred, fallback) = self
|
|
68
|
+
.iter
|
|
69
|
+
.partition::<Vec<_>, _>(|addr| addr.is_ipv6() == preferring_v6);
|
|
70
|
+
|
|
71
|
+
(SocketAddrs::new(preferred), SocketAddrs::new(fallback))
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
#[inline]
|
|
77
|
+
fn filter(self, predicate: impl FnMut(&SocketAddr) -> bool) -> SocketAddrs {
|
|
78
|
+
SocketAddrs::new(self.iter.filter(predicate).collect())
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#[inline]
|
|
82
|
+
pub(crate) fn is_empty(&self) -> bool {
|
|
83
|
+
self.iter.as_slice().is_empty()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#[inline]
|
|
87
|
+
pub(crate) fn len(&self) -> usize {
|
|
88
|
+
self.iter.as_slice().len()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
impl Iterator for SocketAddrs {
|
|
93
|
+
type Item = SocketAddr;
|
|
94
|
+
#[inline]
|
|
95
|
+
fn next(&mut self) -> Option<SocketAddr> {
|
|
96
|
+
self.iter.next()
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
16
100
|
mod sealed {
|
|
17
101
|
use std::{
|
|
18
102
|
future::Future,
|
|
@@ -20,10 +104,9 @@ mod sealed {
|
|
|
20
104
|
task::{self, Poll},
|
|
21
105
|
};
|
|
22
106
|
|
|
23
|
-
use tower::Service;
|
|
107
|
+
use tower::{BoxError, Service};
|
|
24
108
|
|
|
25
109
|
use super::Name;
|
|
26
|
-
use crate::error::BoxError;
|
|
27
110
|
|
|
28
111
|
/// Internal adapter trait for DNS resolvers.
|
|
29
112
|
///
|