wreq-rb 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.lock +1922 -397
- data/LICENSE +203 -0
- data/README.md +19 -15
- data/ext/wreq_rb/Cargo.toml +4 -6
- data/ext/wreq_rb/src/client.rs +41 -48
- data/lib/wreq-rb/version.rb +1 -1
- data/patches/0001-add-transfer-size-tracking.patch +76 -67
- data/vendor/wreq/Cargo.toml +119 -71
- data/vendor/wreq/README.md +25 -20
- data/vendor/wreq/bench/http1.rs +25 -0
- data/vendor/wreq/bench/http1_over_tls.rs +25 -0
- data/vendor/wreq/bench/http2.rs +25 -0
- data/vendor/wreq/bench/http2_over_tls.rs +25 -0
- data/vendor/wreq/bench/support/bench.rs +91 -0
- data/vendor/wreq/bench/support/client.rs +217 -0
- data/vendor/wreq/bench/support/server.rs +188 -0
- data/vendor/wreq/bench/support.rs +56 -0
- data/vendor/wreq/examples/cert_store.rs +4 -4
- data/vendor/wreq/examples/{emulation.rs → emulate.rs} +2 -2
- data/vendor/wreq/examples/http2_websocket.rs +2 -2
- data/vendor/wreq/examples/keylog.rs +3 -3
- data/vendor/wreq/examples/{request_with_emulation.rs → request_with_emulate.rs} +2 -2
- data/vendor/wreq/examples/rt.rs +23 -0
- data/vendor/wreq/src/client/body.rs +23 -61
- data/vendor/wreq/src/client/emulate.rs +119 -0
- data/vendor/wreq/src/client/{http/future.rs → future.rs} +11 -32
- data/vendor/wreq/src/client/{http → layer}/client/pool.rs +66 -61
- data/vendor/wreq/src/client/{http → layer}/client.rs +416 -270
- data/vendor/wreq/src/client/layer/config.rs +27 -6
- data/vendor/wreq/src/client/layer/decoder.rs +9 -4
- data/vendor/wreq/src/client/layer/redirect/future.rs +6 -3
- data/vendor/wreq/src/client/layer/redirect.rs +4 -5
- data/vendor/wreq/src/client/layer/retry.rs +8 -5
- data/vendor/wreq/src/client/layer/timeout/body.rs +15 -6
- data/vendor/wreq/src/client/layer/timeout/future.rs +23 -18
- data/vendor/wreq/src/client/layer/timeout.rs +24 -74
- data/vendor/wreq/src/client/layer.rs +1 -2
- data/vendor/wreq/src/client/multipart.rs +137 -154
- data/vendor/wreq/src/client/request.rs +202 -118
- data/vendor/wreq/src/client/response.rs +46 -45
- data/vendor/wreq/src/client/upgrade.rs +15 -0
- data/vendor/wreq/src/client/ws.rs +73 -25
- data/vendor/wreq/src/client.rs +1655 -17
- data/vendor/wreq/src/config.rs +11 -11
- data/vendor/wreq/src/{client/conn → conn}/connector.rs +139 -137
- data/vendor/wreq/src/conn/descriptor.rs +143 -0
- data/vendor/wreq/src/conn/http.rs +484 -0
- data/vendor/wreq/src/conn/net/io.rs +75 -0
- data/vendor/wreq/src/conn/net/tcp/compio.rs +71 -0
- data/vendor/wreq/src/conn/net/tcp/tokio.rs +57 -0
- data/vendor/wreq/src/conn/net/tcp.rs +561 -0
- data/vendor/wreq/src/conn/net/uds/compio.rs +60 -0
- data/vendor/wreq/src/{client/conn/uds.rs → conn/net/uds/tokio.rs} +18 -12
- data/vendor/wreq/src/conn/net/uds.rs +11 -0
- data/vendor/wreq/src/conn/net.rs +130 -0
- data/vendor/wreq/src/{client/conn → conn}/proxy/socks.rs +2 -9
- data/vendor/wreq/src/{client/conn → conn}/proxy/tunnel.rs +21 -56
- data/vendor/wreq/src/conn/tls_info.rs +47 -0
- data/vendor/wreq/src/{client/conn.rs → conn.rs} +202 -54
- data/vendor/wreq/src/cookie.rs +302 -142
- data/vendor/wreq/src/dns/gai/compio.rs +77 -0
- data/vendor/wreq/src/dns/gai/tokio.rs +90 -0
- data/vendor/wreq/src/dns/gai.rs +14 -164
- data/vendor/wreq/src/dns/hickory.rs +16 -23
- data/vendor/wreq/src/dns/resolve.rs +7 -41
- data/vendor/wreq/src/dns.rs +90 -7
- data/vendor/wreq/src/error.rs +57 -31
- data/vendor/wreq/src/ext.rs +25 -0
- data/vendor/wreq/src/group.rs +211 -0
- data/vendor/wreq/src/header.rs +100 -112
- data/vendor/wreq/src/lib.rs +124 -73
- data/vendor/wreq/src/proxy.rs +6 -20
- data/vendor/wreq/src/redirect.rs +1 -1
- data/vendor/wreq/src/rt.rs +208 -0
- data/vendor/wreq/src/sync.rs +97 -98
- data/vendor/wreq/src/tls/compress.rs +124 -0
- data/vendor/wreq/src/tls/conn/ext.rs +54 -45
- data/vendor/wreq/src/tls/conn/service.rs +14 -18
- data/vendor/wreq/src/tls/conn.rs +169 -241
- data/vendor/wreq/src/tls/keylog.rs +68 -5
- data/vendor/wreq/src/tls/session.rs +205 -0
- data/vendor/wreq/src/tls/{x509 → trust}/identity.rs +4 -21
- data/vendor/wreq/src/tls/{x509/parser.rs → trust/parse.rs} +1 -1
- data/vendor/wreq/src/tls/{x509 → trust}/store.rs +42 -81
- data/vendor/wreq/src/tls/{x509.rs → trust.rs} +8 -2
- data/vendor/wreq/src/tls.rs +489 -25
- data/vendor/wreq/src/trace.rs +0 -12
- data/vendor/wreq/src/util.rs +1 -1
- data/vendor/wreq/tests/badssl.rs +10 -10
- data/vendor/wreq/tests/client.rs +3 -9
- data/vendor/wreq/tests/cookie.rs +6 -8
- data/vendor/wreq/tests/{emulation.rs → emulate.rs} +130 -22
- data/vendor/wreq/tests/multipart.rs +43 -1
- data/vendor/wreq/tests/proxy.rs +1 -1
- data/vendor/wreq/tests/support/layer.rs +1 -0
- metadata +49 -71
- data/patches/0002-add-cancel-connections.patch +0 -181
- data/vendor/wreq/src/client/conn/conn.rs +0 -231
- data/vendor/wreq/src/client/conn/http.rs +0 -1023
- data/vendor/wreq/src/client/conn/tls_info.rs +0 -98
- data/vendor/wreq/src/client/core/body/incoming.rs +0 -485
- data/vendor/wreq/src/client/core/body/length.rs +0 -118
- data/vendor/wreq/src/client/core/body.rs +0 -34
- data/vendor/wreq/src/client/core/common/buf.rs +0 -149
- data/vendor/wreq/src/client/core/common/rewind.rs +0 -141
- data/vendor/wreq/src/client/core/common/watch.rs +0 -76
- data/vendor/wreq/src/client/core/common.rs +0 -3
- data/vendor/wreq/src/client/core/conn/http1.rs +0 -342
- data/vendor/wreq/src/client/core/conn/http2.rs +0 -307
- data/vendor/wreq/src/client/core/conn.rs +0 -11
- data/vendor/wreq/src/client/core/dispatch.rs +0 -299
- data/vendor/wreq/src/client/core/error.rs +0 -435
- data/vendor/wreq/src/client/core/ext.rs +0 -201
- data/vendor/wreq/src/client/core/http1.rs +0 -178
- data/vendor/wreq/src/client/core/http2.rs +0 -483
- data/vendor/wreq/src/client/core/proto/h1/conn.rs +0 -988
- data/vendor/wreq/src/client/core/proto/h1/decode.rs +0 -1170
- data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +0 -684
- data/vendor/wreq/src/client/core/proto/h1/encode.rs +0 -580
- data/vendor/wreq/src/client/core/proto/h1/io.rs +0 -879
- data/vendor/wreq/src/client/core/proto/h1/role.rs +0 -694
- data/vendor/wreq/src/client/core/proto/h1.rs +0 -104
- data/vendor/wreq/src/client/core/proto/h2/client.rs +0 -650
- data/vendor/wreq/src/client/core/proto/h2/ping.rs +0 -539
- data/vendor/wreq/src/client/core/proto/h2.rs +0 -379
- data/vendor/wreq/src/client/core/proto/headers.rs +0 -138
- data/vendor/wreq/src/client/core/proto.rs +0 -58
- data/vendor/wreq/src/client/core/rt/bounds.rs +0 -57
- data/vendor/wreq/src/client/core/rt/timer.rs +0 -150
- data/vendor/wreq/src/client/core/rt/tokio.rs +0 -99
- data/vendor/wreq/src/client/core/rt.rs +0 -25
- data/vendor/wreq/src/client/core/upgrade.rs +0 -267
- data/vendor/wreq/src/client/core.rs +0 -16
- data/vendor/wreq/src/client/emulation.rs +0 -161
- data/vendor/wreq/src/client/http/client/error.rs +0 -142
- data/vendor/wreq/src/client/http/client/exec.rs +0 -29
- data/vendor/wreq/src/client/http/client/extra.rs +0 -77
- data/vendor/wreq/src/client/http/client/util.rs +0 -104
- data/vendor/wreq/src/client/http.rs +0 -1629
- data/vendor/wreq/src/client/layer/config/options.rs +0 -156
- data/vendor/wreq/src/client/layer/cookie.rs +0 -161
- data/vendor/wreq/src/hash.rs +0 -143
- data/vendor/wreq/src/tls/conn/cache.rs +0 -123
- data/vendor/wreq/src/tls/conn/cert_compression.rs +0 -125
- data/vendor/wreq/src/tls/keylog/handle.rs +0 -64
- data/vendor/wreq/src/tls/options.rs +0 -464
- /data/vendor/wreq/src/client/{http → layer}/client/lazy.rs +0 -0
- /data/vendor/wreq/src/{client/conn → conn}/proxy.rs +0 -0
- /data/vendor/wreq/src/{client/conn → conn}/verbose.rs +0 -0
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
//! Streaming bodies for Requests and Responses
|
|
2
|
-
//!
|
|
3
|
-
//! For both [Clients](crate::client), requests and
|
|
4
|
-
//! responses use streaming bodies, instead of complete buffering. This
|
|
5
|
-
//! allows applications to not use memory they don't need, and allows exerting
|
|
6
|
-
//! back-pressure on connections by only reading when asked.
|
|
7
|
-
//!
|
|
8
|
-
//! There are two pieces to this in crate::core::
|
|
9
|
-
//!
|
|
10
|
-
//! - **The [\`Body`\] trait** describes all possible bodies. crate::core: allows any body type that
|
|
11
|
-
//! implements `Body`, allowing applications to have fine-grained control over their streaming.
|
|
12
|
-
//! - **The [`Incoming`] concrete type**, which is an implementation of `Body`, and returned by
|
|
13
|
-
//! crate::core: as a "receive stream" (so, for server requests and client responses).
|
|
14
|
-
//!
|
|
15
|
-
//! There are additional implementations available in [`http-body-util`][],
|
|
16
|
-
//! such as a `Full` or `Empty` body.
|
|
17
|
-
//!
|
|
18
|
-
//! [`http-body-util`]: https://docs.rs/http-body-util
|
|
19
|
-
|
|
20
|
-
mod incoming;
|
|
21
|
-
mod length;
|
|
22
|
-
|
|
23
|
-
pub(crate) use self::{
|
|
24
|
-
incoming::{Incoming, Sender},
|
|
25
|
-
length::DecodedLength,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
fn _assert_send_sync() {
|
|
29
|
-
fn _assert_send<T: Send>() {}
|
|
30
|
-
fn _assert_sync<T: Sync>() {}
|
|
31
|
-
|
|
32
|
-
_assert_send::<Incoming>();
|
|
33
|
-
_assert_sync::<Incoming>();
|
|
34
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
use std::{collections::VecDeque, io::IoSlice};
|
|
2
|
-
|
|
3
|
-
use bytes::{Buf, BufMut, Bytes, BytesMut};
|
|
4
|
-
|
|
5
|
-
pub(crate) struct BufList<T> {
|
|
6
|
-
bufs: VecDeque<T>,
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
impl<T: Buf> BufList<T> {
|
|
10
|
-
pub(crate) fn new() -> BufList<T> {
|
|
11
|
-
BufList {
|
|
12
|
-
bufs: VecDeque::new(),
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
#[inline]
|
|
17
|
-
pub(crate) fn push(&mut self, buf: T) {
|
|
18
|
-
debug_assert!(buf.has_remaining());
|
|
19
|
-
self.bufs.push_back(buf);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
#[inline]
|
|
23
|
-
pub(crate) fn bufs_cnt(&self) -> usize {
|
|
24
|
-
self.bufs.len()
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
impl<T: Buf> Buf for BufList<T> {
|
|
29
|
-
#[inline]
|
|
30
|
-
fn remaining(&self) -> usize {
|
|
31
|
-
self.bufs.iter().map(|buf| buf.remaining()).sum()
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
#[inline]
|
|
35
|
-
fn chunk(&self) -> &[u8] {
|
|
36
|
-
self.bufs.front().map(Buf::chunk).unwrap_or_default()
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
#[inline]
|
|
40
|
-
fn advance(&mut self, mut cnt: usize) {
|
|
41
|
-
while cnt > 0 {
|
|
42
|
-
{
|
|
43
|
-
let front = &mut self.bufs[0];
|
|
44
|
-
let rem = front.remaining();
|
|
45
|
-
if rem > cnt {
|
|
46
|
-
front.advance(cnt);
|
|
47
|
-
return;
|
|
48
|
-
} else {
|
|
49
|
-
front.advance(rem);
|
|
50
|
-
cnt -= rem;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
self.bufs.pop_front();
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
#[inline]
|
|
58
|
-
fn chunks_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize {
|
|
59
|
-
if dst.is_empty() {
|
|
60
|
-
return 0;
|
|
61
|
-
}
|
|
62
|
-
let mut vecs = 0;
|
|
63
|
-
for buf in &self.bufs {
|
|
64
|
-
vecs += buf.chunks_vectored(&mut dst[vecs..]);
|
|
65
|
-
if vecs == dst.len() {
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
vecs
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
#[inline]
|
|
73
|
-
fn copy_to_bytes(&mut self, len: usize) -> Bytes {
|
|
74
|
-
// Our inner buffer may have an optimized version of copy_to_bytes, and if the whole
|
|
75
|
-
// request can be fulfilled by the front buffer, we can take advantage.
|
|
76
|
-
match self.bufs.front_mut() {
|
|
77
|
-
Some(front) if front.remaining() == len => {
|
|
78
|
-
let b = front.copy_to_bytes(len);
|
|
79
|
-
self.bufs.pop_front();
|
|
80
|
-
b
|
|
81
|
-
}
|
|
82
|
-
Some(front) if front.remaining() > len => front.copy_to_bytes(len),
|
|
83
|
-
_ => {
|
|
84
|
-
assert!(len <= self.remaining(), "`len` greater than remaining");
|
|
85
|
-
let mut bm = BytesMut::with_capacity(len);
|
|
86
|
-
bm.put(self.take(len));
|
|
87
|
-
bm.freeze()
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
#[cfg(test)]
|
|
94
|
-
mod tests {
|
|
95
|
-
use std::ptr;
|
|
96
|
-
|
|
97
|
-
use super::*;
|
|
98
|
-
|
|
99
|
-
fn hello_world_buf() -> BufList<Bytes> {
|
|
100
|
-
BufList {
|
|
101
|
-
bufs: vec![Bytes::from("Hello"), Bytes::from(" "), Bytes::from("World")].into(),
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
#[test]
|
|
106
|
-
fn to_bytes_shorter() {
|
|
107
|
-
let mut bufs = hello_world_buf();
|
|
108
|
-
let old_ptr = bufs.chunk().as_ptr();
|
|
109
|
-
let start = bufs.copy_to_bytes(4);
|
|
110
|
-
assert_eq!(start, "Hell");
|
|
111
|
-
assert!(ptr::eq(old_ptr, start.as_ptr()));
|
|
112
|
-
assert_eq!(bufs.chunk(), b"o");
|
|
113
|
-
assert!(ptr::eq(old_ptr.wrapping_add(4), bufs.chunk().as_ptr()));
|
|
114
|
-
assert_eq!(bufs.remaining(), 7);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
#[test]
|
|
118
|
-
fn to_bytes_eq() {
|
|
119
|
-
let mut bufs = hello_world_buf();
|
|
120
|
-
let old_ptr = bufs.chunk().as_ptr();
|
|
121
|
-
let start = bufs.copy_to_bytes(5);
|
|
122
|
-
assert_eq!(start, "Hello");
|
|
123
|
-
assert!(ptr::eq(old_ptr, start.as_ptr()));
|
|
124
|
-
assert_eq!(bufs.chunk(), b" ");
|
|
125
|
-
assert_eq!(bufs.remaining(), 6);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
#[test]
|
|
129
|
-
fn to_bytes_longer() {
|
|
130
|
-
let mut bufs = hello_world_buf();
|
|
131
|
-
let start = bufs.copy_to_bytes(7);
|
|
132
|
-
assert_eq!(start, "Hello W");
|
|
133
|
-
assert_eq!(bufs.remaining(), 4);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
#[test]
|
|
137
|
-
fn one_long_buf_to_bytes() {
|
|
138
|
-
let mut buf = BufList::new();
|
|
139
|
-
buf.push(b"Hello World" as &[_]);
|
|
140
|
-
assert_eq!(buf.copy_to_bytes(5), "Hello");
|
|
141
|
-
assert_eq!(buf.chunk(), b" World");
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
#[test]
|
|
145
|
-
#[should_panic(expected = "`len` greater than remaining")]
|
|
146
|
-
fn buf_to_bytes_too_many() {
|
|
147
|
-
hello_world_buf().copy_to_bytes(42);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
use std::{
|
|
2
|
-
cmp, io,
|
|
3
|
-
pin::Pin,
|
|
4
|
-
task::{Context, Poll},
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
use bytes::{Buf, Bytes};
|
|
8
|
-
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
|
|
9
|
-
|
|
10
|
-
/// Combine a buffer with an IO, rewinding reads to use the buffer.
|
|
11
|
-
#[derive(Debug)]
|
|
12
|
-
pub(crate) struct Rewind<T> {
|
|
13
|
-
pre: Option<Bytes>,
|
|
14
|
-
inner: T,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
impl<T> Rewind<T> {
|
|
18
|
-
pub(crate) fn new_buffered(io: T, buf: Bytes) -> Self {
|
|
19
|
-
Rewind {
|
|
20
|
-
pre: Some(buf),
|
|
21
|
-
inner: io,
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
#[cfg(test)]
|
|
26
|
-
pub(crate) fn rewind(&mut self, bs: Bytes) {
|
|
27
|
-
debug_assert!(self.pre.is_none());
|
|
28
|
-
self.pre = Some(bs);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
impl<T> AsyncRead for Rewind<T>
|
|
33
|
-
where
|
|
34
|
-
T: AsyncRead + Unpin,
|
|
35
|
-
{
|
|
36
|
-
fn poll_read(
|
|
37
|
-
mut self: Pin<&mut Self>,
|
|
38
|
-
cx: &mut Context<'_>,
|
|
39
|
-
buf: &mut ReadBuf<'_>,
|
|
40
|
-
) -> Poll<io::Result<()>> {
|
|
41
|
-
if let Some(mut prefix) = self.pre.take() {
|
|
42
|
-
// If there are no remaining bytes, let the bytes get dropped.
|
|
43
|
-
if !prefix.is_empty() {
|
|
44
|
-
let copy_len = cmp::min(prefix.len(), buf.remaining());
|
|
45
|
-
// TODO: There should be a way to do following two lines cleaner...
|
|
46
|
-
buf.put_slice(&prefix[..copy_len]);
|
|
47
|
-
prefix.advance(copy_len);
|
|
48
|
-
// Put back what's left
|
|
49
|
-
if !prefix.is_empty() {
|
|
50
|
-
self.pre = Some(prefix);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return Poll::Ready(Ok(()));
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
Pin::new(&mut self.inner).poll_read(cx, buf)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
impl<T> AsyncWrite for Rewind<T>
|
|
61
|
-
where
|
|
62
|
-
T: AsyncWrite + Unpin,
|
|
63
|
-
{
|
|
64
|
-
fn poll_write(
|
|
65
|
-
mut self: Pin<&mut Self>,
|
|
66
|
-
cx: &mut Context<'_>,
|
|
67
|
-
buf: &[u8],
|
|
68
|
-
) -> Poll<io::Result<usize>> {
|
|
69
|
-
Pin::new(&mut self.inner).poll_write(cx, buf)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
fn poll_write_vectored(
|
|
73
|
-
mut self: Pin<&mut Self>,
|
|
74
|
-
cx: &mut Context<'_>,
|
|
75
|
-
bufs: &[io::IoSlice<'_>],
|
|
76
|
-
) -> Poll<io::Result<usize>> {
|
|
77
|
-
Pin::new(&mut self.inner).poll_write_vectored(cx, bufs)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
81
|
-
Pin::new(&mut self.inner).poll_flush(cx)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
85
|
-
Pin::new(&mut self.inner).poll_shutdown(cx)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
fn is_write_vectored(&self) -> bool {
|
|
89
|
-
self.inner.is_write_vectored()
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
#[cfg(test)]
|
|
94
|
-
mod tests {
|
|
95
|
-
use bytes::Bytes;
|
|
96
|
-
use tokio::io::AsyncReadExt;
|
|
97
|
-
|
|
98
|
-
use super::Rewind;
|
|
99
|
-
|
|
100
|
-
#[tokio::test]
|
|
101
|
-
async fn partial_rewind() {
|
|
102
|
-
let underlying = [104, 101, 108, 108, 111];
|
|
103
|
-
|
|
104
|
-
let mock = tokio_test::io::Builder::new().read(&underlying).build();
|
|
105
|
-
|
|
106
|
-
let mut stream = Rewind::new_buffered(mock, Bytes::new());
|
|
107
|
-
|
|
108
|
-
// Read off some bytes, ensure we filled o1
|
|
109
|
-
let mut buf = [0; 2];
|
|
110
|
-
stream.read_exact(&mut buf).await.expect("read1");
|
|
111
|
-
|
|
112
|
-
// Rewind the stream so that it is as if we never read in the first place.
|
|
113
|
-
stream.rewind(Bytes::copy_from_slice(&buf[..]));
|
|
114
|
-
|
|
115
|
-
let mut buf = [0; 5];
|
|
116
|
-
stream.read_exact(&mut buf).await.expect("read1");
|
|
117
|
-
|
|
118
|
-
// At this point we should have read everything that was in the MockStream
|
|
119
|
-
assert_eq!(&buf, &underlying);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
#[tokio::test]
|
|
123
|
-
async fn full_rewind() {
|
|
124
|
-
let underlying = [104, 101, 108, 108, 111];
|
|
125
|
-
|
|
126
|
-
let mock = tokio_test::io::Builder::new().read(&underlying).build();
|
|
127
|
-
|
|
128
|
-
let mut stream = Rewind::new_buffered(mock, Bytes::new());
|
|
129
|
-
|
|
130
|
-
let mut buf = [0; 5];
|
|
131
|
-
stream.read_exact(&mut buf).await.expect("read1");
|
|
132
|
-
|
|
133
|
-
// Rewind the stream so that it is as if we never read in the first place.
|
|
134
|
-
stream.rewind(Bytes::copy_from_slice(&buf[..]));
|
|
135
|
-
|
|
136
|
-
let mut buf = [0; 5];
|
|
137
|
-
stream.read_exact(&mut buf).await.expect("read1");
|
|
138
|
-
|
|
139
|
-
assert_eq!(&buf, &underlying);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
//! An SPSC broadcast channel.
|
|
2
|
-
//!
|
|
3
|
-
//! - The value can only be a `usize`.
|
|
4
|
-
//! - The consumer is only notified if the value is different.
|
|
5
|
-
//! - The value `0` is reserved for closed.
|
|
6
|
-
|
|
7
|
-
use std::{
|
|
8
|
-
sync::{
|
|
9
|
-
Arc,
|
|
10
|
-
atomic::{AtomicUsize, Ordering},
|
|
11
|
-
},
|
|
12
|
-
task,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
use futures_util::task::AtomicWaker;
|
|
16
|
-
|
|
17
|
-
type Value = usize;
|
|
18
|
-
|
|
19
|
-
pub(crate) const CLOSED: usize = 0;
|
|
20
|
-
|
|
21
|
-
pub(crate) fn channel(initial: Value) -> (Sender, Receiver) {
|
|
22
|
-
debug_assert!(
|
|
23
|
-
initial != CLOSED,
|
|
24
|
-
"watch::channel initial state of 0 is reserved"
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
let shared = Arc::new(Shared {
|
|
28
|
-
value: AtomicUsize::new(initial),
|
|
29
|
-
waker: AtomicWaker::new(),
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
(
|
|
33
|
-
Sender {
|
|
34
|
-
shared: shared.clone(),
|
|
35
|
-
},
|
|
36
|
-
Receiver { shared },
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
pub(crate) struct Sender {
|
|
41
|
-
shared: Arc<Shared>,
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
pub(crate) struct Receiver {
|
|
45
|
-
shared: Arc<Shared>,
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
struct Shared {
|
|
49
|
-
value: AtomicUsize,
|
|
50
|
-
waker: AtomicWaker,
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
impl Sender {
|
|
54
|
-
pub(crate) fn send(&mut self, value: Value) {
|
|
55
|
-
if self.shared.value.swap(value, Ordering::SeqCst) != value {
|
|
56
|
-
self.shared.waker.wake();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
impl Drop for Sender {
|
|
62
|
-
fn drop(&mut self) {
|
|
63
|
-
self.send(CLOSED);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
impl Receiver {
|
|
68
|
-
pub(crate) fn load(&mut self, cx: &mut task::Context<'_>) -> Value {
|
|
69
|
-
self.shared.waker.register(cx.waker());
|
|
70
|
-
self.shared.value.load(Ordering::SeqCst)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
pub(crate) fn peek(&self) -> Value {
|
|
74
|
-
self.shared.value.load(Ordering::Relaxed)
|
|
75
|
-
}
|
|
76
|
-
}
|