diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/src/lib.rs b/src/lib.rs index 76d4c68e8b90..b52ebc3ef09c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,7 +77,7 @@ extern crate curl; pub use curl::init; -use curl::easy::{Auth, Easy, Form, List, ReadError}; +use curl::easy::{Auth, Easy, Form, List, Transfer, ReadError, WriteError}; use std::collections::HashMap; use std::io::Write; use std::path::Path; @@ -379,18 +379,10 @@ impl <'a> Request<'a> { // Write the payload if it exists: match self.body { - Body::Bytes { data, .. } => transfer.read_function(move |mut into| { - into.write_all(data) - .map(|_| data.len()) - .map_err(|_| ReadError::Abort) - })?, + Body::Bytes { data, .. } => chunked_read_function(&mut transfer, data)?, #[cfg(feature = "json")] - Body::Json(json) => transfer.read_function(move |mut into| { - into.write_all(&json) - .map(|_| json.len()) - .map_err(|_| ReadError::Abort) - })?, + Body::Json(ref json) => chunked_read_function(&mut transfer, json)?, // Do nothing if there is no body or if the body is a // form. @@ -426,7 +418,7 @@ impl <'a> Request<'a> { let len = data.len(); body.write_all(data) .map(|_| len) - .map_err(|err| panic!("{:?}", err)) + .map_err(|_| WriteError::Pause) })?; transfer.perform()?; @@ -440,6 +432,26 @@ impl <'a> Request<'a> { } } +/// Provide a data chunk potentially larger than cURL's initial write +/// buffer to the data reading callback by tracking the offset off +/// already written data. +/// +/// As we manually set the expected upload size, cURL will call the +/// read callback repeatedly until it has all the data it needs. +fn chunked_read_function<'easy, 'data>(transfer: &mut Transfer<'easy, 'data>, + data: &'data [u8]) -> Result<(), curl::Error> { + let mut data = data; + + transfer.read_function(move |mut into| { + let written = into.write(data) + .map_err(|_| ReadError::Abort)?; + + data = &data[written..]; + + Ok(written) + }) +} + impl <T> Response<T> { /// Check whether the status code of this HTTP response is a /// success (i.e. in the 200-299 range). |