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:
@@ -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))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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())))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user