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,98 +0,0 @@
1
- use bytes::Bytes;
2
- use tokio::net::TcpStream;
3
- #[cfg(unix)]
4
- use tokio::net::UnixStream;
5
- use tokio_boring2::SslStream;
6
-
7
- use crate::tls::{TlsInfo, conn::MaybeHttpsStream};
8
-
9
- /// A trait for extracting TLS information from a connection.
10
- ///
11
- /// Implementors can provide access to peer certificate data or other TLS-related metadata.
12
- /// For non-TLS connections, this typically returns `None`.
13
- pub trait TlsInfoFactory {
14
- fn tls_info(&self) -> Option<TlsInfo>;
15
- }
16
-
17
- fn extract_tls_info<S>(ssl_stream: &SslStream<S>) -> TlsInfo {
18
- let ssl = ssl_stream.ssl();
19
- TlsInfo {
20
- peer_certificate: ssl
21
- .peer_certificate()
22
- .and_then(|cert| cert.to_der().ok())
23
- .map(Bytes::from),
24
- peer_certificate_chain: ssl.peer_cert_chain().map(|chain| {
25
- chain
26
- .iter()
27
- .filter_map(|cert| cert.to_der().ok())
28
- .map(Bytes::from)
29
- .collect()
30
- }),
31
- }
32
- }
33
-
34
- // ===== impl TcpStream =====
35
-
36
- impl TlsInfoFactory for TcpStream {
37
- fn tls_info(&self) -> Option<TlsInfo> {
38
- None
39
- }
40
- }
41
-
42
- impl TlsInfoFactory for SslStream<TcpStream> {
43
- #[inline]
44
- fn tls_info(&self) -> Option<TlsInfo> {
45
- Some(extract_tls_info(self))
46
- }
47
- }
48
-
49
- impl TlsInfoFactory for MaybeHttpsStream<TcpStream> {
50
- fn tls_info(&self) -> Option<TlsInfo> {
51
- match self {
52
- MaybeHttpsStream::Https(tls) => tls.tls_info(),
53
- MaybeHttpsStream::Http(_) => None,
54
- }
55
- }
56
- }
57
-
58
- impl TlsInfoFactory for SslStream<MaybeHttpsStream<TcpStream>> {
59
- #[inline]
60
- fn tls_info(&self) -> Option<TlsInfo> {
61
- Some(extract_tls_info(self))
62
- }
63
- }
64
-
65
- // ===== impl UnixStream =====
66
-
67
- #[cfg(unix)]
68
- impl TlsInfoFactory for UnixStream {
69
- fn tls_info(&self) -> Option<TlsInfo> {
70
- None
71
- }
72
- }
73
-
74
- #[cfg(unix)]
75
- impl TlsInfoFactory for SslStream<UnixStream> {
76
- #[inline]
77
- fn tls_info(&self) -> Option<TlsInfo> {
78
- Some(extract_tls_info(self))
79
- }
80
- }
81
-
82
- #[cfg(unix)]
83
- impl TlsInfoFactory for MaybeHttpsStream<UnixStream> {
84
- fn tls_info(&self) -> Option<TlsInfo> {
85
- match self {
86
- MaybeHttpsStream::Https(tls) => tls.tls_info(),
87
- MaybeHttpsStream::Http(_) => None,
88
- }
89
- }
90
- }
91
-
92
- #[cfg(unix)]
93
- impl TlsInfoFactory for SslStream<MaybeHttpsStream<UnixStream>> {
94
- #[inline]
95
- fn tls_info(&self) -> Option<TlsInfo> {
96
- Some(extract_tls_info(self))
97
- }
98
- }
@@ -1,485 +0,0 @@
1
- use std::{
2
- fmt,
3
- future::Future,
4
- pin::Pin,
5
- task::{Context, Poll, ready},
6
- };
7
-
8
- use bytes::Bytes;
9
- use futures_channel::{mpsc, oneshot};
10
- use futures_util::{Stream, stream::FusedStream};
11
- use http::HeaderMap;
12
- use http_body::{Body, Frame, SizeHint};
13
-
14
- use super::DecodedLength;
15
- use crate::client::core::{self, Error, common::watch, proto::h2::ping};
16
-
17
- type BodySender = mpsc::Sender<Result<Bytes, Error>>;
18
- type TrailersSender = oneshot::Sender<HeaderMap>;
19
-
20
- /// A stream of `Bytes`, used when receiving bodies from the network.
21
- ///
22
- /// Note that Users should not instantiate this struct directly. When working with the crate::core:
23
- /// client, `Incoming` is returned to you in responses.
24
- #[must_use = "streams do nothing unless polled"]
25
- pub struct Incoming {
26
- kind: Kind,
27
- }
28
-
29
- enum Kind {
30
- Empty,
31
- Chan {
32
- content_length: DecodedLength,
33
- want_tx: watch::Sender,
34
- data_rx: mpsc::Receiver<Result<Bytes, Error>>,
35
- trailers_rx: oneshot::Receiver<HeaderMap>,
36
- },
37
- H2 {
38
- content_length: DecodedLength,
39
- data_done: bool,
40
- ping: ping::Recorder,
41
- recv: http2::RecvStream,
42
- },
43
- }
44
-
45
- /// A sender half created through [`Body::channel()`].
46
- ///
47
- /// Useful when wanting to stream chunks from another thread.
48
- ///
49
- /// ## Body Closing
50
- ///
51
- /// Note that the request body will always be closed normally when the sender is dropped (meaning
52
- /// that the empty terminating chunk will be sent to the remote). If you desire to close the
53
- /// connection with an incomplete response (e.g. in the case of an error during asynchronous
54
- /// processing), call the [`Sender::abort()`] method to abort the body in an abnormal fashion.
55
- ///
56
- /// [`Body::channel()`]: struct.Body.html#method.channel
57
- /// [`Sender::abort()`]: struct.Sender.html#method.abort
58
- #[must_use = "Sender does nothing unless sent on"]
59
- pub(crate) struct Sender {
60
- want_rx: watch::Receiver,
61
- data_tx: BodySender,
62
- trailers_tx: Option<TrailersSender>,
63
- }
64
-
65
- const WANT_PENDING: usize = 1;
66
- const WANT_READY: usize = 2;
67
-
68
- impl Incoming {
69
- /// Create a `Body` stream with an associated sender half.
70
- ///
71
- /// Useful when wanting to stream chunks from another thread.
72
- #[inline]
73
- #[cfg(test)]
74
- pub(crate) fn channel() -> (Sender, Incoming) {
75
- Self::new_channel(DecodedLength::CHUNKED, /* wanter = */ false)
76
- }
77
-
78
- pub(crate) fn new_channel(content_length: DecodedLength, wanter: bool) -> (Sender, Incoming) {
79
- let (data_tx, data_rx) = mpsc::channel(0);
80
- let (trailers_tx, trailers_rx) = oneshot::channel();
81
-
82
- // If wanter is true, `Sender::poll_ready()` won't becoming ready
83
- // until the `Body` has been polled for data once.
84
- let want = if wanter { WANT_PENDING } else { WANT_READY };
85
-
86
- let (want_tx, want_rx) = watch::channel(want);
87
-
88
- let tx = Sender {
89
- want_rx,
90
- data_tx,
91
- trailers_tx: Some(trailers_tx),
92
- };
93
- let rx = Incoming::new(Kind::Chan {
94
- content_length,
95
- want_tx,
96
- data_rx,
97
- trailers_rx,
98
- });
99
-
100
- (tx, rx)
101
- }
102
-
103
- fn new(kind: Kind) -> Incoming {
104
- Incoming { kind }
105
- }
106
-
107
- pub(crate) fn empty() -> Incoming {
108
- Incoming::new(Kind::Empty)
109
- }
110
-
111
- pub(crate) fn h2(
112
- recv: http2::RecvStream,
113
- mut content_length: DecodedLength,
114
- ping: ping::Recorder,
115
- ) -> Self {
116
- // If the stream is already EOS, then the "unknown length" is clearly
117
- // actually ZERO.
118
- if !content_length.is_exact() && recv.is_end_stream() {
119
- content_length = DecodedLength::ZERO;
120
- }
121
-
122
- Incoming::new(Kind::H2 {
123
- data_done: false,
124
- ping,
125
- content_length,
126
- recv,
127
- })
128
- }
129
- }
130
-
131
- impl Body for Incoming {
132
- type Data = Bytes;
133
- type Error = Error;
134
-
135
- fn poll_frame(
136
- mut self: Pin<&mut Self>,
137
- cx: &mut Context<'_>,
138
- ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
139
- match self.kind {
140
- Kind::Empty => Poll::Ready(None),
141
- Kind::Chan {
142
- content_length: ref mut len,
143
- ref mut data_rx,
144
- ref mut want_tx,
145
- ref mut trailers_rx,
146
- } => {
147
- want_tx.send(WANT_READY);
148
-
149
- if !data_rx.is_terminated() {
150
- if let Some(chunk) = ready!(Pin::new(data_rx).poll_next(cx)?) {
151
- len.sub_if(chunk.len() as u64);
152
- return Poll::Ready(Some(Ok(Frame::data(chunk))));
153
- }
154
- }
155
-
156
- // check trailers after data is terminated
157
- match ready!(Pin::new(trailers_rx).poll(cx)) {
158
- Ok(t) => Poll::Ready(Some(Ok(Frame::trailers(t)))),
159
- Err(_) => Poll::Ready(None),
160
- }
161
- }
162
- Kind::H2 {
163
- ref mut data_done,
164
- ref ping,
165
- recv: ref mut h2,
166
- content_length: ref mut len,
167
- } => {
168
- if !*data_done {
169
- match ready!(h2.poll_data(cx)) {
170
- Some(Ok(bytes)) => {
171
- let _ = h2.flow_control().release_capacity(bytes.len());
172
- len.sub_if(bytes.len() as u64);
173
- ping.record_data(bytes.len());
174
- return Poll::Ready(Some(Ok(Frame::data(bytes))));
175
- }
176
- Some(Err(e)) => {
177
- return match e.reason() {
178
- // These reasons should cause the body reading to stop, but not fail
179
- // it. The same logic as for `Read
180
- // for H2Upgraded` is applied here.
181
- Some(http2::Reason::NO_ERROR) | Some(http2::Reason::CANCEL) => {
182
- Poll::Ready(None)
183
- }
184
- _ => Poll::Ready(Some(Err(Error::new_body(e)))),
185
- };
186
- }
187
- None => {
188
- *data_done = true;
189
- // fall through to trailers
190
- }
191
- }
192
- }
193
-
194
- // after data, check trailers
195
- match ready!(h2.poll_trailers(cx)) {
196
- Ok(t) => {
197
- ping.record_non_data();
198
- Poll::Ready(Ok(t.map(Frame::trailers)).transpose())
199
- }
200
- Err(e) => Poll::Ready(Some(Err(Error::new_h2(e)))),
201
- }
202
- }
203
- }
204
- }
205
-
206
- fn is_end_stream(&self) -> bool {
207
- match self.kind {
208
- Kind::Empty => true,
209
- Kind::Chan { content_length, .. } => content_length == DecodedLength::ZERO,
210
- Kind::H2 { recv: ref h2, .. } => h2.is_end_stream(),
211
- }
212
- }
213
-
214
- fn size_hint(&self) -> SizeHint {
215
- fn opt_len(decoded_length: DecodedLength) -> SizeHint {
216
- if let Some(content_length) = decoded_length.into_opt() {
217
- SizeHint::with_exact(content_length)
218
- } else {
219
- SizeHint::default()
220
- }
221
- }
222
-
223
- match self.kind {
224
- Kind::Empty => SizeHint::with_exact(0),
225
- Kind::Chan { content_length, .. } => opt_len(content_length),
226
- Kind::H2 { content_length, .. } => opt_len(content_length),
227
- }
228
- }
229
- }
230
-
231
- impl fmt::Debug for Incoming {
232
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233
- #[derive(Debug)]
234
- struct Streaming;
235
- #[derive(Debug)]
236
- struct Empty;
237
-
238
- let mut builder = f.debug_tuple("Body");
239
- match self.kind {
240
- Kind::Empty => builder.field(&Empty),
241
- _ => builder.field(&Streaming),
242
- };
243
-
244
- builder.finish()
245
- }
246
- }
247
-
248
- impl Sender {
249
- /// Check to see if this `Sender` can send more data.
250
- pub(crate) fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<core::Result<()>> {
251
- // Check if the receiver end has tried polling for the body yet
252
- ready!(self.poll_want(cx)?);
253
- self.data_tx.poll_ready(cx).map_err(|_| Error::new_closed())
254
- }
255
-
256
- fn poll_want(&mut self, cx: &mut Context<'_>) -> Poll<core::Result<()>> {
257
- match self.want_rx.load(cx) {
258
- WANT_READY => Poll::Ready(Ok(())),
259
- WANT_PENDING => Poll::Pending,
260
- watch::CLOSED => Poll::Ready(Err(Error::new_closed())),
261
- unexpected => unreachable!("want_rx value: {}", unexpected),
262
- }
263
- }
264
-
265
- #[cfg(test)]
266
- async fn ready(&mut self) -> core::Result<()> {
267
- std::future::poll_fn(|cx| self.poll_ready(cx)).await
268
- }
269
-
270
- /// Try to send data on this channel.
271
- ///
272
- /// # Errors
273
- ///
274
- /// Returns `Err(Bytes)` if the channel could not (currently) accept
275
- /// another `Bytes`.
276
- ///
277
- /// # Note
278
- ///
279
- /// This is mostly useful for when trying to send from some other thread
280
- /// that doesn't have an async context. If in an async context, prefer
281
- /// `send_data()` instead.
282
- pub(crate) fn try_send_data(&mut self, chunk: Bytes) -> Result<(), Bytes> {
283
- self.data_tx
284
- .try_send(Ok(chunk))
285
- .map_err(|err| err.into_inner().expect("just sent Ok"))
286
- }
287
-
288
- pub(crate) fn try_send_trailers(
289
- &mut self,
290
- trailers: HeaderMap,
291
- ) -> Result<(), Option<HeaderMap>> {
292
- let tx = match self.trailers_tx.take() {
293
- Some(tx) => tx,
294
- None => return Err(None),
295
- };
296
-
297
- tx.send(trailers).map_err(Some)
298
- }
299
-
300
- #[cfg(test)]
301
- pub(crate) fn abort(mut self) {
302
- self.send_error(Error::new_body_write_aborted());
303
- }
304
-
305
- pub(crate) fn send_error(&mut self, err: Error) {
306
- let _ = self
307
- .data_tx
308
- // clone so the send works even if buffer is full
309
- .clone()
310
- .try_send(Err(err));
311
- }
312
- }
313
-
314
- impl fmt::Debug for Sender {
315
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316
- #[derive(Debug)]
317
- struct Open;
318
- #[derive(Debug)]
319
- struct Closed;
320
-
321
- let mut builder = f.debug_tuple("Sender");
322
- match self.want_rx.peek() {
323
- watch::CLOSED => builder.field(&Closed),
324
- _ => builder.field(&Open),
325
- };
326
-
327
- builder.finish()
328
- }
329
- }
330
-
331
- #[cfg(test)]
332
- mod tests {
333
- use std::{mem, task::Poll};
334
-
335
- use http_body_util::BodyExt;
336
-
337
- use super::{Body, DecodedLength, Incoming, Sender, SizeHint};
338
-
339
- #[test]
340
- fn test_size_of() {
341
- // These are mostly to help catch *accidentally* increasing
342
- // the size by too much.
343
-
344
- let body_size = mem::size_of::<Incoming>();
345
- let body_expected_size = mem::size_of::<u64>() * 5;
346
- assert!(
347
- body_size <= body_expected_size,
348
- "Body size = {body_size} <= {body_expected_size}",
349
- );
350
-
351
- //assert_eq!(body_size, mem::size_of::<Option<Incoming>>(), "Option<Incoming>");
352
-
353
- assert_eq!(
354
- mem::size_of::<Sender>(),
355
- mem::size_of::<usize>() * 5,
356
- "Sender"
357
- );
358
-
359
- assert_eq!(
360
- mem::size_of::<Sender>(),
361
- mem::size_of::<Option<Sender>>(),
362
- "Option<Sender>"
363
- );
364
- }
365
-
366
- #[test]
367
- fn size_hint() {
368
- fn eq(body: Incoming, b: SizeHint, note: &str) {
369
- let a = body.size_hint();
370
- assert_eq!(a.lower(), b.lower(), "lower for {note:?}");
371
- assert_eq!(a.upper(), b.upper(), "upper for {note:?}");
372
- }
373
-
374
- eq(Incoming::empty(), SizeHint::with_exact(0), "empty");
375
-
376
- eq(Incoming::channel().1, SizeHint::new(), "channel");
377
-
378
- eq(
379
- Incoming::new_channel(DecodedLength::new(4), /* wanter = */ false).1,
380
- SizeHint::with_exact(4),
381
- "channel with length",
382
- );
383
- }
384
-
385
- #[tokio::test]
386
- async fn channel_abort() {
387
- let (tx, mut rx) = Incoming::channel();
388
-
389
- tx.abort();
390
-
391
- let err = rx.frame().await.unwrap().unwrap_err();
392
- assert!(err.is_body_write_aborted(), "{err:?}");
393
- }
394
-
395
- #[tokio::test]
396
- async fn channel_abort_when_buffer_is_full() {
397
- let (mut tx, mut rx) = Incoming::channel();
398
-
399
- tx.try_send_data("chunk 1".into()).expect("send 1");
400
- // buffer is full, but can still send abort
401
- tx.abort();
402
-
403
- let chunk1 = rx
404
- .frame()
405
- .await
406
- .expect("item 1")
407
- .expect("chunk 1")
408
- .into_data()
409
- .unwrap();
410
- assert_eq!(chunk1, "chunk 1");
411
-
412
- let err = rx.frame().await.unwrap().unwrap_err();
413
- assert!(err.is_body_write_aborted(), "{err:?}");
414
- }
415
-
416
- #[test]
417
- fn channel_buffers_one() {
418
- let (mut tx, _rx) = Incoming::channel();
419
-
420
- tx.try_send_data("chunk 1".into()).expect("send 1");
421
-
422
- // buffer is now full
423
- let chunk2 = tx.try_send_data("chunk 2".into()).expect_err("send 2");
424
- assert_eq!(chunk2, "chunk 2");
425
- }
426
-
427
- #[tokio::test]
428
- async fn channel_empty() {
429
- let (_, mut rx) = Incoming::channel();
430
-
431
- assert!(rx.frame().await.is_none());
432
- }
433
-
434
- #[test]
435
- fn channel_ready() {
436
- let (mut tx, _rx) =
437
- Incoming::new_channel(DecodedLength::CHUNKED, /* wanter = */ false);
438
-
439
- let mut tx_ready = tokio_test::task::spawn(tx.ready());
440
-
441
- assert!(tx_ready.poll().is_ready(), "tx is ready immediately");
442
- }
443
-
444
- #[test]
445
- fn channel_wanter() {
446
- let (mut tx, mut rx) =
447
- Incoming::new_channel(DecodedLength::CHUNKED, /* wanter = */ true);
448
-
449
- let mut tx_ready = tokio_test::task::spawn(tx.ready());
450
- let mut rx_data = tokio_test::task::spawn(rx.frame());
451
-
452
- assert!(
453
- tx_ready.poll().is_pending(),
454
- "tx isn't ready before rx has been polled"
455
- );
456
-
457
- assert!(rx_data.poll().is_pending(), "poll rx.data");
458
- assert!(tx_ready.is_woken(), "rx poll wakes tx");
459
-
460
- assert!(
461
- tx_ready.poll().is_ready(),
462
- "tx is ready after rx has been polled"
463
- );
464
- }
465
-
466
- #[test]
467
- fn channel_notices_closure() {
468
- let (mut tx, rx) = Incoming::new_channel(DecodedLength::CHUNKED, /* wanter = */ true);
469
-
470
- let mut tx_ready = tokio_test::task::spawn(tx.ready());
471
-
472
- assert!(
473
- tx_ready.poll().is_pending(),
474
- "tx isn't ready before rx has been polled"
475
- );
476
-
477
- drop(rx);
478
- assert!(tx_ready.is_woken(), "dropping rx wakes tx");
479
-
480
- match tx_ready.poll() {
481
- Poll::Ready(Err(ref e)) if e.is_closed() => (),
482
- unexpected => panic!("tx poll ready unexpected: {unexpected:?}"),
483
- }
484
- }
485
- }
@@ -1,118 +0,0 @@
1
- use std::fmt;
2
-
3
- use crate::client::core::error::Parse;
4
-
5
- #[derive(Clone, Copy, PartialEq, Eq)]
6
- pub(crate) struct DecodedLength(u64);
7
-
8
- impl From<Option<u64>> for DecodedLength {
9
- fn from(len: Option<u64>) -> Self {
10
- len.and_then(|len| {
11
- // If the length is u64::MAX, oh well, just reported chunked.
12
- Self::checked_new(len).ok()
13
- })
14
- .unwrap_or(DecodedLength::CHUNKED)
15
- }
16
- }
17
-
18
- const MAX_LEN: u64 = u64::MAX - 2;
19
-
20
- impl DecodedLength {
21
- pub(crate) const CLOSE_DELIMITED: DecodedLength = DecodedLength(u64::MAX);
22
- pub(crate) const CHUNKED: DecodedLength = DecodedLength(u64::MAX - 1);
23
- pub(crate) const ZERO: DecodedLength = DecodedLength(0);
24
-
25
- #[cfg(test)]
26
- pub(crate) fn new(len: u64) -> Self {
27
- debug_assert!(len <= MAX_LEN);
28
- DecodedLength(len)
29
- }
30
-
31
- /// Takes the length as a content-length without other checks.
32
- ///
33
- /// Should only be called if previously confirmed this isn't
34
- /// CLOSE_DELIMITED or CHUNKED.
35
- #[inline]
36
- pub(crate) fn danger_len(self) -> u64 {
37
- debug_assert!(self.0 < Self::CHUNKED.0);
38
- self.0
39
- }
40
-
41
- /// Converts to an `Option<u64>` representing a Known or Unknown length.
42
- pub(crate) fn into_opt(self) -> Option<u64> {
43
- match self {
44
- DecodedLength::CHUNKED | DecodedLength::CLOSE_DELIMITED => None,
45
- DecodedLength(known) => Some(known),
46
- }
47
- }
48
-
49
- /// Checks the `u64` is within the maximum allowed for content-length.
50
- pub(crate) fn checked_new(len: u64) -> Result<Self, Parse> {
51
- if len <= MAX_LEN {
52
- Ok(DecodedLength(len))
53
- } else {
54
- warn!("content-length bigger than maximum: {} > {}", len, MAX_LEN);
55
- Err(Parse::TooLarge)
56
- }
57
- }
58
-
59
- pub(crate) fn sub_if(&mut self, amt: u64) {
60
- match *self {
61
- DecodedLength::CHUNKED | DecodedLength::CLOSE_DELIMITED => (),
62
- DecodedLength(ref mut known) => {
63
- *known -= amt;
64
- }
65
- }
66
- }
67
-
68
- /// Returns whether this represents an exact length.
69
- ///
70
- /// This includes 0, which of course is an exact known length.
71
- ///
72
- /// It would return false if "chunked" or otherwise size-unknown.
73
- pub(crate) fn is_exact(&self) -> bool {
74
- self.0 <= MAX_LEN
75
- }
76
- }
77
-
78
- impl fmt::Debug for DecodedLength {
79
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80
- match *self {
81
- DecodedLength::CLOSE_DELIMITED => f.write_str("CLOSE_DELIMITED"),
82
- DecodedLength::CHUNKED => f.write_str("CHUNKED"),
83
- DecodedLength(n) => f.debug_tuple("DecodedLength").field(&n).finish(),
84
- }
85
- }
86
- }
87
-
88
- impl fmt::Display for DecodedLength {
89
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90
- match *self {
91
- DecodedLength::CLOSE_DELIMITED => f.write_str("close-delimited"),
92
- DecodedLength::CHUNKED => f.write_str("chunked encoding"),
93
- DecodedLength::ZERO => f.write_str("empty"),
94
- DecodedLength(n) => write!(f, "content-length ({n} bytes)"),
95
- }
96
- }
97
- }
98
-
99
- #[cfg(test)]
100
- mod tests {
101
- use super::*;
102
-
103
- #[test]
104
- fn sub_if_known() {
105
- let mut len = DecodedLength::new(30);
106
- len.sub_if(20);
107
-
108
- assert_eq!(len.0, 10);
109
- }
110
-
111
- #[test]
112
- fn sub_if_chunked() {
113
- let mut len = DecodedLength::CHUNKED;
114
- len.sub_if(20);
115
-
116
- assert_eq!(len, DecodedLength::CHUNKED);
117
- }
118
- }