Skip to content

Commit cc5ee28

Browse files
authored
Merge pull request #14 from mmstick/isahc-body-request-fix
fix: Body's reader is now optional; may be checked for emptiness
2 parents 3124c74 + 851baf3 commit cc5ee28

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

src/isahc.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,16 @@ impl HttpClient for IsahcClient {
4242
let client = self.client.clone();
4343
Box::pin(async move {
4444
let (parts, body) = req.into_parts();
45-
let body = match body.len {
46-
Some(len) => isahc::Body::reader_sized(body, len),
47-
None => isahc::Body::reader(body),
45+
46+
let body = if body.is_empty() {
47+
isahc::Body::empty()
48+
} else {
49+
match body.len {
50+
Some(len) => isahc::Body::reader_sized(body, len),
51+
None => isahc::Body::reader(body),
52+
}
4853
};
54+
4955
let req: http::Request<isahc::Body> = http::Request::from_parts(parts, body);
5056

5157
let res = client.send_async(req).await?;

src/lib.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub trait HttpClient: Debug + Unpin + Send + Sync + Clone + 'static {
6969
/// Both `Body` and `Bytes` values can be easily created from standard owned byte buffer types
7070
/// like `Vec<u8>` or `String`, using the `From` trait.
7171
pub struct Body {
72-
reader: Box<dyn AsyncRead + Unpin + Send + 'static>,
72+
reader: Option<Box<dyn AsyncRead + Unpin + Send + 'static>>,
7373
/// Intentionally use `u64` over `usize` here.
7474
/// `usize` won't work if you try to send 10GB file from 32bit host.
7575
#[allow(dead_code)] // not all backends make use of this
@@ -80,18 +80,23 @@ impl Body {
8080
/// Create a new empty body.
8181
pub fn empty() -> Self {
8282
Self {
83-
reader: Box::new(futures::io::empty()),
83+
reader: None,
8484
len: Some(0),
8585
}
8686
}
8787

8888
/// Create a new instance from a reader.
8989
pub fn from_reader(reader: impl AsyncRead + Unpin + Send + 'static) -> Self {
9090
Self {
91-
reader: Box::new(reader),
91+
reader: Some(Box::new(reader)),
9292
len: None,
9393
}
9494
}
95+
96+
/// Validate that the body was created with `Body::empty()`.
97+
pub fn is_empty(&self) -> bool {
98+
self.reader.is_none()
99+
}
95100
}
96101

97102
impl AsyncRead for Body {
@@ -101,7 +106,10 @@ impl AsyncRead for Body {
101106
cx: &mut Context<'_>,
102107
buf: &mut [u8],
103108
) -> Poll<io::Result<usize>> {
104-
Pin::new(&mut self.reader).poll_read(cx, buf)
109+
match self.reader.as_mut() {
110+
Some(reader) => Pin::new(reader).poll_read(cx, buf),
111+
None => Poll::Ready(Ok(0)),
112+
}
105113
}
106114
}
107115

@@ -118,7 +126,7 @@ impl From<Vec<u8>> for Body {
118126
fn from(vec: Vec<u8>) -> Body {
119127
let len = vec.len() as u64;
120128
Self {
121-
reader: Box::new(Cursor::new(vec)),
129+
reader: Some(Box::new(Cursor::new(vec))),
122130
len: Some(len),
123131
}
124132
}
@@ -128,6 +136,9 @@ impl<R: AsyncRead + Unpin + Send + 'static> From<Box<R>> for Body {
128136
/// Converts an `AsyncRead` into a Body.
129137
#[allow(missing_doc_code_examples)]
130138
fn from(reader: Box<R>) -> Self {
131-
Self { reader, len: None }
139+
Self {
140+
reader: Some(reader),
141+
len: None,
142+
}
132143
}
133144
}

0 commit comments

Comments
 (0)