14
Cargo.toml
14
Cargo.toml
@@ -22,20 +22,20 @@ include = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bytes = "0.6"
|
bytes = "1"
|
||||||
futures-core = { version = "0.3", default-features = false }
|
futures-core = { version = "0.3", default-features = false }
|
||||||
futures-channel = "0.3"
|
futures-channel = "0.3"
|
||||||
futures-util = { version = "0.3", default-features = false }
|
futures-util = { version = "0.3", default-features = false }
|
||||||
http = "0.2"
|
http = "0.2"
|
||||||
http-body = { git = "https://github.com/hyperium/http-body" }
|
http-body = "0.4"
|
||||||
httpdate = "0.3"
|
httpdate = "0.3"
|
||||||
httparse = "1.0"
|
httparse = "1.0"
|
||||||
h2 = { git = "https://github.com/hyperium/h2", optional = true }
|
h2 = { version = "0.3", optional = true }
|
||||||
itoa = "0.4.1"
|
itoa = "0.4.1"
|
||||||
tracing = { version = "0.1", default-features = false, features = ["std"] }
|
tracing = { version = "0.1", default-features = false, features = ["std"] }
|
||||||
pin-project = "1.0"
|
pin-project = "1.0"
|
||||||
tower-service = "0.3"
|
tower-service = "0.3"
|
||||||
tokio = { version = "0.3.4", features = ["sync", "stream"] }
|
tokio = { version = "1", features = ["sync"] }
|
||||||
want = "0.3"
|
want = "0.3"
|
||||||
|
|
||||||
# Optional
|
# Optional
|
||||||
@@ -51,7 +51,7 @@ spmc = "0.3"
|
|||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
tokio = { version = "0.3", features = [
|
tokio = { version = "1", features = [
|
||||||
"fs",
|
"fs",
|
||||||
"macros",
|
"macros",
|
||||||
"io-std",
|
"io-std",
|
||||||
@@ -62,8 +62,8 @@ tokio = { version = "0.3", features = [
|
|||||||
"time",
|
"time",
|
||||||
"test-util",
|
"test-util",
|
||||||
] }
|
] }
|
||||||
tokio-test = "0.3"
|
tokio-test = "0.4"
|
||||||
tokio-util = { version = "0.5", features = ["codec"] }
|
tokio-util = { version = "0.6", features = ["codec"] }
|
||||||
tower-util = "0.3"
|
tower-util = "0.3"
|
||||||
url = "1.0"
|
url = "1.0"
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ where
|
|||||||
let second = if let Some(buf) = body.data().await {
|
let second = if let Some(buf) = body.data().await {
|
||||||
buf?
|
buf?
|
||||||
} else {
|
} else {
|
||||||
return Ok(first.copy_to_bytes(first.bytes().len()));
|
return Ok(first.copy_to_bytes(first.remaining()));
|
||||||
};
|
};
|
||||||
|
|
||||||
// With more than 1 buf, we gotta flatten into a Vec first.
|
// With more than 1 buf, we gotta flatten into a Vec first.
|
||||||
|
|||||||
@@ -667,8 +667,11 @@ impl ConnectingTcp<'_> {
|
|||||||
let fallback_fut = fallback.remote.connect(self.config);
|
let fallback_fut = fallback.remote.connect(self.config);
|
||||||
futures_util::pin_mut!(fallback_fut);
|
futures_util::pin_mut!(fallback_fut);
|
||||||
|
|
||||||
|
let fallback_delay = fallback.delay;
|
||||||
|
futures_util::pin_mut!(fallback_delay);
|
||||||
|
|
||||||
let (result, future) =
|
let (result, future) =
|
||||||
match futures_util::future::select(preferred_fut, fallback.delay).await {
|
match futures_util::future::select(preferred_fut, fallback_delay).await {
|
||||||
Either::Left((result, _fallback_delay)) => {
|
Either::Left((result, _fallback_delay)) => {
|
||||||
(result, Either::Right(fallback_fut))
|
(result, Either::Right(fallback_fut))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#[cfg(feature = "http2")]
|
#[cfg(feature = "http2")]
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
use tokio::stream::Stream;
|
use futures_util::FutureExt;
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
|
|
||||||
use crate::common::{task, Pin, Poll};
|
use crate::common::{task, Pin, Poll};
|
||||||
@@ -150,8 +150,8 @@ impl<T, U> Receiver<T, U> {
|
|||||||
self: Pin<&mut Self>,
|
self: Pin<&mut Self>,
|
||||||
cx: &mut task::Context<'_>,
|
cx: &mut task::Context<'_>,
|
||||||
) -> Poll<Option<(T, Callback<T, U>)>> {
|
) -> Poll<Option<(T, Callback<T, U>)>> {
|
||||||
let this = self.project();
|
let mut this = self.project();
|
||||||
match this.inner.poll_next(cx) {
|
match this.inner.poll_recv(cx) {
|
||||||
Poll::Ready(item) => {
|
Poll::Ready(item) => {
|
||||||
Poll::Ready(item.map(|mut env| env.0.take().expect("envelope not dropped")))
|
Poll::Ready(item.map(|mut env| env.0.take().expect("envelope not dropped")))
|
||||||
}
|
}
|
||||||
@@ -170,9 +170,9 @@ impl<T, U> Receiver<T, U> {
|
|||||||
|
|
||||||
#[cfg(feature = "http1")]
|
#[cfg(feature = "http1")]
|
||||||
pub(crate) fn try_recv(&mut self) -> Option<(T, Callback<T, U>)> {
|
pub(crate) fn try_recv(&mut self) -> Option<(T, Callback<T, U>)> {
|
||||||
match self.inner.try_recv() {
|
match self.inner.recv().now_or_never() {
|
||||||
Ok(mut env) => env.0.take(),
|
Some(Some(mut env)) => env.0.take(),
|
||||||
Err(_) => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -731,7 +731,6 @@ impl<T: Poolable + 'static> Future for IdleTask<T> {
|
|||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
|
||||||
use tokio::stream::Stream;
|
|
||||||
let mut this = self.project();
|
let mut this = self.project();
|
||||||
loop {
|
loop {
|
||||||
match this.pool_drop_notifier.as_mut().poll(cx) {
|
match this.pool_drop_notifier.as_mut().poll(cx) {
|
||||||
@@ -743,7 +742,7 @@ impl<T: Poolable + 'static> Future for IdleTask<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ready!(this.interval.as_mut().poll_next(cx));
|
ready!(this.interval.as_mut().poll_tick(cx));
|
||||||
|
|
||||||
if let Some(inner) = this.pool.upgrade() {
|
if let Some(inner) = this.pool.upgrade() {
|
||||||
if let Ok(mut inner) = inner.lock() {
|
if let Ok(mut inner) = inner.lock() {
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ impl<T: Buf> Buf for BufList<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes(&self) -> &[u8] {
|
fn chunk(&self) -> &[u8] {
|
||||||
self.bufs.front().map(Buf::bytes).unwrap_or_default()
|
self.bufs.front().map(Buf::chunk).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -57,13 +57,13 @@ impl<T: Buf> Buf for BufList<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize {
|
fn chunks_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize {
|
||||||
if dst.is_empty() {
|
if dst.is_empty() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
let mut vecs = 0;
|
let mut vecs = 0;
|
||||||
for buf in &self.bufs {
|
for buf in &self.bufs {
|
||||||
vecs += buf.bytes_vectored(&mut dst[vecs..]);
|
vecs += buf.chunks_vectored(&mut dst[vecs..]);
|
||||||
if vecs == dst.len() {
|
if vecs == dst.len() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
mod rewind;
|
mod rewind;
|
||||||
|
|
||||||
pub(crate) use self::rewind::Rewind;
|
pub(crate) use self::rewind::Rewind;
|
||||||
pub(crate) const MAX_WRITEV_BUFS: usize = 64;
|
|
||||||
|
|||||||
@@ -229,12 +229,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes(&self) -> &[u8] {
|
fn chunk(&self) -> &[u8] {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
BufKind::Exact(ref b) => b.bytes(),
|
BufKind::Exact(ref b) => b.chunk(),
|
||||||
BufKind::Limited(ref b) => b.bytes(),
|
BufKind::Limited(ref b) => b.chunk(),
|
||||||
BufKind::Chunked(ref b) => b.bytes(),
|
BufKind::Chunked(ref b) => b.chunk(),
|
||||||
BufKind::ChunkedEnd(ref b) => b.bytes(),
|
BufKind::ChunkedEnd(ref b) => b.chunk(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,12 +249,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize {
|
fn chunks_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
BufKind::Exact(ref b) => b.bytes_vectored(dst),
|
BufKind::Exact(ref b) => b.chunks_vectored(dst),
|
||||||
BufKind::Limited(ref b) => b.bytes_vectored(dst),
|
BufKind::Limited(ref b) => b.chunks_vectored(dst),
|
||||||
BufKind::Chunked(ref b) => b.bytes_vectored(dst),
|
BufKind::Chunked(ref b) => b.chunks_vectored(dst),
|
||||||
BufKind::ChunkedEnd(ref b) => b.bytes_vectored(dst),
|
BufKind::ChunkedEnd(ref b) => b.chunks_vectored(dst),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,7 +295,7 @@ impl Buf for ChunkSize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes(&self) -> &[u8] {
|
fn chunk(&self) -> &[u8] {
|
||||||
&self.bytes[self.pos.into()..self.len.into()]
|
&self.bytes[self.pos.into()..self.len.into()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ where
|
|||||||
self.read_buf.reserve(next);
|
self.read_buf.reserve(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
let dst = self.read_buf.bytes_mut();
|
let dst = self.read_buf.chunk_mut();
|
||||||
let dst = unsafe { &mut *(dst as *mut _ as *mut [MaybeUninit<u8>]) };
|
let dst = unsafe { &mut *(dst as *mut _ as *mut [MaybeUninit<u8>]) };
|
||||||
let mut buf = ReadBuf::uninit(dst);
|
let mut buf = ReadBuf::uninit(dst);
|
||||||
match Pin::new(&mut self.io).poll_read(cx, &mut buf) {
|
match Pin::new(&mut self.io).poll_read(cx, &mut buf) {
|
||||||
@@ -231,10 +231,11 @@ where
|
|||||||
return self.poll_flush_flattened(cx);
|
return self.poll_flush_flattened(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MAX_WRITEV_BUFS: usize = 64;
|
||||||
loop {
|
loop {
|
||||||
let n = {
|
let n = {
|
||||||
let mut iovs = [IoSlice::new(&[]); crate::common::io::MAX_WRITEV_BUFS];
|
let mut iovs = [IoSlice::new(&[]); MAX_WRITEV_BUFS];
|
||||||
let len = self.write_buf.bytes_vectored(&mut iovs);
|
let len = self.write_buf.chunks_vectored(&mut iovs);
|
||||||
ready!(Pin::new(&mut self.io).poll_write_vectored(cx, &iovs[..len]))?
|
ready!(Pin::new(&mut self.io).poll_write_vectored(cx, &iovs[..len]))?
|
||||||
};
|
};
|
||||||
// TODO(eliza): we have to do this manually because
|
// TODO(eliza): we have to do this manually because
|
||||||
@@ -262,7 +263,7 @@ where
|
|||||||
/// that skips some bookkeeping around using multiple buffers.
|
/// that skips some bookkeeping around using multiple buffers.
|
||||||
fn poll_flush_flattened(&mut self, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {
|
fn poll_flush_flattened(&mut self, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {
|
||||||
loop {
|
loop {
|
||||||
let n = ready!(Pin::new(&mut self.io).poll_write(cx, self.write_buf.headers.bytes()))?;
|
let n = ready!(Pin::new(&mut self.io).poll_write(cx, self.write_buf.headers.chunk()))?;
|
||||||
debug!("flushed {} bytes", n);
|
debug!("flushed {} bytes", n);
|
||||||
self.write_buf.headers.advance(n);
|
self.write_buf.headers.advance(n);
|
||||||
if self.write_buf.headers.remaining() == 0 {
|
if self.write_buf.headers.remaining() == 0 {
|
||||||
@@ -433,7 +434,7 @@ impl<T: AsRef<[u8]>> Buf for Cursor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes(&self) -> &[u8] {
|
fn chunk(&self) -> &[u8] {
|
||||||
&self.bytes.as_ref()[self.pos..]
|
&self.bytes.as_ref()[self.pos..]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,7 +488,7 @@ where
|
|||||||
//but accomplishes the same result.
|
//but accomplishes the same result.
|
||||||
loop {
|
loop {
|
||||||
let adv = {
|
let adv = {
|
||||||
let slice = buf.bytes();
|
let slice = buf.chunk();
|
||||||
if slice.is_empty() {
|
if slice.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -534,12 +535,12 @@ impl<B: Buf> Buf for WriteBuf<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes(&self) -> &[u8] {
|
fn chunk(&self) -> &[u8] {
|
||||||
let headers = self.headers.bytes();
|
let headers = self.headers.chunk();
|
||||||
if !headers.is_empty() {
|
if !headers.is_empty() {
|
||||||
headers
|
headers
|
||||||
} else {
|
} else {
|
||||||
self.queue.bytes()
|
self.queue.chunk()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,9 +560,9 @@ impl<B: Buf> Buf for WriteBuf<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize {
|
fn chunks_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize {
|
||||||
let n = self.headers.bytes_vectored(dst);
|
let n = self.headers.chunks_vectored(dst);
|
||||||
self.queue.bytes_vectored(&mut dst[n..]) + n
|
self.queue.chunks_vectored(&mut dst[n..]) + n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -257,8 +257,8 @@ impl<B: Buf> Buf for SendBuf<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes(&self) -> &[u8] {
|
fn chunk(&self) -> &[u8] {
|
||||||
self.0.as_ref().map(|b| b.bytes()).unwrap_or(&[])
|
self.0.as_ref().map(|b| b.chunk()).unwrap_or(&[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -268,7 +268,7 @@ impl<B: Buf> Buf for SendBuf<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bytes_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
|
fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
|
||||||
self.0.as_ref().map(|b| b.bytes_vectored(dst)).unwrap_or(0)
|
self.0.as_ref().map(|b| b.chunks_vectored(dst)).unwrap_or(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ pub(super) fn channel(ping_pong: PingPong, config: Config) -> (Recorder, Ponger)
|
|||||||
interval,
|
interval,
|
||||||
timeout: config.keep_alive_timeout,
|
timeout: config.keep_alive_timeout,
|
||||||
while_idle: config.keep_alive_while_idle,
|
while_idle: config.keep_alive_while_idle,
|
||||||
timer: tokio::time::sleep(interval),
|
timer: Box::pin(tokio::time::sleep(interval)),
|
||||||
state: KeepAliveState::Init,
|
state: KeepAliveState::Init,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ struct KeepAlive {
|
|||||||
while_idle: bool,
|
while_idle: bool,
|
||||||
|
|
||||||
state: KeepAliveState,
|
state: KeepAliveState,
|
||||||
timer: Sleep,
|
timer: Pin<Box<Sleep>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "runtime")]
|
#[cfg(feature = "runtime")]
|
||||||
@@ -441,7 +441,7 @@ impl KeepAlive {
|
|||||||
|
|
||||||
self.state = KeepAliveState::Scheduled;
|
self.state = KeepAliveState::Scheduled;
|
||||||
let interval = shared.last_read_at() + self.interval;
|
let interval = shared.last_read_at() + self.interval;
|
||||||
self.timer.reset(interval);
|
self.timer.as_mut().reset(interval);
|
||||||
}
|
}
|
||||||
KeepAliveState::PingSent => {
|
KeepAliveState::PingSent => {
|
||||||
if shared.is_ping_sent() {
|
if shared.is_ping_sent() {
|
||||||
@@ -450,7 +450,7 @@ impl KeepAlive {
|
|||||||
|
|
||||||
self.state = KeepAliveState::Scheduled;
|
self.state = KeepAliveState::Scheduled;
|
||||||
let interval = shared.last_read_at() + self.interval;
|
let interval = shared.last_read_at() + self.interval;
|
||||||
self.timer.reset(interval);
|
self.timer.as_mut().reset(interval);
|
||||||
}
|
}
|
||||||
KeepAliveState::Scheduled => (),
|
KeepAliveState::Scheduled => (),
|
||||||
}
|
}
|
||||||
@@ -472,7 +472,7 @@ impl KeepAlive {
|
|||||||
shared.send_ping();
|
shared.send_ping();
|
||||||
self.state = KeepAliveState::PingSent;
|
self.state = KeepAliveState::PingSent;
|
||||||
let timeout = Instant::now() + self.timeout;
|
let timeout = Instant::now() + self.timeout;
|
||||||
self.timer.reset(timeout);
|
self.timer.as_mut().reset(timeout);
|
||||||
}
|
}
|
||||||
KeepAliveState::Init | KeepAliveState::PingSent => (),
|
KeepAliveState::Init | KeepAliveState::PingSent => (),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub struct AddrIncoming {
|
|||||||
sleep_on_errors: bool,
|
sleep_on_errors: bool,
|
||||||
tcp_keepalive_timeout: Option<Duration>,
|
tcp_keepalive_timeout: Option<Duration>,
|
||||||
tcp_nodelay: bool,
|
tcp_nodelay: bool,
|
||||||
timeout: Option<Sleep>,
|
timeout: Option<Pin<Box<Sleep>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddrIncoming {
|
impl AddrIncoming {
|
||||||
@@ -160,9 +160,9 @@ impl AddrIncoming {
|
|||||||
error!("accept error: {}", e);
|
error!("accept error: {}", e);
|
||||||
|
|
||||||
// Sleep 1s.
|
// Sleep 1s.
|
||||||
let mut timeout = tokio::time::sleep(Duration::from_secs(1));
|
let mut timeout = Box::pin(tokio::time::sleep(Duration::from_secs(1)));
|
||||||
|
|
||||||
match Pin::new(&mut timeout).poll(cx) {
|
match timeout.as_mut().poll(cx) {
|
||||||
Poll::Ready(()) => {
|
Poll::Ready(()) => {
|
||||||
// Wow, it's been a second already? Ok then...
|
// Wow, it's been a second already? Ok then...
|
||||||
continue;
|
continue;
|
||||||
@@ -263,7 +263,7 @@ mod addr_stream {
|
|||||||
pub fn poll_peek(
|
pub fn poll_peek(
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut task::Context<'_>,
|
cx: &mut task::Context<'_>,
|
||||||
buf: &mut [u8],
|
buf: &mut tokio::io::ReadBuf<'_>,
|
||||||
) -> Poll<io::Result<usize>> {
|
) -> Poll<io::Result<usize>> {
|
||||||
self.inner.poll_peek(cx, buf)
|
self.inner.poll_peek(cx, buf)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use std::fmt;
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::marker::Unpin;
|
use std::marker::Unpin;
|
||||||
|
|
||||||
use bytes::{Buf, Bytes};
|
use bytes::Bytes;
|
||||||
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
|
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ impl Upgraded {
|
|||||||
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||||
{
|
{
|
||||||
Upgraded {
|
Upgraded {
|
||||||
io: Rewind::new_buffered(Box::new(ForwardsWriteBuf(io)), read_buf),
|
io: Rewind::new_buffered(Box::new(io), read_buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +92,9 @@ impl Upgraded {
|
|||||||
/// `Upgraded` back.
|
/// `Upgraded` back.
|
||||||
pub fn downcast<T: AsyncRead + AsyncWrite + Unpin + 'static>(self) -> Result<Parts<T>, Self> {
|
pub fn downcast<T: AsyncRead + AsyncWrite + Unpin + 'static>(self) -> Result<Parts<T>, Self> {
|
||||||
let (io, buf) = self.io.into_inner();
|
let (io, buf) = self.io.into_inner();
|
||||||
match io.__hyper_downcast::<ForwardsWriteBuf<T>>() {
|
match io.__hyper_downcast() {
|
||||||
Ok(t) => Ok(Parts {
|
Ok(t) => Ok(Parts {
|
||||||
io: t.0,
|
io: *t,
|
||||||
read_buf: buf,
|
read_buf: buf,
|
||||||
_inner: (),
|
_inner: (),
|
||||||
}),
|
}),
|
||||||
@@ -221,20 +221,14 @@ impl StdError for UpgradeExpected {}
|
|||||||
|
|
||||||
// ===== impl Io =====
|
// ===== impl Io =====
|
||||||
|
|
||||||
struct ForwardsWriteBuf<T>(T);
|
|
||||||
|
|
||||||
pub(crate) trait Io: AsyncRead + AsyncWrite + Unpin + 'static {
|
pub(crate) trait Io: AsyncRead + AsyncWrite + Unpin + 'static {
|
||||||
fn poll_write_dyn_buf(
|
|
||||||
&mut self,
|
|
||||||
cx: &mut task::Context<'_>,
|
|
||||||
buf: &mut dyn Buf,
|
|
||||||
) -> Poll<io::Result<usize>>;
|
|
||||||
|
|
||||||
fn __hyper_type_id(&self) -> TypeId {
|
fn __hyper_type_id(&self) -> TypeId {
|
||||||
TypeId::of::<Self>()
|
TypeId::of::<Self>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: AsyncRead + AsyncWrite + Unpin + 'static> Io for T {}
|
||||||
|
|
||||||
impl dyn Io + Send {
|
impl dyn Io + Send {
|
||||||
fn __hyper_is<T: Io>(&self) -> bool {
|
fn __hyper_is<T: Io>(&self) -> bool {
|
||||||
let t = TypeId::of::<T>();
|
let t = TypeId::of::<T>();
|
||||||
@@ -254,61 +248,6 @@ impl dyn Io + Send {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsyncRead + Unpin> AsyncRead for ForwardsWriteBuf<T> {
|
|
||||||
fn poll_read(
|
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut task::Context<'_>,
|
|
||||||
buf: &mut ReadBuf<'_>,
|
|
||||||
) -> Poll<io::Result<()>> {
|
|
||||||
Pin::new(&mut self.0).poll_read(cx, buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsyncWrite + Unpin> AsyncWrite for ForwardsWriteBuf<T> {
|
|
||||||
fn poll_write(
|
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut task::Context<'_>,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Poll<io::Result<usize>> {
|
|
||||||
Pin::new(&mut self.0).poll_write(cx, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_write_vectored(
|
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut task::Context<'_>,
|
|
||||||
bufs: &[io::IoSlice<'_>],
|
|
||||||
) -> Poll<io::Result<usize>> {
|
|
||||||
Pin::new(&mut self.0).poll_write_vectored(cx, bufs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {
|
|
||||||
Pin::new(&mut self.0).poll_flush(cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {
|
|
||||||
Pin::new(&mut self.0).poll_shutdown(cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_write_vectored(&self) -> bool {
|
|
||||||
self.0.is_write_vectored()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsyncRead + AsyncWrite + Unpin + 'static> Io for ForwardsWriteBuf<T> {
|
|
||||||
fn poll_write_dyn_buf(
|
|
||||||
&mut self,
|
|
||||||
cx: &mut task::Context<'_>,
|
|
||||||
buf: &mut dyn Buf,
|
|
||||||
) -> Poll<io::Result<usize>> {
|
|
||||||
if self.0.is_write_vectored() {
|
|
||||||
let mut bufs = [io::IoSlice::new(&[]); crate::common::io::MAX_WRITEV_BUFS];
|
|
||||||
let cnt = buf.bytes_vectored(&mut bufs);
|
|
||||||
return Pin::new(&mut self.0).poll_write_vectored(cx, &bufs[..cnt]);
|
|
||||||
}
|
|
||||||
Pin::new(&mut self.0).poll_write(cx, buf.bytes())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod sealed {
|
mod sealed {
|
||||||
use super::OnUpgrade;
|
use super::OnUpgrade;
|
||||||
|
|
||||||
@@ -352,7 +291,6 @@ mod sealed {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use tokio::io::AsyncWriteExt;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn upgraded_downcast() {
|
fn upgraded_downcast() {
|
||||||
@@ -363,15 +301,6 @@ mod tests {
|
|||||||
upgraded.downcast::<Mock>().unwrap();
|
upgraded.downcast::<Mock>().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn upgraded_forwards_write_buf() {
|
|
||||||
// sanity check that the underlying IO implements write_buf
|
|
||||||
Mock.write_buf(&mut "hello".as_bytes()).await.unwrap();
|
|
||||||
|
|
||||||
let mut upgraded = Upgraded::new(Mock, Bytes::new());
|
|
||||||
upgraded.write_buf(&mut "hello".as_bytes()).await.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: replace with tokio_test::io when it can test write_buf
|
// TODO: replace with tokio_test::io when it can test write_buf
|
||||||
struct Mock;
|
struct Mock;
|
||||||
|
|
||||||
@@ -395,17 +324,6 @@ mod tests {
|
|||||||
Poll::Ready(Ok(buf.len()))
|
Poll::Ready(Ok(buf.len()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(eliza): :(
|
|
||||||
// fn poll_write_buf<B: Buf>(
|
|
||||||
// self: Pin<&mut Self>,
|
|
||||||
// _cx: &mut task::Context<'_>,
|
|
||||||
// buf: &mut B,
|
|
||||||
// ) -> Poll<io::Result<usize>> {
|
|
||||||
// let n = buf.remaining();
|
|
||||||
// buf.advance(n);
|
|
||||||
// Poll::Ready(Ok(n))
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn poll_flush(self: Pin<&mut Self>, _cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {
|
fn poll_flush(self: Pin<&mut Self>, _cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {
|
||||||
unreachable!("Mock::poll_flush")
|
unreachable!("Mock::poll_flush")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1209,6 +1209,7 @@ mod dispatch_impl {
|
|||||||
|
|
||||||
// and wait a few ticks for the connections to close
|
// and wait a few ticks for the connections to close
|
||||||
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
||||||
|
futures_util::pin_mut!(t);
|
||||||
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
||||||
future::select(t, close).await;
|
future::select(t, close).await;
|
||||||
}
|
}
|
||||||
@@ -1257,6 +1258,7 @@ mod dispatch_impl {
|
|||||||
|
|
||||||
// res now dropped
|
// res now dropped
|
||||||
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
||||||
|
futures_util::pin_mut!(t);
|
||||||
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
||||||
future::select(t, close).await;
|
future::select(t, close).await;
|
||||||
}
|
}
|
||||||
@@ -1312,6 +1314,7 @@ mod dispatch_impl {
|
|||||||
|
|
||||||
// and wait a few ticks to see the connection drop
|
// and wait a few ticks to see the connection drop
|
||||||
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
||||||
|
futures_util::pin_mut!(t);
|
||||||
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
||||||
future::select(t, close).await;
|
future::select(t, close).await;
|
||||||
}
|
}
|
||||||
@@ -1362,6 +1365,7 @@ mod dispatch_impl {
|
|||||||
res.unwrap();
|
res.unwrap();
|
||||||
|
|
||||||
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
||||||
|
futures_util::pin_mut!(t);
|
||||||
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
||||||
future::select(t, close).await;
|
future::select(t, close).await;
|
||||||
}
|
}
|
||||||
@@ -1408,6 +1412,7 @@ mod dispatch_impl {
|
|||||||
res.unwrap();
|
res.unwrap();
|
||||||
|
|
||||||
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
let t = tokio::time::sleep(Duration::from_millis(100)).map(|_| panic!("time out"));
|
||||||
|
futures_util::pin_mut!(t);
|
||||||
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
let close = closes.into_future().map(|(opt, _)| opt.expect("closes"));
|
||||||
future::select(t, close).await;
|
future::select(t, close).await;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user