diff --git a/Cargo.toml b/Cargo.toml index 843c069e..217c24b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,17 +16,27 @@ features = ["docs"] rustdoc-args = ["--cfg", "feature=\"docs\""] [features] -default = ["async_std", "cookie-secure"] +default = ["cookie-secure"] docs = ["unstable"] unstable = [] hyperium_http = ["http"] -async_std = [] # "async-std" when it is not default +async_std = ["async-std"] # "async-std" when it is not default cookie-secure = ["cookie/secure"] +[dependencies.futures-io] +default-features = false +features = ["std"] +version = "0.3" + +[dependencies.futures-util] +default-features = false +features = ["std","sink"] +version = "0.3" + [dependencies] # Note(yoshuawuyts): used for async_std's `channel` only; use "core" once possible. # features: async_std -async-std = { version = "1.6.0", features = ["unstable"] } +async-std = { version = "1.6.0", optional = true, features = ["unstable"] } # features: hyperium/http http = { version = "0.2.0", optional = true } @@ -35,10 +45,11 @@ anyhow = "1.0.26" cookie = { version = "0.13.0", features = ["percent-encode"] } infer = "0.1.2" pin-project-lite = "0.1.0" -url = "2.1.1" -serde_json = "1.0.51" -serde = { version = "1.0.106", features = ["derive"] } -serde_urlencoded = "0.6.1" +url = "*" +serde_json = "*" +serde = { version = "*", features = ["derive"] } +serde_urlencoded = "*" +async-channel = "1" [dev-dependencies] http = "0.2.0" diff --git a/src/body.rs b/src/body.rs index bda6f214..0e2e461b 100644 --- a/src/body.rs +++ b/src/body.rs @@ -1,5 +1,5 @@ -use async_std::io::prelude::*; -use async_std::io::{self, Cursor}; +//use async_std::io::prelude::*; +//use async_std::io::{self, Cursor}; use serde::{de::DeserializeOwned, Serialize}; use std::fmt::{self, Debug}; @@ -8,6 +8,9 @@ use std::task::{Context, Poll}; use crate::{mime, Mime}; use crate::{Status, StatusCode}; +use futures_io::{AsyncRead, AsyncBufRead}; +use futures_util::{AsyncReadExt}; +use futures_util::io::Cursor; pin_project_lite::pin_project! { /// A streaming HTTP body. @@ -54,7 +57,7 @@ pin_project_lite::pin_project! { /// and not rely on the fallback mechanisms. However, they're still there if you need them. pub struct Body { #[pin] - reader: Box, + reader: Box, mime: Mime, length: Option, } @@ -76,7 +79,7 @@ impl Body { /// ``` pub fn empty() -> Self { Self { - reader: Box::new(io::empty()), + reader: Box::new(futures_util::io::empty()), mime: mime::BYTE_STREAM, length: Some(0), } @@ -102,7 +105,7 @@ impl Body { /// req.set_body(Body::from_reader(cursor, Some(len))); /// ``` pub fn from_reader( - reader: impl BufRead + Unpin + Send + Sync + 'static, + reader: impl AsyncBufRead + Unpin + Send + Sync + 'static, len: Option, ) -> Self { Self { @@ -125,7 +128,7 @@ impl Body { /// let body = Body::from_reader(cursor, None); /// let _ = body.into_reader(); /// ``` - pub fn into_reader(self) -> Box { + pub fn into_reader(self) -> Box { self.reader } @@ -151,7 +154,7 @@ impl Body { Self { mime: mime::BYTE_STREAM, length: Some(bytes.len()), - reader: Box::new(io::Cursor::new(bytes)), + reader: Box::new(Cursor::new(bytes)), } } @@ -200,7 +203,7 @@ impl Body { Self { mime: mime::PLAIN, length: Some(s.len()), - reader: Box::new(io::Cursor::new(s.into_bytes())), + reader: Box::new(Cursor::new(s.into_bytes())), } } @@ -449,20 +452,20 @@ impl<'a> From<&'a [u8]> for Body { } } -impl Read for Body { +impl AsyncRead for Body { #[allow(missing_doc_code_examples)] fn poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], - ) -> Poll> { + ) -> Poll> { Pin::new(&mut self.reader).poll_read(cx, buf) } } -impl BufRead for Body { +impl AsyncBufRead for Body { #[allow(missing_doc_code_examples)] - fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); this.reader.poll_fill_buf(cx) } @@ -475,14 +478,14 @@ impl BufRead for Body { /// Look at first few bytes of a file to determine the mime type. /// This is used for various binary formats such as images and videos. #[cfg(all(feature = "async_std", not(target_os = "unknown")))] -async fn peek_mime(file: &mut async_std::fs::File) -> io::Result> { +async fn peek_mime(file: &mut async_std::fs::File) -> futures_io::Result> { // We need to read the first 300 bytes to correctly infer formats such as tar. let mut buf = [0_u8; 300]; file.read(&mut buf).await?; let mime = Mime::sniff(&buf).ok(); // Reset the file cursor back to the start. - file.seek(io::SeekFrom::Start(0)).await?; + file.seek(futures_io::SeekFrom::Start(0)).await?; Ok(mime) } diff --git a/src/request.rs b/src/request.rs index fb007600..e105337e 100644 --- a/src/request.rs +++ b/src/request.rs @@ -1,5 +1,5 @@ -use async_std::io::{self, BufRead, Read}; -use async_std::sync; +//use async_std::io::{self, BufRead, Read}; +//use async_std::sync; use std::convert::{Into, TryInto}; use std::mem; @@ -15,6 +15,7 @@ use crate::headers::{ use crate::mime::Mime; use crate::trailers::{self, Trailers}; use crate::{Body, Extensions, Method, StatusCode, Url, Version}; +use futures_io::{AsyncRead, AsyncBufRead}; pin_project_lite::pin_project! { /// An HTTP request. @@ -38,8 +39,8 @@ pin_project_lite::pin_project! { local_addr: Option, peer_addr: Option, ext: Extensions, - trailers_sender: Option>, - trailers_receiver: Option>, + trailers_sender: Option>, + trailers_receiver: Option>, } } @@ -51,7 +52,7 @@ impl Request { U::Error: std::fmt::Debug, { let url = url.try_into().expect("Could not convert into a valid url"); - let (trailers_sender, trailers_receiver) = sync::channel(1); + let (trailers_sender, trailers_receiver) = async_channel::bounded(1); Self { method, url, @@ -877,20 +878,20 @@ impl Clone for Request { } } -impl Read for Request { +impl AsyncRead for Request { #[allow(missing_doc_code_examples)] fn poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], - ) -> Poll> { + ) -> Poll> { Pin::new(&mut self.body).poll_read(cx, buf) } } -impl BufRead for Request { +impl AsyncBufRead for Request { #[allow(missing_doc_code_examples)] - fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); this.body.poll_fill_buf(cx) } diff --git a/src/response.rs b/src/response.rs index ad97ca52..721e9558 100644 --- a/src/response.rs +++ b/src/response.rs @@ -1,5 +1,5 @@ -use async_std::io::{self, BufRead, Read}; -use async_std::sync; +//use async_std::io::{self, BufRead, Read}; +//use async_std::sync; use std::convert::{Into, TryInto}; use std::fmt::Debug; @@ -16,6 +16,7 @@ use crate::headers::{ use crate::mime::Mime; use crate::trailers::{self, Trailers}; use crate::{Body, Extensions, StatusCode, Version}; +use futures_io::{AsyncRead, AsyncBufRead}; cfg_unstable! { use crate::upgrade; @@ -42,8 +43,8 @@ pin_project_lite::pin_project! { status: StatusCode, headers: Headers, version: Option, - trailers_sender: Option>, - trailers_receiver: Option>, + trailers_sender: Option>, + trailers_receiver: Option>, #[pin] body: Body, ext: Extensions, @@ -73,10 +74,10 @@ pin_project_lite::pin_project! { status: StatusCode, headers: Headers, version: Option, - trailers_sender: Option>, - trailers_receiver: Option>, - upgrade_sender: Option>, - upgrade_receiver: Option>, + trailers_sender: Option>, + trailers_receiver: Option>, + upgrade_sender: Option>, + upgrade_receiver: Option>, has_upgrade: bool, #[pin] body: Body, @@ -97,7 +98,7 @@ impl Response { let status = status .try_into() .expect("Could not convert into a valid `StatusCode`"); - let (trailers_sender, trailers_receiver) = sync::channel(1); + let (trailers_sender, trailers_receiver) = async_channel::bounded(1); Self { status, headers: Headers::new(), @@ -121,8 +122,8 @@ impl Response { let status = status .try_into() .expect("Could not convert into a valid `StatusCode`"); - let (trailers_sender, trailers_receiver) = sync::channel(1); - let (upgrade_sender, upgrade_receiver) = sync::channel(1); + let (trailers_sender, trailers_receiver) = async_channel::bounded(1); + let (upgrade_sender, upgrade_receiver) = async_channel::bounded(1); Self { status, headers: Headers::new(), @@ -268,7 +269,7 @@ impl Response { /// req.swap_body(&mut body); /// /// let mut string = String::new(); - /// body.read_to_string(&mut string).await?; + /// body.read_to(&mut string).await?; /// assert_eq!(&string, "Hello, Nori!"); /// # /// # Ok(()) }) } @@ -654,20 +655,20 @@ impl Clone for Response { } } -impl Read for Response { +impl AsyncRead for Response { #[allow(missing_doc_code_examples)] fn poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], - ) -> Poll> { + ) -> Poll> { Pin::new(&mut self.body).poll_read(cx, buf) } } -impl BufRead for Response { +impl AsyncBufRead for Response { #[allow(missing_doc_code_examples)] - fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); this.body.poll_fill_buf(cx) } diff --git a/src/trailers.rs b/src/trailers.rs index 231a7472..173ccdfe 100644 --- a/src/trailers.rs +++ b/src/trailers.rs @@ -50,14 +50,15 @@ use crate::headers::{ HeaderName, HeaderValues, Headers, Iter, IterMut, Names, ToHeaderValues, Values, }; -use async_std::prelude::*; -use async_std::sync; +//use async_std::prelude::*; +//use async_std::sync; use std::convert::Into; use std::future::Future; use std::ops::{Deref, DerefMut, Index}; use std::pin::Pin; use std::task::{Context, Poll}; +use futures_util::stream::Stream; /// A collection of trailing HTTP headers. #[derive(Debug)] @@ -212,13 +213,13 @@ impl Index<&str> for Trailers { /// `Trailers` should be created. #[derive(Debug)] pub struct Sender { - sender: sync::Sender, + sender: async_channel::Sender, } impl Sender { /// Create a new instance of `Sender`. #[doc(hidden)] - pub fn new(sender: sync::Sender) -> Self { + pub fn new(sender: async_channel::Sender) -> Self { Self { sender } } @@ -226,7 +227,7 @@ impl Sender { /// /// The channel will be consumed after having sent trailers. pub async fn send(self, trailers: Trailers) { - self.sender.send(trailers).await + let _ = self.sender.send(trailers).await; } } @@ -238,12 +239,12 @@ impl Sender { #[must_use = "Futures do nothing unless polled or .awaited"] #[derive(Debug)] pub struct Receiver { - receiver: sync::Receiver, + receiver: async_channel::Receiver, } impl Receiver { /// Create a new instance of `Receiver`. - pub(crate) fn new(receiver: sync::Receiver) -> Self { + pub(crate) fn new(receiver: async_channel::Receiver) -> Self { Self { receiver } } } diff --git a/src/upgrade/connection.rs b/src/upgrade/connection.rs index abd47ec6..396fe3b7 100644 --- a/src/upgrade/connection.rs +++ b/src/upgrade/connection.rs @@ -1,4 +1,4 @@ -use async_std::io::{self, prelude::*}; +//use async_std::io::{self, prelude::*}; use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/src/upgrade/receiver.rs b/src/upgrade/receiver.rs index 44f4522a..e51e4801 100644 --- a/src/upgrade/receiver.rs +++ b/src/upgrade/receiver.rs @@ -1,5 +1,5 @@ -use async_std::prelude::*; -use async_std::sync; +//use async_std::prelude::*; +//use async_std::sync; use std::future::Future; use std::pin::Pin; diff --git a/src/upgrade/sender.rs b/src/upgrade/sender.rs index 562a455b..3265bf41 100644 --- a/src/upgrade/sender.rs +++ b/src/upgrade/sender.rs @@ -1,4 +1,4 @@ -use async_std::sync; +//use async_std::sync; use crate::upgrade::Connection;