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
@@ -1,342 +0,0 @@
1
- //! HTTP/1 client connections
2
-
3
- use std::{
4
- fmt,
5
- future::Future,
6
- pin::Pin,
7
- task::{Context, Poll, ready},
8
- };
9
-
10
- use bytes::Bytes;
11
- use http::{Request, Response};
12
- use http_body::Body;
13
- use httparse::ParserConfig;
14
- use tokio::io::{AsyncRead, AsyncWrite};
15
-
16
- use crate::client::core::{
17
- Error, Result,
18
- body::Incoming as IncomingBody,
19
- dispatch::{self, TrySendError},
20
- error::BoxError,
21
- http1::Http1Options,
22
- proto,
23
- };
24
-
25
- type Dispatcher<T, B> =
26
- proto::dispatch::Dispatcher<proto::dispatch::Client<B>, B, T, proto::h1::ClientTransaction>;
27
-
28
- /// The sender side of an established connection.
29
- pub struct SendRequest<B> {
30
- dispatch: dispatch::Sender<Request<B>, Response<IncomingBody>>,
31
- }
32
-
33
- /// Deconstructed parts of a `Connection`.
34
- ///
35
- /// This allows taking apart a `Connection` at a later time, in order to
36
- /// reclaim the IO object, and additional related pieces.
37
- #[derive(Debug)]
38
- #[non_exhaustive]
39
- pub struct Parts<T> {
40
- /// The original IO object used in the handshake.
41
- pub io: T,
42
- /// A buffer of bytes that have been read but not processed as HTTP.
43
- ///
44
- /// For instance, if the `Connection` is used for an HTTP upgrade request,
45
- /// it is possible the server sent back the first bytes of the new protocol
46
- /// along with the response upgrade.
47
- ///
48
- /// You will want to check for any existing bytes if you plan to continue
49
- /// communicating on the IO object.
50
- pub read_buf: Bytes,
51
- }
52
-
53
- /// A future that processes all HTTP state for the IO object.
54
- ///
55
- /// In most cases, this should just be spawned into an executor, so that it
56
- /// can process incoming and outgoing messages, notice hangups, and the like.
57
- #[must_use = "futures do nothing unless polled"]
58
- pub struct Connection<T, B>
59
- where
60
- T: AsyncRead + AsyncWrite,
61
- B: Body + 'static,
62
- {
63
- inner: Dispatcher<T, B>,
64
- }
65
-
66
- impl<T, B> Connection<T, B>
67
- where
68
- T: AsyncRead + AsyncWrite + Unpin,
69
- B: Body + 'static,
70
- B::Error: Into<BoxError>,
71
- {
72
- /// Return the inner IO object, and additional information.
73
- ///
74
- /// Only works for HTTP/1 connections. HTTP/2 connections will panic.
75
- pub fn into_parts(self) -> Parts<T> {
76
- let (io, read_buf, _) = self.inner.into_inner();
77
- Parts { io, read_buf }
78
- }
79
- }
80
-
81
- /// A builder to configure an HTTP connection.
82
- ///
83
- /// After setting options, the builder is used to create a handshake future.
84
- ///
85
- /// **Note**: The default values of options are *not considered stable*. They
86
- /// are subject to change at any time.
87
- #[derive(Clone, Debug)]
88
- pub struct Builder {
89
- opts: Http1Options,
90
- }
91
-
92
- // ===== impl SendRequest
93
-
94
- impl<B> SendRequest<B> {
95
- /// Polls to determine whether this sender can be used yet for a request.
96
- ///
97
- /// If the associated connection is closed, this returns an Error.
98
- pub fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<()>> {
99
- self.dispatch.poll_ready(cx)
100
- }
101
-
102
- /// Waits until the dispatcher is ready
103
- ///
104
- /// If the associated connection is closed, this returns an Error.
105
- pub async fn ready(&mut self) -> Result<()> {
106
- std::future::poll_fn(|cx| self.poll_ready(cx)).await
107
- }
108
-
109
- /// Checks if the connection is currently ready to send a request.
110
- ///
111
- /// # Note
112
- ///
113
- /// This is mostly a hint. Due to inherent latency of networks, it is
114
- /// possible that even after checking this is ready, sending a request
115
- /// may still fail because the connection was closed in the meantime.
116
- pub fn is_ready(&self) -> bool {
117
- self.dispatch.is_ready()
118
- }
119
- }
120
-
121
- impl<B> SendRequest<B>
122
- where
123
- B: Body + 'static,
124
- {
125
- /// Sends a `Request` on the associated connection.
126
- ///
127
- /// Returns a future that if successful, yields the `Response`.
128
- ///
129
- /// # Error
130
- ///
131
- /// If there was an error before trying to serialize the request to the
132
- /// connection, the message will be returned as part of this error.
133
- pub fn try_send_request(
134
- &mut self,
135
- req: Request<B>,
136
- ) -> impl Future<Output = std::result::Result<Response<IncomingBody>, TrySendError<Request<B>>>>
137
- {
138
- let sent = self.dispatch.try_send(req);
139
- async move {
140
- match sent {
141
- Ok(rx) => match rx.await {
142
- Ok(Ok(res)) => Ok(res),
143
- Ok(Err(err)) => Err(err),
144
- // this is definite bug if it happens, but it shouldn't happen!
145
- Err(_) => panic!("dispatch dropped without returning error"),
146
- },
147
- Err(req) => {
148
- debug!("connection was not ready");
149
- let error = Error::new_canceled().with("connection was not ready");
150
- Err(TrySendError {
151
- error,
152
- message: Some(req),
153
- })
154
- }
155
- }
156
- }
157
- }
158
- }
159
-
160
- impl<B> fmt::Debug for SendRequest<B> {
161
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162
- f.debug_struct("SendRequest").finish()
163
- }
164
- }
165
-
166
- // ===== impl Connection
167
-
168
- impl<T, B> Connection<T, B>
169
- where
170
- T: AsyncRead + AsyncWrite + Unpin + Send,
171
- B: Body + 'static,
172
- B::Error: Into<BoxError>,
173
- {
174
- /// Enable this connection to support higher-level HTTP upgrades.
175
- pub fn with_upgrades(self) -> upgrades::UpgradeableConnection<T, B> {
176
- upgrades::UpgradeableConnection { inner: Some(self) }
177
- }
178
- }
179
-
180
- impl<T, B> fmt::Debug for Connection<T, B>
181
- where
182
- T: AsyncRead + AsyncWrite + fmt::Debug,
183
- B: Body + 'static,
184
- {
185
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186
- f.debug_struct("Connection").finish()
187
- }
188
- }
189
-
190
- impl<T, B> Future for Connection<T, B>
191
- where
192
- T: AsyncRead + AsyncWrite + Unpin,
193
- B: Body + 'static,
194
- B::Data: Send,
195
- B::Error: Into<BoxError>,
196
- {
197
- type Output = Result<()>;
198
-
199
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
200
- match ready!(Pin::new(&mut self.inner).poll(cx))? {
201
- proto::Dispatched::Shutdown => Poll::Ready(Ok(())),
202
- proto::Dispatched::Upgrade(pending) => {
203
- // With no `Send` bound on `I`, we can't try to do
204
- // upgrades here. In case a user was trying to use
205
- // `upgrade` with this API, send a special
206
- // error letting them know about that.
207
- pending.manual();
208
- Poll::Ready(Ok(()))
209
- }
210
- }
211
- }
212
- }
213
-
214
- // ===== impl Builder
215
-
216
- impl Default for Builder {
217
- fn default() -> Self {
218
- Self::new()
219
- }
220
- }
221
-
222
- impl Builder {
223
- /// Creates a new connection builder.
224
- #[inline]
225
- pub fn new() -> Builder {
226
- Builder {
227
- opts: Default::default(),
228
- }
229
- }
230
-
231
- /// Provide a options configuration for the HTTP/1 connection.
232
- #[inline]
233
- pub fn options(&mut self, opts: Http1Options) {
234
- self.opts = opts;
235
- }
236
-
237
- /// Constructs a connection with the configured options and IO.
238
- ///
239
- /// Note, if [`Connection`] is not `await`-ed, [`SendRequest`] will
240
- /// do nothing.
241
- pub async fn handshake<T, B>(self, io: T) -> Result<(SendRequest<B>, Connection<T, B>)>
242
- where
243
- T: AsyncRead + AsyncWrite + Unpin,
244
- B: Body + 'static,
245
- B::Data: Send,
246
- B::Error: Into<BoxError>,
247
- {
248
- trace!("client handshake HTTP/1");
249
-
250
- let (tx, rx) = dispatch::channel();
251
- let mut conn = proto::Conn::new(io);
252
-
253
- // Set the HTTP/1 parser configuration
254
- let h1_parser_config = {
255
- let mut h1_parser_config = ParserConfig::default();
256
- h1_parser_config
257
- .ignore_invalid_headers_in_responses(self.opts.ignore_invalid_headers_in_responses)
258
- .allow_spaces_after_header_name_in_responses(
259
- self.opts.allow_spaces_after_header_name_in_responses,
260
- )
261
- .allow_obsolete_multiline_headers_in_responses(
262
- self.opts.allow_obsolete_multiline_headers_in_responses,
263
- );
264
- h1_parser_config
265
- };
266
- conn.set_h1_parser_config(h1_parser_config);
267
-
268
- // Set the h1 write strategy
269
- if let Some(writev) = self.opts.h1_writev {
270
- if writev {
271
- conn.set_write_strategy_queue();
272
- } else {
273
- conn.set_write_strategy_flatten();
274
- }
275
- }
276
-
277
- // Set the maximum size of the request headers
278
- if let Some(max_headers) = self.opts.h1_max_headers {
279
- conn.set_http1_max_headers(max_headers);
280
- }
281
-
282
- // Enable HTTP/0.9 responses if requested
283
- if self.opts.h09_responses {
284
- conn.set_h09_responses();
285
- }
286
-
287
- // Set the read buffer size if specified
288
- if let Some(sz) = self.opts.h1_read_buf_exact_size {
289
- conn.set_read_buf_exact_size(sz);
290
- }
291
-
292
- // Set the maximum buffer size for HTTP/1 connections
293
- if let Some(max) = self.opts.h1_max_buf_size {
294
- conn.set_max_buf_size(max);
295
- }
296
-
297
- let cd = proto::h1::dispatch::Client::new(rx);
298
- let proto = proto::h1::Dispatcher::new(cd, conn);
299
-
300
- Ok((SendRequest { dispatch: tx }, Connection { inner: proto }))
301
- }
302
- }
303
-
304
- mod upgrades {
305
- use super::*;
306
- use crate::client::core::upgrade::Upgraded;
307
-
308
- // A future binding a connection with a Service with Upgrade support.
309
- //
310
- // This type is unnameable outside the crate.
311
- #[must_use = "futures do nothing unless polled"]
312
- pub struct UpgradeableConnection<T, B>
313
- where
314
- T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
315
- B: Body + 'static,
316
- B::Error: Into<BoxError>,
317
- {
318
- pub(super) inner: Option<Connection<T, B>>,
319
- }
320
-
321
- impl<I, B> Future for UpgradeableConnection<I, B>
322
- where
323
- I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
324
- B: Body + 'static,
325
- B::Data: Send,
326
- B::Error: Into<BoxError>,
327
- {
328
- type Output = Result<()>;
329
-
330
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
331
- match ready!(Pin::new(&mut self.inner.as_mut().unwrap().inner).poll(cx)) {
332
- Ok(proto::Dispatched::Shutdown) => Poll::Ready(Ok(())),
333
- Ok(proto::Dispatched::Upgrade(pending)) => {
334
- let Parts { io, read_buf } = self.inner.take().unwrap().into_parts();
335
- pending.fulfill(Upgraded::new(io, read_buf));
336
- Poll::Ready(Ok(()))
337
- }
338
- Err(e) => Poll::Ready(Err(e)),
339
- }
340
- }
341
- }
342
- }
@@ -1,307 +0,0 @@
1
- //! HTTP/2 client connections
2
-
3
- use std::{
4
- fmt,
5
- future::Future,
6
- marker::PhantomData,
7
- pin::Pin,
8
- task::{Context, Poll, ready},
9
- };
10
-
11
- use http::{Request, Response};
12
- use http_body::Body;
13
- use tokio::io::{AsyncRead, AsyncWrite};
14
-
15
- use crate::{
16
- client::core::{
17
- Result,
18
- body::Incoming as IncomingBody,
19
- dispatch::{self, TrySendError},
20
- error::{BoxError, Error},
21
- proto::{self, h2::ping},
22
- rt::{ArcTimer, Time, Timer, bounds::Http2ClientConnExec},
23
- },
24
- http2::Http2Options,
25
- };
26
-
27
- /// The sender side of an established connection.
28
- pub struct SendRequest<B> {
29
- dispatch: dispatch::UnboundedSender<Request<B>, Response<IncomingBody>>,
30
- }
31
-
32
- impl<B> Clone for SendRequest<B> {
33
- fn clone(&self) -> SendRequest<B> {
34
- SendRequest {
35
- dispatch: self.dispatch.clone(),
36
- }
37
- }
38
- }
39
-
40
- /// A future that processes all HTTP state for the IO object.
41
- ///
42
- /// In most cases, this should just be spawned into an executor, so that it
43
- /// can process incoming and outgoing messages, notice hangups, and the like.
44
- #[must_use = "futures do nothing unless polled"]
45
- pub struct Connection<T, B, E>
46
- where
47
- T: AsyncRead + AsyncWrite + Unpin,
48
- B: Body + 'static,
49
- E: Http2ClientConnExec<B, T> + Unpin,
50
- B::Error: Into<BoxError>,
51
- {
52
- inner: (PhantomData<T>, proto::h2::ClientTask<B, E, T>),
53
- }
54
-
55
- /// A builder to configure an HTTP connection.
56
- ///
57
- /// After setting options, the builder is used to create a handshake future.
58
- ///
59
- /// **Note**: The default values of options are *not considered stable*. They
60
- /// are subject to change at any time.
61
- #[derive(Clone)]
62
- pub struct Builder<Ex> {
63
- exec: Ex,
64
- timer: Time,
65
- opts: Http2Options,
66
- }
67
-
68
- // ===== impl SendRequest
69
-
70
- impl<B> SendRequest<B> {
71
- /// Polls to determine whether this sender can be used yet for a request.
72
- ///
73
- /// If the associated connection is closed, this returns an Error.
74
- pub fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<()>> {
75
- if self.is_closed() {
76
- Poll::Ready(Err(Error::new_closed()))
77
- } else {
78
- Poll::Ready(Ok(()))
79
- }
80
- }
81
-
82
- /// Waits until the dispatcher is ready
83
- ///
84
- /// If the associated connection is closed, this returns an Error.
85
- pub async fn ready(&mut self) -> Result<()> {
86
- std::future::poll_fn(|cx| self.poll_ready(cx)).await
87
- }
88
-
89
- /// Checks if the connection is currently ready to send a request.
90
- ///
91
- /// # Note
92
- ///
93
- /// This is mostly a hint. Due to inherent latency of networks, it is
94
- /// possible that even after checking this is ready, sending a request
95
- /// may still fail because the connection was closed in the meantime.
96
- pub fn is_ready(&self) -> bool {
97
- self.dispatch.is_ready()
98
- }
99
-
100
- /// Checks if the connection side has been closed.
101
- pub fn is_closed(&self) -> bool {
102
- self.dispatch.is_closed()
103
- }
104
- }
105
-
106
- impl<B> SendRequest<B>
107
- where
108
- B: Body + 'static,
109
- {
110
- /// Sends a `Request` on the associated connection.
111
- ///
112
- /// Returns a future that if successful, yields the `Response`.
113
- ///
114
- /// # Error
115
- ///
116
- /// If there was an error before trying to serialize the request to the
117
- /// connection, the message will be returned as part of this error.
118
- pub fn try_send_request(
119
- &mut self,
120
- req: Request<B>,
121
- ) -> impl Future<Output = std::result::Result<Response<IncomingBody>, TrySendError<Request<B>>>>
122
- {
123
- let sent = self.dispatch.try_send(req);
124
- async move {
125
- match sent {
126
- Ok(rx) => match rx.await {
127
- Ok(Ok(res)) => Ok(res),
128
- Ok(Err(err)) => Err(err),
129
- // this is definite bug if it happens, but it shouldn't happen!
130
- Err(_) => panic!("dispatch dropped without returning error"),
131
- },
132
- Err(req) => {
133
- debug!("connection was not ready");
134
- let error = Error::new_canceled().with("connection was not ready");
135
- Err(TrySendError {
136
- error,
137
- message: Some(req),
138
- })
139
- }
140
- }
141
- }
142
- }
143
- }
144
-
145
- impl<B> fmt::Debug for SendRequest<B> {
146
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147
- f.debug_struct("SendRequest").finish()
148
- }
149
- }
150
-
151
- // ===== impl Connection
152
-
153
- impl<T, B, E> fmt::Debug for Connection<T, B, E>
154
- where
155
- T: AsyncRead + AsyncWrite + fmt::Debug + 'static + Unpin,
156
- B: Body + 'static,
157
- E: Http2ClientConnExec<B, T> + Unpin,
158
- B::Error: Into<BoxError>,
159
- {
160
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161
- f.debug_struct("Connection").finish()
162
- }
163
- }
164
-
165
- impl<T, B, E> Future for Connection<T, B, E>
166
- where
167
- T: AsyncRead + AsyncWrite + Unpin + 'static,
168
- B: Body + 'static + Unpin,
169
- B::Data: Send,
170
- E: Unpin,
171
- B::Error: Into<BoxError>,
172
- E: Http2ClientConnExec<B, T> + Unpin,
173
- {
174
- type Output = Result<()>;
175
-
176
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
177
- match ready!(Pin::new(&mut self.inner.1).poll(cx))? {
178
- proto::Dispatched::Shutdown => Poll::Ready(Ok(())),
179
- proto::Dispatched::Upgrade(_pending) => unreachable!("http2 cannot upgrade"),
180
- }
181
- }
182
- }
183
-
184
- // ===== impl Builder
185
-
186
- impl<Ex> Builder<Ex>
187
- where
188
- Ex: Clone,
189
- {
190
- /// Creates a new connection builder.
191
- #[inline]
192
- pub fn new(exec: Ex) -> Builder<Ex> {
193
- Builder {
194
- exec,
195
- timer: Time::Empty,
196
- opts: Default::default(),
197
- }
198
- }
199
-
200
- /// Provide a timer to execute background HTTP2 tasks.
201
- #[inline]
202
- pub fn timer<M>(&mut self, timer: M)
203
- where
204
- M: Timer + Send + Sync + 'static,
205
- {
206
- self.timer = Time::Timer(ArcTimer::new(timer));
207
- }
208
-
209
- /// Provide a options configuration for the HTTP/2 connection.
210
- #[inline]
211
- pub fn options(&mut self, opts: Http2Options) {
212
- self.opts = opts;
213
- }
214
-
215
- /// Constructs a connection with the configured options and IO.
216
- ///
217
- /// Note, if [`Connection`] is not `await`-ed, [`SendRequest`] will
218
- /// do nothing.
219
- pub async fn handshake<T, B>(self, io: T) -> Result<(SendRequest<B>, Connection<T, B, Ex>)>
220
- where
221
- T: AsyncRead + AsyncWrite + Unpin,
222
- B: Body + 'static,
223
- B::Data: Send,
224
- B::Error: Into<BoxError>,
225
- Ex: Http2ClientConnExec<B, T> + Unpin,
226
- {
227
- trace!("client handshake HTTP/2");
228
-
229
- // Crate the HTTP/2 client with the provided options.
230
- let builder = {
231
- let mut builder = http2::client::Builder::default();
232
- builder
233
- .initial_max_send_streams(self.opts.initial_max_send_streams)
234
- .initial_window_size(self.opts.initial_window_size)
235
- .initial_connection_window_size(self.opts.initial_conn_window_size)
236
- .max_send_buffer_size(self.opts.max_send_buffer_size);
237
- if let Some(id) = self.opts.initial_stream_id {
238
- builder.initial_stream_id(id);
239
- }
240
- if let Some(max) = self.opts.max_pending_accept_reset_streams {
241
- builder.max_pending_accept_reset_streams(max);
242
- }
243
- if let Some(max) = self.opts.max_concurrent_reset_streams {
244
- builder.max_concurrent_reset_streams(max);
245
- }
246
- if let Some(max) = self.opts.max_concurrent_streams {
247
- builder.max_concurrent_streams(max);
248
- }
249
- if let Some(max) = self.opts.max_header_list_size {
250
- builder.max_header_list_size(max);
251
- }
252
- if let Some(opt) = self.opts.enable_push {
253
- builder.enable_push(opt);
254
- }
255
- if let Some(max) = self.opts.max_frame_size {
256
- builder.max_frame_size(max);
257
- }
258
- if let Some(max) = self.opts.header_table_size {
259
- builder.header_table_size(max);
260
- }
261
- if let Some(v) = self.opts.enable_connect_protocol {
262
- builder.enable_connect_protocol(v);
263
- }
264
- if let Some(v) = self.opts.no_rfc7540_priorities {
265
- builder.no_rfc7540_priorities(v);
266
- }
267
- if let Some(order) = self.opts.settings_order {
268
- builder.settings_order(order);
269
- }
270
- if let Some(experimental_settings) = self.opts.experimental_settings {
271
- builder.experimental_settings(experimental_settings);
272
- }
273
- if let Some(stream_dependency) = self.opts.headers_stream_dependency {
274
- builder.headers_stream_dependency(stream_dependency);
275
- }
276
- if let Some(order) = self.opts.headers_pseudo_order {
277
- builder.headers_pseudo_order(order);
278
- }
279
- if let Some(priority) = self.opts.priorities {
280
- builder.priorities(priority);
281
- }
282
-
283
- builder
284
- };
285
-
286
- // Create the ping configuration for the connection.
287
- let ping_config = ping::Config::new(
288
- self.opts.adaptive_window,
289
- self.opts.initial_window_size,
290
- self.opts.keep_alive_interval,
291
- self.opts.keep_alive_timeout,
292
- self.opts.keep_alive_while_idle,
293
- );
294
-
295
- let (tx, rx) = dispatch::channel();
296
- let h2 = proto::h2::client::handshake(io, rx, builder, ping_config, self.exec, self.timer)
297
- .await?;
298
- Ok((
299
- SendRequest {
300
- dispatch: tx.unbound(),
301
- },
302
- Connection {
303
- inner: (PhantomData, h2),
304
- },
305
- ))
306
- }
307
- }
@@ -1,11 +0,0 @@
1
- //! Lower-level client connection API.
2
- //!
3
- //! The types in this module are to provide a lower-level API based around a
4
- //! single connection. Connecting to a host, pooling connections, and the like
5
- //! are not handled at this level. This module provides the building blocks to
6
- //! customize those things externally.
7
-
8
- pub mod http1;
9
- pub mod http2;
10
-
11
- pub use super::dispatch::TrySendError;