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
data/vendor/wreq/src/config.rs
CHANGED
|
@@ -73,17 +73,6 @@ where
|
|
|
73
73
|
.or(self.as_ref())
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
/// Stores this value into the given [`http::Extensions`], if a value of the same type is not
|
|
77
|
-
/// already present.
|
|
78
|
-
///
|
|
79
|
-
/// This method checks whether the provided [`http::Extensions`] contains a
|
|
80
|
-
/// [`RequestConfig<T>`]. If not, it clones the current value and inserts it into the
|
|
81
|
-
/// extensions. If a value already exists, the method does nothing.
|
|
82
|
-
#[inline]
|
|
83
|
-
pub(crate) fn store<'a>(&'a self, ext: &'a mut Extensions) -> &'a mut Option<T::Value> {
|
|
84
|
-
&mut ext.get_or_insert_with(|| self.clone()).0
|
|
85
|
-
}
|
|
86
|
-
|
|
87
76
|
/// Loads the internal value from the provided [`http::Extensions`], if present.
|
|
88
77
|
///
|
|
89
78
|
/// This method attempts to remove a value of type [`RequestConfig<T>`] from the provided
|
|
@@ -97,6 +86,17 @@ where
|
|
|
97
86
|
self.as_ref()
|
|
98
87
|
}
|
|
99
88
|
|
|
89
|
+
/// Removes and returns the value of this type from the given [`http::Extensions`],
|
|
90
|
+
/// or returns a clone of the current value if not present.
|
|
91
|
+
///
|
|
92
|
+
/// This method attempts to remove a [`RequestConfig<T>`] from the provided
|
|
93
|
+
/// [`http::Extensions`]. If a value is found, it is returned. If not, the current value is
|
|
94
|
+
/// cloned and returned instead.
|
|
95
|
+
#[inline]
|
|
96
|
+
pub(crate) fn take<'a>(&'a self, ext: &'a mut Extensions) -> Option<T::Value> {
|
|
97
|
+
ext.remove().unwrap_or_else(|| self.clone()).0
|
|
98
|
+
}
|
|
99
|
+
|
|
100
100
|
/// Returns an immutable reference to the stored value from the given [`http::Extensions`], if
|
|
101
101
|
/// present.
|
|
102
102
|
///
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
#[cfg(unix)]
|
|
2
|
-
use std::path::Path;
|
|
3
1
|
use std::{
|
|
2
|
+
borrow::Cow,
|
|
4
3
|
future::Future,
|
|
5
4
|
pin::Pin,
|
|
6
5
|
sync::Arc,
|
|
@@ -8,28 +7,23 @@ use std::{
|
|
|
8
7
|
time::Duration,
|
|
9
8
|
};
|
|
10
9
|
|
|
11
|
-
use
|
|
12
|
-
use tokio::io::{AsyncRead, AsyncWrite};
|
|
13
|
-
use tokio_boring2::SslStream;
|
|
10
|
+
use tokio_btls::SslStream;
|
|
14
11
|
use tower::{
|
|
15
|
-
Service, ServiceBuilder, ServiceExt,
|
|
12
|
+
BoxError, Service, ServiceBuilder, ServiceExt,
|
|
16
13
|
timeout::TimeoutLayer,
|
|
17
14
|
util::{BoxCloneSyncService, MapRequestLayer},
|
|
18
15
|
};
|
|
19
16
|
|
|
20
17
|
#[cfg(unix)]
|
|
21
|
-
use super::
|
|
18
|
+
use super::net::UnixConnector;
|
|
22
19
|
use super::{
|
|
23
|
-
AsyncConnWithInfo, BoxedConnectorLayer, BoxedConnectorService, Connection, HttpConnector,
|
|
24
|
-
TlsInfoFactory, Unnameable,
|
|
25
|
-
|
|
26
|
-
proxy,
|
|
27
|
-
verbose::Verbose,
|
|
20
|
+
AsyncConnWithInfo, BoxedConnectorLayer, BoxedConnectorService, Conn, Connection, HttpConnector,
|
|
21
|
+
TlsConn, TlsInfoFactory, Unnameable, descriptor::ConnectionDescriptor, http::HttpConnect,
|
|
22
|
+
net::TcpConnector, proxy, verbose::Verbose,
|
|
28
23
|
};
|
|
29
24
|
use crate::{
|
|
30
|
-
client::http::{ConnectExtra, ConnectRequest},
|
|
31
25
|
dns::DynResolver,
|
|
32
|
-
error::{
|
|
26
|
+
error::{ProxyConnect, TimedOut, map_timeout_to_connector_error},
|
|
33
27
|
ext::UriExt,
|
|
34
28
|
proxy::{Intercepted, Matcher as ProxyMatcher, matcher::Intercept},
|
|
35
29
|
tls::{
|
|
@@ -47,7 +41,7 @@ type Connecting = Pin<Box<dyn Future<Output = Result<Conn, BoxError>> + Send>>;
|
|
|
47
41
|
struct Config {
|
|
48
42
|
proxies: Arc<Vec<ProxyMatcher>>,
|
|
49
43
|
verbose: Verbose,
|
|
50
|
-
|
|
44
|
+
nodelay: bool,
|
|
51
45
|
tls_info: bool,
|
|
52
46
|
/// When there is a single timeout layer and no other layers,
|
|
53
47
|
/// we embed it directly inside our base Service::call().
|
|
@@ -62,8 +56,7 @@ pub struct ConnectorBuilder {
|
|
|
62
56
|
#[cfg(feature = "socks")]
|
|
63
57
|
resolver: DynResolver,
|
|
64
58
|
http: HttpConnector,
|
|
65
|
-
|
|
66
|
-
tls_builder: TlsConnectorBuilder,
|
|
59
|
+
builder: TlsConnectorBuilder,
|
|
67
60
|
}
|
|
68
61
|
|
|
69
62
|
/// Connector service that establishes connections.
|
|
@@ -79,9 +72,9 @@ pub struct ConnectorService {
|
|
|
79
72
|
config: Config,
|
|
80
73
|
#[cfg(feature = "socks")]
|
|
81
74
|
resolver: DynResolver,
|
|
82
|
-
http: HttpConnector,
|
|
83
75
|
tls: TlsConnector,
|
|
84
|
-
|
|
76
|
+
http: HttpConnector,
|
|
77
|
+
builder: Arc<TlsConnectorBuilder>,
|
|
85
78
|
}
|
|
86
79
|
|
|
87
80
|
// ===== impl ConnectorBuilder =====
|
|
@@ -103,7 +96,7 @@ impl ConnectorBuilder {
|
|
|
103
96
|
where
|
|
104
97
|
F: FnOnce(TlsConnectorBuilder) -> TlsConnectorBuilder,
|
|
105
98
|
{
|
|
106
|
-
self.
|
|
99
|
+
self.builder = call(self.builder);
|
|
107
100
|
self
|
|
108
101
|
}
|
|
109
102
|
|
|
@@ -131,24 +124,28 @@ impl ConnectorBuilder {
|
|
|
131
124
|
self
|
|
132
125
|
}
|
|
133
126
|
|
|
134
|
-
/// Sets the
|
|
127
|
+
/// Sets the TCP_NODELAY option for connections.
|
|
135
128
|
#[inline]
|
|
136
|
-
pub fn
|
|
137
|
-
|
|
138
|
-
self.tls_options = opts;
|
|
139
|
-
}
|
|
129
|
+
pub fn tcp_nodelay(mut self, enabled: bool) -> ConnectorBuilder {
|
|
130
|
+
self.config.nodelay = enabled;
|
|
140
131
|
self
|
|
141
132
|
}
|
|
142
133
|
|
|
143
134
|
/// Build a [`Connector`] with the provided layers.
|
|
144
|
-
pub fn build(
|
|
135
|
+
pub fn build(
|
|
136
|
+
self,
|
|
137
|
+
tls_options: Option<TlsOptions>,
|
|
138
|
+
layers: Vec<BoxedConnectorLayer>,
|
|
139
|
+
) -> crate::Result<Connector> {
|
|
145
140
|
let mut service = ConnectorService {
|
|
146
141
|
config: self.config,
|
|
147
142
|
#[cfg(feature = "socks")]
|
|
148
143
|
resolver: self.resolver.clone(),
|
|
149
144
|
http: self.http,
|
|
150
|
-
tls: self
|
|
151
|
-
|
|
145
|
+
tls: self
|
|
146
|
+
.builder
|
|
147
|
+
.build(tls_options.map(Cow::Owned).unwrap_or_default())?,
|
|
148
|
+
builder: Arc::new(self.builder),
|
|
152
149
|
};
|
|
153
150
|
|
|
154
151
|
// we have no user-provided layers, only use concrete types
|
|
@@ -161,7 +158,7 @@ impl ConnectorBuilder {
|
|
|
161
158
|
|
|
162
159
|
// otherwise we have user provided layers
|
|
163
160
|
// so we need type erasure all the way through
|
|
164
|
-
// as well as mapping the unnameable type of the layers back to
|
|
161
|
+
// as well as mapping the unnameable type of the layers back to ConnectionDescriptor for the
|
|
165
162
|
// inner service
|
|
166
163
|
let service = layers.into_iter().fold(
|
|
167
164
|
BoxCloneSyncService::new(
|
|
@@ -207,20 +204,19 @@ impl Connector {
|
|
|
207
204
|
config: Config {
|
|
208
205
|
proxies: Arc::new(proxies),
|
|
209
206
|
verbose: Verbose::OFF,
|
|
210
|
-
|
|
207
|
+
nodelay: true,
|
|
211
208
|
tls_info: false,
|
|
212
209
|
timeout: None,
|
|
213
210
|
},
|
|
214
211
|
#[cfg(feature = "socks")]
|
|
215
212
|
resolver: resolver.clone(),
|
|
216
|
-
http: HttpConnector::
|
|
217
|
-
|
|
218
|
-
tls_builder: TlsConnector::builder(),
|
|
213
|
+
http: HttpConnector::new(resolver, TcpConnector::new()),
|
|
214
|
+
builder: TlsConnector::builder(),
|
|
219
215
|
}
|
|
220
216
|
}
|
|
221
217
|
}
|
|
222
218
|
|
|
223
|
-
impl Service<
|
|
219
|
+
impl Service<ConnectionDescriptor> for Connector {
|
|
224
220
|
type Response = Conn;
|
|
225
221
|
type Error = BoxError;
|
|
226
222
|
type Future = Connecting;
|
|
@@ -234,10 +230,10 @@ impl Service<ConnectRequest> for Connector {
|
|
|
234
230
|
}
|
|
235
231
|
|
|
236
232
|
#[inline]
|
|
237
|
-
fn call(&mut self,
|
|
233
|
+
fn call(&mut self, descriptor: ConnectionDescriptor) -> Self::Future {
|
|
238
234
|
match self {
|
|
239
|
-
Connector::Simple(service) => service.call(
|
|
240
|
-
Connector::WithLayers(service) => service.call(Unnameable(
|
|
235
|
+
Connector::Simple(service) => service.call(descriptor),
|
|
236
|
+
Connector::WithLayers(service) => service.call(Unnameable(descriptor)),
|
|
241
237
|
}
|
|
242
238
|
}
|
|
243
239
|
}
|
|
@@ -245,6 +241,50 @@ impl Service<ConnectRequest> for Connector {
|
|
|
245
241
|
// ===== impl ConnectorService =====
|
|
246
242
|
|
|
247
243
|
impl ConnectorService {
|
|
244
|
+
fn build_https_connector(
|
|
245
|
+
&self,
|
|
246
|
+
https: bool,
|
|
247
|
+
descriptor: &ConnectionDescriptor,
|
|
248
|
+
) -> Result<HttpsConnector<HttpConnector>, BoxError> {
|
|
249
|
+
let mut http = self.http.clone();
|
|
250
|
+
|
|
251
|
+
// Disable Nagle's algorithm for TLS handshake
|
|
252
|
+
//
|
|
253
|
+
// https://www.openssl.org/docs/man1.1.1/man3/SSL_connect.html#NOTES
|
|
254
|
+
if https && !self.config.nodelay {
|
|
255
|
+
http.set_nodelay(true);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Apply TCP options if provided in metadata
|
|
259
|
+
if let Some(socket_opts) = descriptor.socket_bind_options() {
|
|
260
|
+
http.set_local_addresses(socket_opts.ipv4_address, socket_opts.ipv6_address);
|
|
261
|
+
#[cfg(any(
|
|
262
|
+
target_os = "android",
|
|
263
|
+
target_os = "fuchsia",
|
|
264
|
+
target_os = "illumos",
|
|
265
|
+
target_os = "ios",
|
|
266
|
+
target_os = "linux",
|
|
267
|
+
target_os = "macos",
|
|
268
|
+
target_os = "solaris",
|
|
269
|
+
target_os = "tvos",
|
|
270
|
+
target_os = "visionos",
|
|
271
|
+
target_os = "watchos",
|
|
272
|
+
))]
|
|
273
|
+
if let Some(interface) = &socket_opts.interface {
|
|
274
|
+
http.set_interface(interface.clone());
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Prefer TLS options from metadata, fallback to default
|
|
279
|
+
let tls = descriptor
|
|
280
|
+
.tls_options()
|
|
281
|
+
.map(|opts| self.builder.build(Cow::Borrowed(opts)))
|
|
282
|
+
.transpose()?
|
|
283
|
+
.unwrap_or_else(|| self.tls.clone());
|
|
284
|
+
|
|
285
|
+
Ok(HttpsConnector::new(http, tls))
|
|
286
|
+
}
|
|
287
|
+
|
|
248
288
|
fn tunnel_conn_from_stream<IO>(&self, io: MaybeHttpsStream<IO>) -> Result<Conn, BoxError>
|
|
249
289
|
where
|
|
250
290
|
IO: AsyncConnWithInfo,
|
|
@@ -252,13 +292,13 @@ impl ConnectorService {
|
|
|
252
292
|
SslStream<IO>: TlsInfoFactory,
|
|
253
293
|
{
|
|
254
294
|
let conn = match io {
|
|
255
|
-
MaybeHttpsStream::Http(
|
|
256
|
-
|
|
295
|
+
MaybeHttpsStream::Http(stream) => Conn {
|
|
296
|
+
stream: self.config.verbose.wrap(stream),
|
|
257
297
|
tls_info: false,
|
|
258
298
|
proxy: None,
|
|
259
299
|
},
|
|
260
|
-
MaybeHttpsStream::Https(
|
|
261
|
-
|
|
300
|
+
MaybeHttpsStream::Https(stream) => Conn {
|
|
301
|
+
stream: self.config.verbose.wrap(TlsConn { stream }),
|
|
262
302
|
tls_info: self.config.tls_info,
|
|
263
303
|
proxy: None,
|
|
264
304
|
},
|
|
@@ -275,111 +315,63 @@ impl ConnectorService {
|
|
|
275
315
|
P: Into<Option<Intercept>>,
|
|
276
316
|
{
|
|
277
317
|
let conn = match io {
|
|
278
|
-
MaybeHttpsStream::Http(
|
|
279
|
-
MaybeHttpsStream::Https(
|
|
318
|
+
MaybeHttpsStream::Http(stream) => self.config.verbose.wrap(stream),
|
|
319
|
+
MaybeHttpsStream::Https(stream) => self.config.verbose.wrap(TlsConn { stream }),
|
|
280
320
|
};
|
|
281
321
|
|
|
282
322
|
Ok(Conn {
|
|
283
|
-
|
|
323
|
+
stream: conn,
|
|
284
324
|
tls_info: self.config.tls_info,
|
|
285
325
|
proxy: proxy.into(),
|
|
286
326
|
})
|
|
287
327
|
}
|
|
288
328
|
|
|
289
|
-
fn
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
// Disable Nagle's algorithm for TLS handshake
|
|
296
|
-
//
|
|
297
|
-
// https://www.openssl.org/docs/man1.1.1/man3/SSL_connect.html#NOTES
|
|
298
|
-
if !self.config.tcp_nodelay {
|
|
299
|
-
http.set_nodelay(true);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// Apply TCP options if provided in metadata
|
|
303
|
-
if let Some(opts) = extra.tcp_options() {
|
|
304
|
-
http.set_connect_options(opts.clone());
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
self.build_tls_connector_generic(http, extra)
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
#[cfg(unix)]
|
|
311
|
-
fn build_unix_connector(
|
|
312
|
-
&self,
|
|
313
|
-
unix_socket: Arc<Path>,
|
|
314
|
-
extra: &ConnectExtra,
|
|
315
|
-
) -> Result<HttpsConnector<UnixConnector>, BoxError> {
|
|
316
|
-
// Create a Unix connector with the specified socket path
|
|
317
|
-
self.build_tls_connector_generic(UnixConnector(unix_socket), extra)
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
fn build_tls_connector_generic<S, T>(
|
|
321
|
-
&self,
|
|
322
|
-
connector: S,
|
|
323
|
-
extra: &ConnectExtra,
|
|
324
|
-
) -> Result<HttpsConnector<S>, BoxError>
|
|
325
|
-
where
|
|
326
|
-
S: Service<Uri, Response = T> + Send,
|
|
327
|
-
S::Error: Into<BoxError>,
|
|
328
|
-
S::Future: Unpin + Send + 'static,
|
|
329
|
-
T: AsyncRead + AsyncWrite + Connection + Unpin + std::fmt::Debug + Sync + Send + 'static,
|
|
330
|
-
{
|
|
331
|
-
// Prefer TLS options from metadata, fallback to default
|
|
332
|
-
let tls = extra
|
|
333
|
-
.tls_options()
|
|
334
|
-
.map(|opts| self.tls_builder.build(opts))
|
|
335
|
-
.transpose()?
|
|
336
|
-
.unwrap_or_else(|| self.tls.clone());
|
|
337
|
-
|
|
338
|
-
Ok(HttpsConnector::with_connector(connector, tls))
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
impl ConnectorService {
|
|
343
|
-
async fn connect_auto_proxy<P>(self, req: ConnectRequest, proxy: P) -> Result<Conn, BoxError>
|
|
344
|
-
where
|
|
345
|
-
P: Into<Option<Intercept>>,
|
|
346
|
-
{
|
|
329
|
+
async fn connect_auto_proxy<P: Into<Option<Intercept>>>(
|
|
330
|
+
self,
|
|
331
|
+
descriptor: ConnectionDescriptor,
|
|
332
|
+
proxy: P,
|
|
333
|
+
) -> Result<Conn, BoxError> {
|
|
334
|
+
let is_https = descriptor.uri().is_https();
|
|
347
335
|
let proxy = proxy.into();
|
|
336
|
+
|
|
348
337
|
trace!("connect with maybe proxy: {:?}", proxy);
|
|
349
338
|
|
|
350
|
-
let mut connector = self.build_https_connector(
|
|
339
|
+
let mut connector = self.build_https_connector(is_https, &descriptor)?;
|
|
351
340
|
|
|
352
341
|
// When using a proxy for HTTPS targets, disable ALPN to avoid protocol negotiation issues
|
|
353
|
-
if proxy.is_some() &&
|
|
342
|
+
if proxy.is_some() && is_https {
|
|
354
343
|
connector.no_alpn();
|
|
355
344
|
}
|
|
356
345
|
|
|
357
|
-
let io = connector.call(
|
|
346
|
+
let io = connector.call(descriptor).await?;
|
|
358
347
|
|
|
359
348
|
// Re-enable Nagle's algorithm if it was disabled earlier
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
349
|
+
if_tokio_rt!(block:{
|
|
350
|
+
if is_https && !self.config.nodelay {
|
|
351
|
+
io.as_ref().set_nodelay(false)?;
|
|
352
|
+
}
|
|
353
|
+
});
|
|
363
354
|
|
|
364
355
|
self.conn_from_stream(io, proxy)
|
|
365
356
|
}
|
|
366
357
|
|
|
367
358
|
async fn connect_via_proxy(
|
|
368
359
|
self,
|
|
369
|
-
mut
|
|
360
|
+
mut descriptor: ConnectionDescriptor,
|
|
370
361
|
proxy: Intercepted,
|
|
371
362
|
) -> Result<Conn, BoxError> {
|
|
372
|
-
let uri =
|
|
363
|
+
let uri = descriptor.uri().clone();
|
|
373
364
|
|
|
374
365
|
match proxy {
|
|
375
366
|
Intercepted::Proxy(proxy) => {
|
|
367
|
+
let is_https = uri.is_https();
|
|
376
368
|
let proxy_uri = proxy.uri().clone();
|
|
377
369
|
|
|
378
370
|
#[cfg(feature = "socks")]
|
|
379
371
|
{
|
|
380
372
|
use proxy::socks::{DnsResolve, SocksConnector, Version};
|
|
381
373
|
|
|
382
|
-
if let Some((version, dns_resolve)) = match
|
|
374
|
+
if let Some((version, dns_resolve)) = match proxy_uri.scheme_str() {
|
|
383
375
|
Some("socks4") => Some((Version::V4, DnsResolve::Local)),
|
|
384
376
|
Some("socks4a") => Some((Version::V4, DnsResolve::Remote)),
|
|
385
377
|
Some("socks5") => Some((Version::V5, DnsResolve::Local)),
|
|
@@ -391,7 +383,7 @@ impl ConnectorService {
|
|
|
391
383
|
// Connect to the proxy and establish the SOCKS connection.
|
|
392
384
|
let conn = {
|
|
393
385
|
// Build a SOCKS connector.
|
|
394
|
-
let mut socks = SocksConnector::
|
|
386
|
+
let mut socks = SocksConnector::new(
|
|
395
387
|
proxy_uri,
|
|
396
388
|
self.http.clone(),
|
|
397
389
|
self.resolver.clone(),
|
|
@@ -403,26 +395,29 @@ impl ConnectorService {
|
|
|
403
395
|
};
|
|
404
396
|
|
|
405
397
|
// Build an HTTPS connector.
|
|
406
|
-
let mut connector = self.build_https_connector(
|
|
398
|
+
let mut connector = self.build_https_connector(is_https, &descriptor)?;
|
|
407
399
|
|
|
408
400
|
// Wrap the established SOCKS connection with TLS if needed.
|
|
409
|
-
let io = connector
|
|
401
|
+
let io = connector
|
|
402
|
+
.call(EstablishedConn::new(conn, descriptor))
|
|
403
|
+
.await?;
|
|
410
404
|
|
|
411
405
|
// Re-enable Nagle's algorithm if it was disabled earlier
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
406
|
+
if_tokio_rt!(block:{
|
|
407
|
+
if is_https && !self.config.nodelay {
|
|
408
|
+
io.as_ref().set_nodelay(false)?;
|
|
409
|
+
}
|
|
410
|
+
});
|
|
415
411
|
|
|
416
412
|
return self.tunnel_conn_from_stream(io);
|
|
417
413
|
}
|
|
418
414
|
}
|
|
419
415
|
|
|
420
|
-
|
|
421
|
-
if uri.is_https() {
|
|
416
|
+
if is_https {
|
|
422
417
|
trace!("tunneling over HTTP(s) proxy: {:?}", proxy_uri);
|
|
423
418
|
|
|
424
419
|
// Build an HTTPS connector.
|
|
425
|
-
let mut connector = self.build_https_connector(
|
|
420
|
+
let mut connector = self.build_https_connector(is_https, &descriptor)?;
|
|
426
421
|
|
|
427
422
|
// Build a tunnel connector to establish the CONNECT tunnel.
|
|
428
423
|
let tunneled = {
|
|
@@ -444,18 +439,22 @@ impl ConnectorService {
|
|
|
444
439
|
};
|
|
445
440
|
|
|
446
441
|
// Wrap the established tunneled stream with TLS.
|
|
447
|
-
let io = connector
|
|
442
|
+
let io = connector
|
|
443
|
+
.call(EstablishedConn::new(tunneled, descriptor))
|
|
444
|
+
.await?;
|
|
448
445
|
|
|
449
446
|
// Re-enable Nagle's algorithm if it was disabled earlier
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
447
|
+
if_tokio_rt!(block:{
|
|
448
|
+
if !self.config.nodelay {
|
|
449
|
+
io.as_ref().as_ref().set_nodelay(false)?;
|
|
450
|
+
}
|
|
451
|
+
});
|
|
453
452
|
|
|
454
453
|
return self.tunnel_conn_from_stream(io);
|
|
455
454
|
}
|
|
456
455
|
|
|
457
|
-
*
|
|
458
|
-
self.connect_auto_proxy(
|
|
456
|
+
*descriptor.uri_mut() = proxy_uri;
|
|
457
|
+
self.connect_auto_proxy(descriptor, proxy)
|
|
459
458
|
.await
|
|
460
459
|
.map_err(ProxyConnect)
|
|
461
460
|
.map_err(Into::into)
|
|
@@ -465,18 +464,20 @@ impl ConnectorService {
|
|
|
465
464
|
trace!("connecting via Unix socket: {:?}", unix_socket);
|
|
466
465
|
|
|
467
466
|
// Create a Unix connector with the specified socket path.
|
|
468
|
-
let mut connector =
|
|
467
|
+
let mut connector =
|
|
468
|
+
HttpsConnector::new(UnixConnector::new(unix_socket), self.tls.clone());
|
|
469
469
|
|
|
470
470
|
// If the target URI is HTTPS, establish a CONNECT tunnel over the Unix socket,
|
|
471
471
|
// then upgrade the tunneled stream to TLS.
|
|
472
472
|
if uri.is_https() {
|
|
473
473
|
// Use a dummy HTTP URI so the HTTPS connector works over the Unix socket.
|
|
474
|
-
let proxy_uri = Uri::from_static("http://localhost");
|
|
474
|
+
let proxy_uri = http::Uri::from_static("http://localhost");
|
|
475
475
|
|
|
476
476
|
// The tunnel connector will first establish a CONNECT tunnel,
|
|
477
477
|
// then perform the TLS handshake over the tunneled stream.
|
|
478
478
|
let tunneled = {
|
|
479
|
-
// Create a tunnel connector using the Unix socket and the HTTPS
|
|
479
|
+
// Create a tunnel connector using the Unix socket and the HTTPS
|
|
480
|
+
// connector.
|
|
480
481
|
let mut tunnel =
|
|
481
482
|
proxy::tunnel::TunnelConnector::new(proxy_uri, connector.clone());
|
|
482
483
|
|
|
@@ -484,20 +485,22 @@ impl ConnectorService {
|
|
|
484
485
|
};
|
|
485
486
|
|
|
486
487
|
// Wrap the established tunneled stream with TLS.
|
|
487
|
-
let io = connector
|
|
488
|
+
let io = connector
|
|
489
|
+
.call(EstablishedConn::new(tunneled, descriptor))
|
|
490
|
+
.await?;
|
|
488
491
|
|
|
489
492
|
return self.tunnel_conn_from_stream(io);
|
|
490
493
|
}
|
|
491
494
|
|
|
492
495
|
// For plain HTTP, use the Unix connector directly.
|
|
493
|
-
let io = connector.call(
|
|
496
|
+
let io = connector.call(descriptor).await?;
|
|
494
497
|
|
|
495
498
|
self.conn_from_stream(io, None)
|
|
496
499
|
}
|
|
497
500
|
}
|
|
498
501
|
}
|
|
499
502
|
|
|
500
|
-
async fn connect_auto(self, req:
|
|
503
|
+
async fn connect_auto(self, req: ConnectionDescriptor) -> Result<Conn, BoxError> {
|
|
501
504
|
debug!("starting new connection: {:?}", req.uri());
|
|
502
505
|
|
|
503
506
|
let timeout = self.config.timeout;
|
|
@@ -505,8 +508,7 @@ impl ConnectorService {
|
|
|
505
508
|
// Determine if a proxy should be used for this request.
|
|
506
509
|
let fut = async {
|
|
507
510
|
let intercepted = req
|
|
508
|
-
.
|
|
509
|
-
.proxy_matcher()
|
|
511
|
+
.proxy()
|
|
510
512
|
.and_then(|prox| prox.intercept(req.uri()))
|
|
511
513
|
.or_else(|| {
|
|
512
514
|
self.config
|
|
@@ -532,7 +534,7 @@ impl ConnectorService {
|
|
|
532
534
|
}
|
|
533
535
|
}
|
|
534
536
|
|
|
535
|
-
impl Service<
|
|
537
|
+
impl Service<ConnectionDescriptor> for ConnectorService {
|
|
536
538
|
type Response = Conn;
|
|
537
539
|
type Error = BoxError;
|
|
538
540
|
type Future = Connecting;
|
|
@@ -543,7 +545,7 @@ impl Service<ConnectRequest> for ConnectorService {
|
|
|
543
545
|
}
|
|
544
546
|
|
|
545
547
|
#[inline]
|
|
546
|
-
fn call(&mut self,
|
|
547
|
-
Box::pin(self.clone().connect_auto(
|
|
548
|
+
fn call(&mut self, descriptor: ConnectionDescriptor) -> Self::Future {
|
|
549
|
+
Box::pin(self.clone().connect_auto(descriptor))
|
|
548
550
|
}
|
|
549
551
|
}
|