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.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1922 -397
  3. data/LICENSE +203 -0
  4. data/README.md +19 -15
  5. data/ext/wreq_rb/Cargo.toml +4 -6
  6. data/ext/wreq_rb/src/client.rs +41 -48
  7. data/lib/wreq-rb/version.rb +1 -1
  8. data/patches/0001-add-transfer-size-tracking.patch +76 -67
  9. data/vendor/wreq/Cargo.toml +119 -71
  10. data/vendor/wreq/README.md +25 -20
  11. data/vendor/wreq/bench/http1.rs +25 -0
  12. data/vendor/wreq/bench/http1_over_tls.rs +25 -0
  13. data/vendor/wreq/bench/http2.rs +25 -0
  14. data/vendor/wreq/bench/http2_over_tls.rs +25 -0
  15. data/vendor/wreq/bench/support/bench.rs +91 -0
  16. data/vendor/wreq/bench/support/client.rs +217 -0
  17. data/vendor/wreq/bench/support/server.rs +188 -0
  18. data/vendor/wreq/bench/support.rs +56 -0
  19. data/vendor/wreq/examples/cert_store.rs +4 -4
  20. data/vendor/wreq/examples/{emulation.rs → emulate.rs} +2 -2
  21. data/vendor/wreq/examples/http2_websocket.rs +2 -2
  22. data/vendor/wreq/examples/keylog.rs +3 -3
  23. data/vendor/wreq/examples/{request_with_emulation.rs → request_with_emulate.rs} +2 -2
  24. data/vendor/wreq/examples/rt.rs +23 -0
  25. data/vendor/wreq/src/client/body.rs +23 -61
  26. data/vendor/wreq/src/client/emulate.rs +119 -0
  27. data/vendor/wreq/src/client/{http/future.rs → future.rs} +11 -32
  28. data/vendor/wreq/src/client/{http → layer}/client/pool.rs +66 -61
  29. data/vendor/wreq/src/client/{http → layer}/client.rs +416 -270
  30. data/vendor/wreq/src/client/layer/config.rs +27 -6
  31. data/vendor/wreq/src/client/layer/decoder.rs +9 -4
  32. data/vendor/wreq/src/client/layer/redirect/future.rs +6 -3
  33. data/vendor/wreq/src/client/layer/redirect.rs +4 -5
  34. data/vendor/wreq/src/client/layer/retry.rs +8 -5
  35. data/vendor/wreq/src/client/layer/timeout/body.rs +15 -6
  36. data/vendor/wreq/src/client/layer/timeout/future.rs +23 -18
  37. data/vendor/wreq/src/client/layer/timeout.rs +24 -74
  38. data/vendor/wreq/src/client/layer.rs +1 -2
  39. data/vendor/wreq/src/client/multipart.rs +137 -154
  40. data/vendor/wreq/src/client/request.rs +202 -118
  41. data/vendor/wreq/src/client/response.rs +46 -45
  42. data/vendor/wreq/src/client/upgrade.rs +15 -0
  43. data/vendor/wreq/src/client/ws.rs +73 -25
  44. data/vendor/wreq/src/client.rs +1655 -17
  45. data/vendor/wreq/src/config.rs +11 -11
  46. data/vendor/wreq/src/{client/conn → conn}/connector.rs +139 -137
  47. data/vendor/wreq/src/conn/descriptor.rs +143 -0
  48. data/vendor/wreq/src/conn/http.rs +484 -0
  49. data/vendor/wreq/src/conn/net/io.rs +75 -0
  50. data/vendor/wreq/src/conn/net/tcp/compio.rs +71 -0
  51. data/vendor/wreq/src/conn/net/tcp/tokio.rs +57 -0
  52. data/vendor/wreq/src/conn/net/tcp.rs +561 -0
  53. data/vendor/wreq/src/conn/net/uds/compio.rs +60 -0
  54. data/vendor/wreq/src/{client/conn/uds.rs → conn/net/uds/tokio.rs} +18 -12
  55. data/vendor/wreq/src/conn/net/uds.rs +11 -0
  56. data/vendor/wreq/src/conn/net.rs +130 -0
  57. data/vendor/wreq/src/{client/conn → conn}/proxy/socks.rs +2 -9
  58. data/vendor/wreq/src/{client/conn → conn}/proxy/tunnel.rs +21 -56
  59. data/vendor/wreq/src/conn/tls_info.rs +47 -0
  60. data/vendor/wreq/src/{client/conn.rs → conn.rs} +202 -54
  61. data/vendor/wreq/src/cookie.rs +302 -142
  62. data/vendor/wreq/src/dns/gai/compio.rs +77 -0
  63. data/vendor/wreq/src/dns/gai/tokio.rs +90 -0
  64. data/vendor/wreq/src/dns/gai.rs +14 -164
  65. data/vendor/wreq/src/dns/hickory.rs +16 -23
  66. data/vendor/wreq/src/dns/resolve.rs +7 -41
  67. data/vendor/wreq/src/dns.rs +90 -7
  68. data/vendor/wreq/src/error.rs +57 -31
  69. data/vendor/wreq/src/ext.rs +25 -0
  70. data/vendor/wreq/src/group.rs +211 -0
  71. data/vendor/wreq/src/header.rs +100 -112
  72. data/vendor/wreq/src/lib.rs +124 -73
  73. data/vendor/wreq/src/proxy.rs +6 -20
  74. data/vendor/wreq/src/redirect.rs +1 -1
  75. data/vendor/wreq/src/rt.rs +208 -0
  76. data/vendor/wreq/src/sync.rs +97 -98
  77. data/vendor/wreq/src/tls/compress.rs +124 -0
  78. data/vendor/wreq/src/tls/conn/ext.rs +54 -45
  79. data/vendor/wreq/src/tls/conn/service.rs +14 -18
  80. data/vendor/wreq/src/tls/conn.rs +169 -241
  81. data/vendor/wreq/src/tls/keylog.rs +68 -5
  82. data/vendor/wreq/src/tls/session.rs +205 -0
  83. data/vendor/wreq/src/tls/{x509 → trust}/identity.rs +4 -21
  84. data/vendor/wreq/src/tls/{x509/parser.rs → trust/parse.rs} +1 -1
  85. data/vendor/wreq/src/tls/{x509 → trust}/store.rs +42 -81
  86. data/vendor/wreq/src/tls/{x509.rs → trust.rs} +8 -2
  87. data/vendor/wreq/src/tls.rs +489 -25
  88. data/vendor/wreq/src/trace.rs +0 -12
  89. data/vendor/wreq/src/util.rs +1 -1
  90. data/vendor/wreq/tests/badssl.rs +10 -10
  91. data/vendor/wreq/tests/client.rs +3 -9
  92. data/vendor/wreq/tests/cookie.rs +6 -8
  93. data/vendor/wreq/tests/{emulation.rs → emulate.rs} +130 -22
  94. data/vendor/wreq/tests/multipart.rs +43 -1
  95. data/vendor/wreq/tests/proxy.rs +1 -1
  96. data/vendor/wreq/tests/support/layer.rs +1 -0
  97. metadata +49 -71
  98. data/patches/0002-add-cancel-connections.patch +0 -181
  99. data/vendor/wreq/src/client/conn/conn.rs +0 -231
  100. data/vendor/wreq/src/client/conn/http.rs +0 -1023
  101. data/vendor/wreq/src/client/conn/tls_info.rs +0 -98
  102. data/vendor/wreq/src/client/core/body/incoming.rs +0 -485
  103. data/vendor/wreq/src/client/core/body/length.rs +0 -118
  104. data/vendor/wreq/src/client/core/body.rs +0 -34
  105. data/vendor/wreq/src/client/core/common/buf.rs +0 -149
  106. data/vendor/wreq/src/client/core/common/rewind.rs +0 -141
  107. data/vendor/wreq/src/client/core/common/watch.rs +0 -76
  108. data/vendor/wreq/src/client/core/common.rs +0 -3
  109. data/vendor/wreq/src/client/core/conn/http1.rs +0 -342
  110. data/vendor/wreq/src/client/core/conn/http2.rs +0 -307
  111. data/vendor/wreq/src/client/core/conn.rs +0 -11
  112. data/vendor/wreq/src/client/core/dispatch.rs +0 -299
  113. data/vendor/wreq/src/client/core/error.rs +0 -435
  114. data/vendor/wreq/src/client/core/ext.rs +0 -201
  115. data/vendor/wreq/src/client/core/http1.rs +0 -178
  116. data/vendor/wreq/src/client/core/http2.rs +0 -483
  117. data/vendor/wreq/src/client/core/proto/h1/conn.rs +0 -988
  118. data/vendor/wreq/src/client/core/proto/h1/decode.rs +0 -1170
  119. data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +0 -684
  120. data/vendor/wreq/src/client/core/proto/h1/encode.rs +0 -580
  121. data/vendor/wreq/src/client/core/proto/h1/io.rs +0 -879
  122. data/vendor/wreq/src/client/core/proto/h1/role.rs +0 -694
  123. data/vendor/wreq/src/client/core/proto/h1.rs +0 -104
  124. data/vendor/wreq/src/client/core/proto/h2/client.rs +0 -650
  125. data/vendor/wreq/src/client/core/proto/h2/ping.rs +0 -539
  126. data/vendor/wreq/src/client/core/proto/h2.rs +0 -379
  127. data/vendor/wreq/src/client/core/proto/headers.rs +0 -138
  128. data/vendor/wreq/src/client/core/proto.rs +0 -58
  129. data/vendor/wreq/src/client/core/rt/bounds.rs +0 -57
  130. data/vendor/wreq/src/client/core/rt/timer.rs +0 -150
  131. data/vendor/wreq/src/client/core/rt/tokio.rs +0 -99
  132. data/vendor/wreq/src/client/core/rt.rs +0 -25
  133. data/vendor/wreq/src/client/core/upgrade.rs +0 -267
  134. data/vendor/wreq/src/client/core.rs +0 -16
  135. data/vendor/wreq/src/client/emulation.rs +0 -161
  136. data/vendor/wreq/src/client/http/client/error.rs +0 -142
  137. data/vendor/wreq/src/client/http/client/exec.rs +0 -29
  138. data/vendor/wreq/src/client/http/client/extra.rs +0 -77
  139. data/vendor/wreq/src/client/http/client/util.rs +0 -104
  140. data/vendor/wreq/src/client/http.rs +0 -1629
  141. data/vendor/wreq/src/client/layer/config/options.rs +0 -156
  142. data/vendor/wreq/src/client/layer/cookie.rs +0 -161
  143. data/vendor/wreq/src/hash.rs +0 -143
  144. data/vendor/wreq/src/tls/conn/cache.rs +0 -123
  145. data/vendor/wreq/src/tls/conn/cert_compression.rs +0 -125
  146. data/vendor/wreq/src/tls/keylog/handle.rs +0 -64
  147. data/vendor/wreq/src/tls/options.rs +0 -464
  148. /data/vendor/wreq/src/client/{http → layer}/client/lazy.rs +0 -0
  149. /data/vendor/wreq/src/{client/conn → conn}/proxy.rs +0 -0
  150. /data/vendor/wreq/src/{client/conn → conn}/verbose.rs +0 -0
@@ -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 http::Uri;
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::uds::UnixConnector;
18
+ use super::net::UnixConnector;
22
19
  use super::{
23
- AsyncConnWithInfo, BoxedConnectorLayer, BoxedConnectorService, Connection, HttpConnector,
24
- TlsInfoFactory, Unnameable,
25
- conn::{Conn, TlsConn},
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::{BoxError, ProxyConnect, TimedOut, map_timeout_to_connector_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
- tcp_nodelay: bool,
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
- tls_options: TlsOptions,
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
- tls_builder: Arc<TlsConnectorBuilder>,
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.tls_builder = call(self.tls_builder);
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 TLS options to use.
127
+ /// Sets the TCP_NODELAY option for connections.
135
128
  #[inline]
136
- pub fn tls_options(mut self, opts: Option<TlsOptions>) -> ConnectorBuilder {
137
- if let Some(opts) = opts {
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(self, layers: Vec<BoxedConnectorLayer>) -> crate::Result<Connector> {
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.tls_builder.build(&self.tls_options)?,
151
- tls_builder: Arc::new(self.tls_builder),
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 ConnectRequest for the
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
- tcp_nodelay: false,
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::new_with_resolver(resolver),
217
- tls_options: TlsOptions::default(),
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<ConnectRequest> for Connector {
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, req: ConnectRequest) -> Self::Future {
233
+ fn call(&mut self, descriptor: ConnectionDescriptor) -> Self::Future {
238
234
  match self {
239
- Connector::Simple(service) => service.call(req),
240
- Connector::WithLayers(service) => service.call(Unnameable(req)),
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(inner) => Conn {
256
- inner: self.config.verbose.wrap(inner),
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(inner) => Conn {
261
- inner: self.config.verbose.wrap(TlsConn::new(inner)),
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(inner) => self.config.verbose.wrap(inner),
279
- MaybeHttpsStream::Https(inner) => self.config.verbose.wrap(TlsConn::new(inner)),
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
- inner: conn,
323
+ stream: conn,
284
324
  tls_info: self.config.tls_info,
285
325
  proxy: proxy.into(),
286
326
  })
287
327
  }
288
328
 
289
- fn build_https_connector(
290
- &self,
291
- extra: &ConnectExtra,
292
- ) -> Result<HttpsConnector<HttpConnector>, BoxError> {
293
- let mut http = self.http.clone();
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(req.extra())?;
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() && req.uri().is_https() {
342
+ if proxy.is_some() && is_https {
354
343
  connector.no_alpn();
355
344
  }
356
345
 
357
- let io = connector.call(req).await?;
346
+ let io = connector.call(descriptor).await?;
358
347
 
359
348
  // Re-enable Nagle's algorithm if it was disabled earlier
360
- if !self.config.tcp_nodelay {
361
- io.get_ref().set_nodelay(false)?;
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 req: ConnectRequest,
360
+ mut descriptor: ConnectionDescriptor,
370
361
  proxy: Intercepted,
371
362
  ) -> Result<Conn, BoxError> {
372
- let uri = req.uri().clone();
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 proxy.uri().scheme_str() {
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::new_with_resolver(
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(req.extra())?;
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.call(EstablishedConn::new(conn, req)).await?;
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
- if !self.config.tcp_nodelay {
413
- io.get_ref().set_nodelay(false)?;
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
- // Handle HTTPS proxy tunneling connection
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(req.extra())?;
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.call(EstablishedConn::new(tunneled, req)).await?;
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
- if !self.config.tcp_nodelay {
451
- io.get_ref().get_ref().set_nodelay(false)?;
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
- *req.uri_mut() = proxy_uri;
458
- self.connect_auto_proxy(req, 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 = self.build_unix_connector(unix_socket, req.extra())?;
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 connector.
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.call(EstablishedConn::new(tunneled, req)).await?;
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(req).await?;
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: ConnectRequest) -> Result<Conn, BoxError> {
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
- .extra()
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<ConnectRequest> for ConnectorService {
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, req: ConnectRequest) -> Self::Future {
547
- Box::pin(self.clone().connect_auto(req))
548
+ fn call(&mut self, descriptor: ConnectionDescriptor) -> Self::Future {
549
+ Box::pin(self.clone().connect_auto(descriptor))
548
550
  }
549
551
  }