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