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
@@ -2,8 +2,6 @@
2
2
 
3
3
  #[macro_use]
4
4
  mod macros;
5
- mod cache;
6
- mod cert_compression;
7
5
  mod ext;
8
6
  mod service;
9
7
 
@@ -16,42 +14,36 @@ use std::{
16
14
  task::{Context, Poll},
17
15
  };
18
16
 
19
- use boring2::{
17
+ use btls::{
20
18
  error::ErrorStack,
21
19
  ex_data::Index,
22
20
  ssl::{Ssl, SslConnector, SslMethod, SslOptions, SslSessionCacheMode},
23
21
  };
24
- use cache::{SessionCache, SessionKey};
25
- use http::Uri;
22
+ use ext::SslConnectorBuilderExt;
23
+ use http::{Uri, Version};
26
24
  use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
27
- use tokio_boring2::SslStream;
28
- use tower::Service;
25
+ use tokio_btls::SslStream;
26
+ use tower::{BoxError, Service};
29
27
 
30
28
  use crate::{
31
29
  Error,
32
- client::{ConnectIdentity, ConnectRequest, Connected, Connection},
33
- error::BoxError,
34
- sync::Mutex,
30
+ conn::{Connected, Connection, descriptor::ConnectionDescriptor},
35
31
  tls::{
36
- AlpnProtocol, AlpsProtocol, CertStore, Identity, KeyLog, TlsOptions, TlsVersion,
37
- conn::ext::SslConnectorBuilderExt,
32
+ AlpnProtocol, AlpsProtocol, KeyShare, TlsOptions, TlsVersion,
33
+ keylog::KeyLog,
34
+ session::{Key, LruTlsSessionCache, TlsSession, TlsSessionCache},
35
+ trust::{CertStore, Identity},
38
36
  },
39
37
  };
40
38
 
41
- fn key_index() -> Result<Index<Ssl, SessionKey<ConnectIdentity>>, ErrorStack> {
42
- static IDX: LazyLock<Result<Index<Ssl, SessionKey<ConnectIdentity>>, ErrorStack>> =
43
- LazyLock::new(Ssl::new_ex_index);
39
+ fn key_index() -> Result<Index<Ssl, Key>, ErrorStack> {
40
+ static IDX: LazyLock<Result<Index<Ssl, Key>, ErrorStack>> = LazyLock::new(Ssl::new_ex_index);
44
41
  IDX.clone()
45
42
  }
46
43
 
47
- /// Builds for [`HandshakeConfig`].
48
- pub struct HandshakeConfigBuilder {
49
- settings: HandshakeConfig,
50
- }
51
-
52
44
  /// Settings for [`TlsConnector`]
53
45
  #[derive(Clone)]
54
- pub struct HandshakeConfig {
46
+ pub struct HandshakeSettings {
55
47
  no_ticket: bool,
56
48
  enable_ech_grease: bool,
57
49
  verify_hostname: bool,
@@ -59,112 +51,19 @@ pub struct HandshakeConfig {
59
51
  alpn_protocols: Option<Cow<'static, [AlpnProtocol]>>,
60
52
  alps_protocols: Option<Cow<'static, [AlpsProtocol]>>,
61
53
  alps_use_new_codepoint: bool,
54
+ key_shares: Option<Cow<'static, [KeyShare]>>,
62
55
  random_aes_hw_override: bool,
63
56
  }
64
57
 
65
- impl HandshakeConfigBuilder {
66
- /// Skips the session ticket.
67
- pub fn no_ticket(mut self, skip: bool) -> Self {
68
- self.settings.no_ticket = skip;
69
- self
70
- }
71
-
72
- /// Enables or disables ECH grease.
73
- pub fn enable_ech_grease(mut self, enable: bool) -> Self {
74
- self.settings.enable_ech_grease = enable;
75
- self
76
- }
77
-
78
- /// Sets hostname verification.
79
- pub fn verify_hostname(mut self, verify: bool) -> Self {
80
- self.settings.verify_hostname = verify;
81
- self
82
- }
83
-
84
- /// Sets TLS SNI.
85
- pub fn tls_sni(mut self, sni: bool) -> Self {
86
- self.settings.tls_sni = sni;
87
- self
88
- }
89
-
90
- /// Sets ALPN protocols.
91
- pub fn alpn_protocols<P>(mut self, alpn_protocols: P) -> Self
92
- where
93
- P: Into<Option<Cow<'static, [AlpnProtocol]>>>,
94
- {
95
- self.settings.alpn_protocols = alpn_protocols.into();
96
- self
97
- }
98
-
99
- /// Sets ALPS protocol.
100
- pub fn alps_protocols<P>(mut self, alps_protocols: P) -> Self
101
- where
102
- P: Into<Option<Cow<'static, [AlpsProtocol]>>>,
103
- {
104
- self.settings.alps_protocols = alps_protocols.into();
105
- self
106
- }
107
-
108
- /// Sets ALPS new codepoint usage.
109
- pub fn alps_use_new_codepoint(mut self, use_new: bool) -> Self {
110
- self.settings.alps_use_new_codepoint = use_new;
111
- self
112
- }
113
-
114
- /// Sets random AES hardware override.
115
- pub fn random_aes_hw_override(mut self, override_: bool) -> Self {
116
- self.settings.random_aes_hw_override = override_;
117
- self
118
- }
119
-
120
- /// Builds the `HandshakeConfig`.
121
- pub fn build(self) -> HandshakeConfig {
122
- self.settings
123
- }
124
- }
125
-
126
- impl HandshakeConfig {
127
- /// Creates a new `HandshakeConfigBuilder`.
128
- pub fn builder() -> HandshakeConfigBuilder {
129
- HandshakeConfigBuilder {
130
- settings: HandshakeConfig::default(),
131
- }
132
- }
133
- }
134
-
135
- impl Default for HandshakeConfig {
136
- fn default() -> Self {
137
- Self {
138
- no_ticket: false,
139
- enable_ech_grease: false,
140
- verify_hostname: true,
141
- tls_sni: true,
142
- alpn_protocols: None,
143
- alps_protocols: None,
144
- alps_use_new_codepoint: false,
145
- random_aes_hw_override: false,
146
- }
147
- }
148
- }
149
-
150
58
  /// A Connector using BoringSSL to support `http` and `https` schemes.
151
59
  #[derive(Clone)]
152
60
  pub struct HttpsConnector<T> {
153
61
  http: T,
154
- inner: Inner,
155
- }
156
-
157
- #[derive(Clone)]
158
- struct Inner {
159
- ssl: SslConnector,
160
- cache: Option<Arc<Mutex<SessionCache<ConnectIdentity>>>>,
161
- config: HandshakeConfig,
62
+ tls: TlsConnector,
162
63
  }
163
64
 
164
65
  /// A builder for creating a `TlsConnector`.
165
- #[derive(Clone)]
166
66
  pub struct TlsConnectorBuilder {
167
- session_cache: Arc<Mutex<SessionCache<ConnectIdentity>>>,
168
67
  alpn_protocol: Option<AlpnProtocol>,
169
68
  max_version: Option<TlsVersion>,
170
69
  min_version: Option<TlsVersion>,
@@ -174,12 +73,15 @@ pub struct TlsConnectorBuilder {
174
73
  cert_store: Option<CertStore>,
175
74
  cert_verification: bool,
176
75
  keylog: Option<KeyLog>,
76
+ session_cache: Arc<dyn TlsSessionCache>,
177
77
  }
178
78
 
179
79
  /// A layer which wraps services in an `SslConnector`.
180
80
  #[derive(Clone)]
181
81
  pub struct TlsConnector {
182
- inner: Inner,
82
+ ssl: SslConnector,
83
+ cache: Option<Arc<dyn TlsSessionCache>>,
84
+ settings: HandshakeSettings,
183
85
  }
184
86
 
185
87
  // ===== impl HttpsConnector =====
@@ -193,24 +95,37 @@ where
193
95
  {
194
96
  /// Creates a new [`HttpsConnector`] with a given [`TlsConnector`].
195
97
  #[inline]
196
- pub fn with_connector(http: S, connector: TlsConnector) -> HttpsConnector<S> {
197
- HttpsConnector {
198
- http,
199
- inner: connector.inner,
200
- }
98
+ pub fn new(http: S, tls: TlsConnector) -> HttpsConnector<S> {
99
+ HttpsConnector { http, tls }
201
100
  }
202
101
 
203
102
  /// Disables ALPN negotiation.
204
103
  #[inline]
205
104
  pub fn no_alpn(&mut self) -> &mut Self {
206
- self.inner.config.alpn_protocols = None;
105
+ self.tls.settings.alpn_protocols = None;
207
106
  self
208
107
  }
209
108
  }
210
109
 
211
- // ===== impl Inner =====
110
+ // ===== impl TlsConnector =====
111
+
112
+ impl TlsConnector {
113
+ /// Creates a new [`TlsConnectorBuilder`] with the given configuration.
114
+ pub fn builder() -> TlsConnectorBuilder {
115
+ TlsConnectorBuilder {
116
+ alpn_protocol: None,
117
+ min_version: None,
118
+ max_version: None,
119
+ identity: None,
120
+ tls_sni: true,
121
+ verify_hostname: true,
122
+ cert_store: None,
123
+ cert_verification: true,
124
+ keylog: None,
125
+ session_cache: Arc::new(LruTlsSessionCache::new(8)),
126
+ }
127
+ }
212
128
 
213
- impl Inner {
214
129
  fn setup_ssl(&self, uri: Uri) -> Result<Ssl, BoxError> {
215
130
  let cfg = self.ssl.configure()?;
216
131
  let host = uri.host().ok_or("URI missing host")?;
@@ -219,63 +134,80 @@ impl Inner {
219
134
  Ok(ssl)
220
135
  }
221
136
 
222
- fn setup_ssl2(&self, req: ConnectRequest) -> Result<Ssl, BoxError> {
137
+ fn setup_ssl2(&self, descriptor: ConnectionDescriptor) -> Result<Ssl, BoxError> {
223
138
  let mut cfg = self.ssl.configure()?;
224
139
 
225
140
  // Use server name indication
226
- cfg.set_use_server_name_indication(self.config.tls_sni);
141
+ cfg.set_use_server_name_indication(self.settings.tls_sni);
227
142
 
228
143
  // Verify hostname
229
- cfg.set_verify_hostname(self.config.verify_hostname);
144
+ cfg.set_verify_hostname(self.settings.verify_hostname);
230
145
 
231
146
  // Set ECH grease
232
- cfg.set_enable_ech_grease(self.config.enable_ech_grease);
147
+ cfg.set_enable_ech_grease(self.settings.enable_ech_grease);
233
148
 
234
149
  // Set random AES hardware override
235
- if self.config.random_aes_hw_override {
150
+ if self.settings.random_aes_hw_override {
236
151
  let random = (crate::util::fast_random() & 1) == 0;
237
152
  cfg.set_aes_hw_override(random);
238
153
  }
239
154
 
155
+ // Set ALPN protocols
156
+ if let Some(version) = descriptor.version() {
157
+ match version {
158
+ Version::HTTP_11 | Version::HTTP_10 | Version::HTTP_09 => {
159
+ cfg.set_alpn_protos(&AlpnProtocol::HTTP1.encode())?;
160
+ }
161
+ Version::HTTP_2 => {
162
+ cfg.set_alpn_protos(&AlpnProtocol::HTTP2.encode())?;
163
+ }
164
+ Version::HTTP_3 => {
165
+ cfg.set_alpn_protos(&AlpnProtocol::HTTP3.encode())?;
166
+ }
167
+ _ => {
168
+ // For unknown versions, we don't set any ALPN protocols.
169
+ }
170
+ }
171
+ } else {
172
+ // Default use the connector configuration.
173
+ if let Some(ref alpn_values) = self.settings.alpn_protocols {
174
+ let encoded = AlpnProtocol::encode_sequence(alpn_values.as_ref());
175
+ cfg.set_alpn_protos(&encoded)?;
176
+ }
177
+ }
178
+
240
179
  // Set ALPS protos
241
- if let Some(ref alps_values) = self.config.alps_protocols {
180
+ if let Some(ref alps_values) = self.settings.alps_protocols {
242
181
  for alps in alps_values.iter() {
243
182
  cfg.add_application_settings(alps.0)?;
244
183
  }
245
184
 
246
- // By default, the old endpoint is used.
247
- if !alps_values.is_empty() && self.config.alps_use_new_codepoint {
248
- cfg.set_alps_use_new_codepoint(true);
185
+ // By default, the new endpoint is used.
186
+ if !alps_values.is_empty() {
187
+ cfg.set_alps_use_new_codepoint(self.settings.alps_use_new_codepoint);
249
188
  }
250
189
  }
251
190
 
252
- // Set ALPN protocols
253
- if let Some(alpn) = req.extra().alpn_protocol() {
254
- // If ALPN is set in the request, it takes precedence over the connector configuration.
255
- cfg.set_alpn_protos(&alpn.encode())?;
256
- } else {
257
- // Default use the connector configuration.
258
- if let Some(ref alpn_values) = self.config.alpn_protocols {
259
- let encoded = AlpnProtocol::encode_sequence(alpn_values.as_ref());
260
- cfg.set_alpn_protos(&encoded)?;
261
- }
191
+ // Set TLS key shares
192
+ if let Some(ref key_shares) = self.settings.key_shares {
193
+ cfg.set_client_key_shares(key_shares.as_ref())?;
262
194
  }
263
195
 
264
- let uri = req.uri().clone();
196
+ let uri = descriptor.uri().clone();
265
197
  let host = uri.host().ok_or("URI missing host")?;
266
198
  let host = Self::normalize_host(host);
267
199
 
268
200
  if let Some(ref cache) = self.cache {
269
- let key = SessionKey(req.identify());
201
+ let key = Key(descriptor.id());
270
202
 
271
203
  // If the session cache is enabled, we try to retrieve the session
272
204
  // associated with the key. If it exists, we set it in the SSL configuration.
273
- if let Some(session) = cache.lock().get(&key) {
205
+ if let Some(session) = cache.pop(&key) {
274
206
  #[allow(unsafe_code)]
275
- unsafe { cfg.set_session(&session) }?;
207
+ unsafe { cfg.set_session(&session.0) }?;
276
208
 
277
- if self.config.no_ticket {
278
- cfg.set_options(SslOptions::NO_TICKET)?;
209
+ if self.settings.no_ticket {
210
+ cfg.set_options(SslOptions::NO_TICKET);
279
211
  }
280
212
  }
281
213
 
@@ -283,8 +215,7 @@ impl Inner {
283
215
  cfg.set_ex_data(idx, key);
284
216
  }
285
217
 
286
- let ssl = cfg.into_ssl(host)?;
287
- Ok(ssl)
218
+ Ok(cfg.into_ssl(host)?)
288
219
  }
289
220
 
290
221
  /// If `host` is an IPv6 address, we must strip away the square brackets that surround
@@ -312,28 +243,28 @@ impl Inner {
312
243
 
313
244
  impl TlsConnectorBuilder {
314
245
  /// Sets the alpn protocol to be used.
315
- #[inline(always)]
246
+ #[inline]
316
247
  pub fn alpn_protocol(mut self, protocol: Option<AlpnProtocol>) -> Self {
317
248
  self.alpn_protocol = protocol;
318
249
  self
319
250
  }
320
251
 
321
252
  /// Sets the TLS keylog policy.
322
- #[inline(always)]
253
+ #[inline]
323
254
  pub fn keylog(mut self, keylog: Option<KeyLog>) -> Self {
324
255
  self.keylog = keylog;
325
256
  self
326
257
  }
327
258
 
328
259
  /// Sets the identity to be used for client certificate authentication.
329
- #[inline(always)]
260
+ #[inline]
330
261
  pub fn identity(mut self, identity: Option<Identity>) -> Self {
331
262
  self.identity = identity;
332
263
  self
333
264
  }
334
265
 
335
266
  /// Sets the certificate store used for TLS verification.
336
- #[inline(always)]
267
+ #[inline]
337
268
  pub fn cert_store<T>(mut self, cert_store: T) -> Self
338
269
  where
339
270
  T: Into<Option<CertStore>>,
@@ -343,14 +274,14 @@ impl TlsConnectorBuilder {
343
274
  }
344
275
 
345
276
  /// Sets the certificate verification flag.
346
- #[inline(always)]
277
+ #[inline]
347
278
  pub fn cert_verification(mut self, enabled: bool) -> Self {
348
279
  self.cert_verification = enabled;
349
280
  self
350
281
  }
351
282
 
352
283
  /// Sets the minimum TLS version to use.
353
- #[inline(always)]
284
+ #[inline]
354
285
  pub fn min_version<T>(mut self, version: T) -> Self
355
286
  where
356
287
  T: Into<Option<TlsVersion>>,
@@ -360,7 +291,7 @@ impl TlsConnectorBuilder {
360
291
  }
361
292
 
362
293
  /// Sets the maximum TLS version to use.
363
- #[inline(always)]
294
+ #[inline]
364
295
  pub fn max_version<T>(mut self, version: T) -> Self
365
296
  where
366
297
  T: Into<Option<TlsVersion>>,
@@ -370,21 +301,35 @@ impl TlsConnectorBuilder {
370
301
  }
371
302
 
372
303
  /// Sets the Server Name Indication (SNI) flag.
373
- #[inline(always)]
304
+ #[inline]
374
305
  pub fn tls_sni(mut self, enabled: bool) -> Self {
375
306
  self.tls_sni = enabled;
376
307
  self
377
308
  }
378
309
 
379
310
  /// Sets the hostname verification flag.
380
- #[inline(always)]
311
+ #[inline]
381
312
  pub fn verify_hostname(mut self, enabled: bool) -> Self {
382
313
  self.verify_hostname = enabled;
383
314
  self
384
315
  }
385
316
 
317
+ /// Sets a custom TLS session store.
318
+ #[inline]
319
+ pub fn session_store(mut self, store: Option<Arc<dyn TlsSessionCache>>) -> Self {
320
+ if let Some(store) = store {
321
+ self.session_cache = store;
322
+ }
323
+ self
324
+ }
325
+
386
326
  /// Build the `TlsConnector` with the provided configuration.
387
- pub fn build(&self, opts: &TlsOptions) -> crate::Result<TlsConnector> {
327
+ pub fn build<'a, T>(&self, opts: T) -> crate::Result<TlsConnector>
328
+ where
329
+ T: Into<Cow<'a, TlsOptions>>,
330
+ {
331
+ let opts = opts.into();
332
+
388
333
  // Replace the default configuration with the provided one
389
334
  let max_tls_version = opts.max_tls_version.or(self.max_version);
390
335
  let min_tls_version = opts.min_tls_version.or(self.min_version);
@@ -394,18 +339,12 @@ impl TlsConnectorBuilder {
394
339
  .or_else(|| opts.alpn_protocols.clone());
395
340
 
396
341
  // Create the SslConnector with the provided options
397
- let mut connector = SslConnector::no_default_verify_builder(SslMethod::tls_client())
342
+ let mut connector = SslConnector::bare_builder(SslMethod::tls())
398
343
  .map_err(Error::tls)?
344
+ .set_identity(self.identity.as_ref())?
399
345
  .set_cert_store(self.cert_store.as_ref())?
400
- .set_cert_verification(self.cert_verification)?
401
- .add_certificate_compression_algorithms(
402
- opts.certificate_compression_algorithms.as_deref(),
403
- )?;
404
-
405
- // Set Identity
406
- if let Some(ref identity) = self.identity {
407
- identity.add_to_tls(&mut connector)?;
408
- }
346
+ .set_cert_verification(self.cert_verification)
347
+ .set_cert_compressors(opts.certificate_compressors.as_deref())?;
409
348
 
410
349
  // Set minimum TLS version
411
350
  set_option_inner_try!(min_tls_version, connector, set_min_proto_version);
@@ -485,9 +424,6 @@ impl TlsConnectorBuilder {
485
424
  // Set TLS record size limit
486
425
  set_option!(opts, record_size_limit, connector, set_record_size_limit);
487
426
 
488
- // Set TLS key shares limit
489
- set_option!(opts, key_shares_limit, connector, set_key_shares_limit);
490
-
491
427
  // Set TLS aes hardware override
492
428
  set_option!(opts, aes_hw_override, connector, set_aes_hw_override);
493
429
 
@@ -506,68 +442,44 @@ impl TlsConnectorBuilder {
506
442
  });
507
443
  }
508
444
 
509
- // Create the handshake config with the default session cache capacity.
510
- let config = HandshakeConfig::builder()
511
- .no_ticket(opts.psk_skip_session_ticket)
512
- .alpn_protocols(alpn_protocols)
513
- .alps_protocols(opts.alps_protocols.clone())
514
- .alps_use_new_codepoint(opts.alps_use_new_codepoint)
515
- .enable_ech_grease(opts.enable_ech_grease)
516
- .tls_sni(self.tls_sni)
517
- .verify_hostname(self.verify_hostname)
518
- .random_aes_hw_override(opts.random_aes_hw_override)
519
- .build();
445
+ // Create the handshake settings with the default session cache capacity.
446
+ let settings = HandshakeSettings {
447
+ tls_sni: self.tls_sni,
448
+ verify_hostname: self.verify_hostname,
449
+ no_ticket: opts.psk_skip_session_ticket,
450
+ alpn_protocols,
451
+ alps_protocols: opts.alps_protocols.clone(),
452
+ alps_use_new_codepoint: opts.alps_use_new_codepoint,
453
+ enable_ech_grease: opts.enable_ech_grease,
454
+ key_shares: opts.key_shares.clone(),
455
+ random_aes_hw_override: opts.random_aes_hw_override,
456
+ };
520
457
 
521
458
  // If the session cache is disabled, we don't need to set up any callbacks.
522
459
  let cache = opts.pre_shared_key.then(|| {
523
- let cache = self.session_cache.clone();
460
+ let session_cache = self.session_cache.clone();
524
461
 
525
462
  connector.set_session_cache_mode(SslSessionCacheMode::CLIENT);
526
463
  connector.set_new_session_callback({
527
- let cache = cache.clone();
464
+ let cache = session_cache.clone();
528
465
  move |ssl, session| {
529
466
  if let Ok(Some(key)) = key_index().map(|idx| ssl.ex_data(idx)) {
530
- cache.lock().insert(key.clone(), session);
467
+ cache.put(key.clone(), TlsSession(session));
531
468
  }
532
469
  }
533
470
  });
534
471
 
535
- cache
472
+ session_cache
536
473
  });
537
474
 
538
475
  Ok(TlsConnector {
539
- inner: Inner {
540
- ssl: connector.build(),
541
- cache,
542
- config,
543
- },
476
+ ssl: connector.build(),
477
+ cache,
478
+ settings,
544
479
  })
545
480
  }
546
481
  }
547
482
 
548
- // ===== impl TlsConnector =====
549
-
550
- impl TlsConnector {
551
- /// Creates a new `TlsConnectorBuilder` with the given configuration.
552
- pub fn builder() -> TlsConnectorBuilder {
553
- const DEFAULT_SESSION_CACHE_CAPACITY: usize = 8;
554
- TlsConnectorBuilder {
555
- session_cache: Arc::new(Mutex::new(SessionCache::with_capacity(
556
- DEFAULT_SESSION_CACHE_CAPACITY,
557
- ))),
558
- alpn_protocol: None,
559
- min_version: None,
560
- max_version: None,
561
- identity: None,
562
- cert_store: None,
563
- cert_verification: true,
564
- tls_sni: true,
565
- verify_hostname: true,
566
- keylog: None,
567
- }
568
- }
569
- }
570
-
571
483
  /// A stream which may be wrapped with TLS.
572
484
  pub enum MaybeHttpsStream<T> {
573
485
  /// A raw HTTP stream.
@@ -579,15 +491,14 @@ pub enum MaybeHttpsStream<T> {
579
491
  /// A connection that has been established with a TLS handshake.
580
492
  pub struct EstablishedConn<IO> {
581
493
  io: IO,
582
- req: ConnectRequest,
494
+ descriptor: ConnectionDescriptor,
583
495
  }
584
496
 
585
497
  // ===== impl MaybeHttpsStream =====
586
498
 
587
- impl<T> MaybeHttpsStream<T> {
588
- /// Returns a reference to the underlying stream.
499
+ impl<T> AsRef<T> for MaybeHttpsStream<T> {
589
500
  #[inline]
590
- pub fn get_ref(&self) -> &T {
501
+ fn as_ref(&self) -> &T {
591
502
  match self {
592
503
  MaybeHttpsStream::Http(s) => s,
593
504
  MaybeHttpsStream::Https(s) => s.get_ref(),
@@ -595,31 +506,24 @@ impl<T> MaybeHttpsStream<T> {
595
506
  }
596
507
  }
597
508
 
598
- impl<T> fmt::Debug for MaybeHttpsStream<T> {
599
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
600
- match *self {
601
- MaybeHttpsStream::Http(..) => f.pad("Http(..)"),
602
- MaybeHttpsStream::Https(..) => f.pad("Https(..)"),
603
- }
604
- }
605
- }
606
-
607
509
  impl<T> Connection for MaybeHttpsStream<T>
608
510
  where
609
511
  T: Connection,
610
512
  {
513
+ #[inline]
611
514
  fn connected(&self) -> Connected {
612
515
  match self {
613
516
  MaybeHttpsStream::Http(s) => s.connected(),
614
- MaybeHttpsStream::Https(s) => {
615
- let mut connected = s.get_ref().connected();
616
-
617
- if s.ssl().selected_alpn_protocol() == Some(b"h2") {
618
- connected = connected.negotiated_h2();
619
- }
517
+ MaybeHttpsStream::Https(s) => s.get_ref().connected(),
518
+ }
519
+ }
520
+ }
620
521
 
621
- connected
622
- }
522
+ impl<T> fmt::Debug for MaybeHttpsStream<T> {
523
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
524
+ match *self {
525
+ MaybeHttpsStream::Http(..) => f.pad("Http(..)"),
526
+ MaybeHttpsStream::Https(..) => f.pad("Https(..)"),
623
527
  }
624
528
  }
625
529
  }
@@ -628,6 +532,7 @@ impl<T> AsyncRead for MaybeHttpsStream<T>
628
532
  where
629
533
  T: AsyncRead + AsyncWrite + Unpin,
630
534
  {
535
+ #[inline]
631
536
  fn poll_read(
632
537
  mut self: Pin<&mut Self>,
633
538
  cx: &mut Context<'_>,
@@ -644,6 +549,7 @@ impl<T> AsyncWrite for MaybeHttpsStream<T>
644
549
  where
645
550
  T: AsyncRead + AsyncWrite + Unpin,
646
551
  {
552
+ #[inline]
647
553
  fn poll_write(
648
554
  mut self: Pin<&mut Self>,
649
555
  ctx: &mut Context<'_>,
@@ -655,6 +561,7 @@ where
655
561
  }
656
562
  }
657
563
 
564
+ #[inline]
658
565
  fn poll_flush(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<io::Result<()>> {
659
566
  match self.as_mut().get_mut() {
660
567
  MaybeHttpsStream::Http(inner) => Pin::new(inner).poll_flush(ctx),
@@ -662,12 +569,33 @@ where
662
569
  }
663
570
  }
664
571
 
572
+ #[inline]
665
573
  fn poll_shutdown(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<io::Result<()>> {
666
574
  match self.as_mut().get_mut() {
667
575
  MaybeHttpsStream::Http(inner) => Pin::new(inner).poll_shutdown(ctx),
668
576
  MaybeHttpsStream::Https(inner) => Pin::new(inner).poll_shutdown(ctx),
669
577
  }
670
578
  }
579
+
580
+ #[inline]
581
+ fn is_write_vectored(&self) -> bool {
582
+ match self {
583
+ MaybeHttpsStream::Http(inner) => inner.is_write_vectored(),
584
+ MaybeHttpsStream::Https(inner) => inner.is_write_vectored(),
585
+ }
586
+ }
587
+
588
+ #[inline]
589
+ fn poll_write_vectored(
590
+ self: Pin<&mut Self>,
591
+ cx: &mut Context<'_>,
592
+ bufs: &[io::IoSlice<'_>],
593
+ ) -> Poll<io::Result<usize>> {
594
+ match self.get_mut() {
595
+ MaybeHttpsStream::Http(inner) => Pin::new(inner).poll_write_vectored(cx, bufs),
596
+ MaybeHttpsStream::Https(inner) => Pin::new(inner).poll_write_vectored(cx, bufs),
597
+ }
598
+ }
671
599
  }
672
600
 
673
601
  // ===== impl EstablishedConn =====
@@ -675,7 +603,7 @@ where
675
603
  impl<IO> EstablishedConn<IO> {
676
604
  /// Creates a new [`EstablishedConn`].
677
605
  #[inline]
678
- pub fn new(io: IO, req: ConnectRequest) -> EstablishedConn<IO> {
679
- EstablishedConn { io, req }
606
+ pub fn new(io: IO, descriptor: ConnectionDescriptor) -> EstablishedConn<IO> {
607
+ EstablishedConn { io, descriptor }
680
608
  }
681
609
  }