Update to tokio 1.0, bytes 1.0 (#1076)

Co-authored-by: Wim Looman <git@nemo157.com>
Co-authored-by: Paolo Barbolini <paolo@paolo565.org>
This commit is contained in:
messense
2020-12-31 01:57:50 +08:00
committed by GitHub
parent 5ee4fe5ab6
commit a19eb34196
16 changed files with 173 additions and 219 deletions

View File

@@ -7,7 +7,7 @@ use bytes::Bytes;
use futures_core::Stream;
use http_body::Body as HttpBody;
use pin_project_lite::pin_project;
use tokio::time::Delay;
use tokio::time::Sleep;
/// An asynchronous request body.
pub struct Body {
@@ -27,7 +27,7 @@ enum Inner {
+ Sync,
>,
>,
timeout: Option<Delay>,
timeout: Option<Pin<Box<Sleep>>>,
},
}
@@ -103,7 +103,7 @@ impl Body {
}
}
pub(crate) fn response(body: hyper::Body, timeout: Option<Delay>) -> Body {
pub(crate) fn response(body: hyper::Body, timeout: Option<Pin<Box<Sleep>>>) -> Body {
Body {
inner: Inner::Streaming {
body: Box::pin(WrapHyper(body)),
@@ -217,7 +217,7 @@ impl HttpBody for ImplStream {
ref mut timeout,
} => {
if let Some(ref mut timeout) = timeout {
if let Poll::Ready(()) = Pin::new(timeout).poll(cx) {
if let Poll::Ready(()) = timeout.as_mut().poll(cx) {
return Poll::Ready(Some(Err(crate::error::body(crate::error::TimedOut))));
}
}

View File

@@ -26,7 +26,7 @@ use rustls::RootCertStore;
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::time::Delay;
use tokio::time::Sleep;
use pin_project_lite::pin_project;
use log::debug;
@@ -96,7 +96,6 @@ struct Config {
#[cfg(feature = "__tls")]
tls: TlsBackend,
http2_only: bool,
http1_writev: Option<bool>,
http1_title_case_headers: bool,
http2_initial_stream_window_size: Option<u32>,
http2_initial_connection_window_size: Option<u32>,
@@ -151,7 +150,6 @@ impl ClientBuilder {
#[cfg(feature = "__tls")]
tls: TlsBackend::default(),
http2_only: false,
http1_writev: None,
http1_title_case_headers: false,
http2_initial_stream_window_size: None,
http2_initial_connection_window_size: None,
@@ -316,10 +314,6 @@ impl ClientBuilder {
builder.http2_only(true);
}
if let Some(http1_writev) = config.http1_writev {
builder.http1_writev(http1_writev);
}
if let Some(http2_initial_stream_window_size) = config.http2_initial_stream_window_size {
builder.http2_initial_stream_window_size(http2_initial_stream_window_size);
}
@@ -655,14 +649,6 @@ impl ClientBuilder {
self
}
/// Force hyper to use either queued(if true), or flattened(if false) write strategy
/// This may eliminate unnecessary cloning of buffers for some TLS backends
/// By default hyper will try to guess which strategy to use
pub fn http1_writev(mut self, writev: bool) -> ClientBuilder {
self.config.http1_writev = Some(writev);
self
}
/// Only use HTTP/2.
pub fn http2_prior_knowledge(mut self) -> ClientBuilder {
self.config.http2_only = true;
@@ -1103,7 +1089,8 @@ impl Client {
let timeout = timeout
.or(self.inner.request_timeout)
.map(tokio::time::delay_for);
.map(tokio::time::sleep)
.map(Box::pin);
*req.headers_mut() = headers.clone();
@@ -1317,7 +1304,7 @@ pin_project! {
#[pin]
in_flight: ResponseFuture,
#[pin]
timeout: Option<Delay>,
timeout: Option<Pin<Box<Sleep>>>,
}
}
@@ -1326,7 +1313,7 @@ impl PendingRequest {
self.project().in_flight
}
fn timeout(self: Pin<&mut Self>) -> Pin<&mut Option<Delay>> {
fn timeout(self: Pin<&mut Self>) -> Pin<&mut Option<Pin<Box<Sleep>>>> {
self.project().timeout
}

View File

@@ -4,10 +4,10 @@ use std::pin::Pin;
use std::task::{Context, Poll};
#[cfg(feature = "gzip")]
use async_compression::stream::GzipDecoder;
use async_compression::tokio::bufread::GzipDecoder;
#[cfg(feature = "brotli")]
use async_compression::stream::BrotliDecoder;
use async_compression::tokio::bufread::BrotliDecoder;
use bytes::Bytes;
use futures_core::Stream;
@@ -15,6 +15,11 @@ use futures_util::stream::Peekable;
use http::HeaderMap;
use hyper::body::HttpBody;
#[cfg(any(feature = "gzip", feature = "brotli"))]
use tokio_util::io::StreamReader;
#[cfg(any(feature = "gzip", feature = "brotli"))]
use tokio_util::codec::{BytesCodec, FramedRead};
use super::super::Body;
use crate::error;
@@ -39,11 +44,11 @@ enum Inner {
/// A `Gzip` decoder will uncompress the gzipped response content before returning it.
#[cfg(feature = "gzip")]
Gzip(GzipDecoder<Peekable<IoStream>>),
Gzip(FramedRead<GzipDecoder<StreamReader<Peekable<IoStream>, Bytes>>, BytesCodec>),
/// A `Brotli` decoder will uncompress the brotlied response content before returning it.
#[cfg(feature = "brotli")]
Brotli(BrotliDecoder<Peekable<IoStream>>),
Brotli(FramedRead<BrotliDecoder<StreamReader<Peekable<IoStream>, Bytes>>, BytesCodec>),
/// A decoder that doesn't have a value yet.
#[cfg(any(feature = "brotli", feature = "gzip"))]
@@ -229,7 +234,7 @@ impl Stream for Decoder {
#[cfg(feature = "gzip")]
Inner::Gzip(ref mut decoder) => {
return match futures_core::ready!(Pin::new(decoder).poll_next(cx)) {
Some(Ok(bytes)) => Poll::Ready(Some(Ok(bytes))),
Some(Ok(bytes)) => Poll::Ready(Some(Ok(bytes.freeze()))),
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
None => Poll::Ready(None),
};
@@ -237,7 +242,7 @@ impl Stream for Decoder {
#[cfg(feature = "brotli")]
Inner::Brotli(ref mut decoder) => {
return match futures_core::ready!(Pin::new(decoder).poll_next(cx)) {
Some(Ok(bytes)) => Poll::Ready(Some(Ok(bytes))),
Some(Ok(bytes)) => Poll::Ready(Some(Ok(bytes.freeze()))),
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
None => Poll::Ready(None),
};
@@ -302,9 +307,9 @@ impl Future for Pending {
match self.1 {
#[cfg(feature = "brotli")]
DecoderType::Brotli => Poll::Ready(Ok(Inner::Brotli(BrotliDecoder::new(_body)))),
DecoderType::Brotli => Poll::Ready(Ok(Inner::Brotli(FramedRead::new(BrotliDecoder::new(StreamReader::new(_body)), BytesCodec::new())))),
#[cfg(feature = "gzip")]
DecoderType::Gzip => Poll::Ready(Ok(Inner::Gzip(GzipDecoder::new(_body)))),
DecoderType::Gzip => Poll::Ready(Ok(Inner::Gzip(FramedRead::new(GzipDecoder::new(StreamReader::new(_body)), BytesCodec::new())))),
}
}
}

View File

@@ -521,11 +521,7 @@ mod tests {
fn form_empty() {
let form = Form::new();
let mut rt = runtime::Builder::new()
.basic_scheduler()
.enable_all()
.build()
.expect("new rt");
let rt = runtime::Builder::new_current_thread().enable_all().build().expect("new rt");
let body = form.stream().into_stream();
let s = body.map_ok(|try_c| try_c.to_vec()).try_concat();
@@ -572,11 +568,7 @@ mod tests {
--boundary\r\n\
Content-Disposition: form-data; name=\"key3\"; filename=\"filename\"\r\n\r\n\
value3\r\n--boundary--\r\n";
let mut rt = runtime::Builder::new()
.basic_scheduler()
.enable_all()
.build()
.expect("new rt");
let rt = runtime::Builder::new_current_thread().enable_all().build().expect("new rt");
let body = form.stream().into_stream();
let s = body.map(|try_c| try_c.map(|r| r.to_vec())).try_concat();
@@ -603,11 +595,7 @@ mod tests {
\r\n\
value2\r\n\
--boundary--\r\n";
let mut rt = runtime::Builder::new()
.basic_scheduler()
.enable_all()
.build()
.expect("new rt");
let rt = runtime::Builder::new_current_thread().enable_all().build().expect("new rt");
let body = form.stream().into_stream();
let s = body.map(|try_c| try_c.map(|r| r.to_vec())).try_concat();

View File

@@ -1,6 +1,7 @@
use std::borrow::Cow;
use std::fmt;
use std::net::SocketAddr;
use std::pin::Pin;
use bytes::Bytes;
use encoding_rs::{Encoding, UTF_8};
@@ -12,7 +13,7 @@ use mime::Mime;
use serde::de::DeserializeOwned;
#[cfg(feature = "json")]
use serde_json;
use tokio::time::Delay;
use tokio::time::Sleep;
use url::Url;
use super::body::Body;
@@ -37,7 +38,7 @@ impl Response {
res: hyper::Response<hyper::Body>,
url: Url,
accepts: Accepts,
timeout: Option<Delay>,
timeout: Option<Pin<Box<Sleep>>>,
) -> Response {
let (parts, body) = res.into_parts();
let status = parts.status;