Skip to content

Commit

Permalink
Merge pull request #14 from mmstick/isahc-body-request-fix
Browse files Browse the repository at this point in the history
fix: Body's reader is now optional; may be checked for emptiness
  • Loading branch information
yoshuawuyts committed Jan 14, 2020
2 parents 3124c74 + 851baf3 commit cc5ee28
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
12 changes: 9 additions & 3 deletions src/isahc.rs
Expand Up @@ -42,10 +42,16 @@ impl HttpClient for IsahcClient {
let client = self.client.clone();
Box::pin(async move {
let (parts, body) = req.into_parts();
let body = match body.len {
Some(len) => isahc::Body::reader_sized(body, len),
None => isahc::Body::reader(body),

let body = if body.is_empty() {
isahc::Body::empty()
} else {
match body.len {
Some(len) => isahc::Body::reader_sized(body, len),
None => isahc::Body::reader(body),
}
};

let req: http::Request<isahc::Body> = http::Request::from_parts(parts, body);

let res = client.send_async(req).await?;
Expand Down
23 changes: 17 additions & 6 deletions src/lib.rs
Expand Up @@ -69,7 +69,7 @@ pub trait HttpClient: Debug + Unpin + Send + Sync + Clone + 'static {
/// Both `Body` and `Bytes` values can be easily created from standard owned byte buffer types
/// like `Vec<u8>` or `String`, using the `From` trait.
pub struct Body {
reader: Box<dyn AsyncRead + Unpin + Send + 'static>,
reader: Option<Box<dyn AsyncRead + Unpin + Send + 'static>>,
/// Intentionally use `u64` over `usize` here.
/// `usize` won't work if you try to send 10GB file from 32bit host.
#[allow(dead_code)] // not all backends make use of this
Expand All @@ -80,18 +80,23 @@ impl Body {
/// Create a new empty body.
pub fn empty() -> Self {
Self {
reader: Box::new(futures::io::empty()),
reader: None,
len: Some(0),
}
}

/// Create a new instance from a reader.
pub fn from_reader(reader: impl AsyncRead + Unpin + Send + 'static) -> Self {
Self {
reader: Box::new(reader),
reader: Some(Box::new(reader)),
len: None,
}
}

/// Validate that the body was created with `Body::empty()`.
pub fn is_empty(&self) -> bool {
self.reader.is_none()
}
}

impl AsyncRead for Body {
Expand All @@ -101,7 +106,10 @@ impl AsyncRead for Body {
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
Pin::new(&mut self.reader).poll_read(cx, buf)
match self.reader.as_mut() {
Some(reader) => Pin::new(reader).poll_read(cx, buf),
None => Poll::Ready(Ok(0)),
}
}
}

Expand All @@ -118,7 +126,7 @@ impl From<Vec<u8>> for Body {
fn from(vec: Vec<u8>) -> Body {
let len = vec.len() as u64;
Self {
reader: Box::new(Cursor::new(vec)),
reader: Some(Box::new(Cursor::new(vec))),
len: Some(len),
}
}
Expand All @@ -128,6 +136,9 @@ impl<R: AsyncRead + Unpin + Send + 'static> From<Box<R>> for Body {
/// Converts an `AsyncRead` into a Body.
#[allow(missing_doc_code_examples)]
fn from(reader: Box<R>) -> Self {
Self { reader, len: None }
Self {
reader: Some(reader),
len: None,
}
}
}

0 comments on commit cc5ee28

Please sign in to comment.