diff --git a/src/conn.rs b/src/conn.rs index c1d194b..4501361 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -22,6 +22,12 @@ impl ConnectionPool { ) -> Result { // + let do_chunk = request.header("transfer-encoding") + // if the user has set an encoding header, obey that. + .map(|enc| enc.len() > 0) + // otherwise, no chunking. + .unwrap_or(false); + let hostname = url.host_str().unwrap_or("localhost"); // is localhost a good alternative? let is_secure = url.scheme().eq_ignore_ascii_case("https"); @@ -31,13 +37,23 @@ impl ConnectionPool { Some(jar) => match_cookies(jar, hostname, url.path(), is_secure), } }; - let headers = request.headers.iter().chain(cookie_headers.iter()); + let extra_headers = { + let mut extra = vec![]; - let do_chunk = request.header("transfer-encoding") - // if the user has set an encoding header, obey that. - .map(|enc| enc.len() > 0) - // otherwise, no chunking. - .unwrap_or(false); + // chunking and Content-Length headers are mutually exclusive + // also don't write this if the user has set it themselves + if !do_chunk && !request.has("content-length") { + if let Some(size) = body.size { + extra.push(format!("Content-Length: {}\r\n", size).parse::
()?); + } + } + extra + }; + let headers = request + .headers + .iter() + .chain(cookie_headers.iter()) + .chain(extra_headers.iter()); // open socket let mut stream = match url.scheme() { @@ -56,13 +72,6 @@ impl ConnectionPool { for header in headers { write!(prelude, "{}: {}\r\n", header.name(), header.value())?; } - // chunking and Content-Length headers are mutually exclusive - // also don't write this if the user has set it themselves - if !do_chunk && !request.has("content-length") { - if let Some(size) = body.size { - write!(prelude, "Content-Length: {}\r\n", size)?; - } - } write!(prelude, "\r\n")?; stream.write_all(&mut prelude[..])?; diff --git a/src/lib.rs b/src/lib.rs index ac5f983..b4e8a2b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,8 +41,8 @@ //! //! ``` //! let resp = ureq::post("http://my-server.com/ingest") -//! .set("Transfer-Encoding", "chunked")` -//! .send("Hello world"); +//! .set("Transfer-Encoding", "chunked") +//! .send_str("Hello world"); //! ``` extern crate ascii; diff --git a/src/request.rs b/src/request.rs index 434f015..e46a232 100644 --- a/src/request.rs +++ b/src/request.rs @@ -35,6 +35,16 @@ pub struct Request { redirects: u32, } +impl ::std::fmt::Debug for Request { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> { + write!( + f, + "Request[{} {}, {}, {:?}]", + self.method, self.path, self.query, self.headers + ) + } +} + enum Payload { Empty, Text(String), diff --git a/src/test/body_send.rs b/src/test/body_send.rs new file mode 100644 index 0000000..62191ad --- /dev/null +++ b/src/test/body_send.rs @@ -0,0 +1,29 @@ +use test; + +use super::super::*; + +#[test] +fn content_length_on_str() { + test::set_handler("/content_length_on_str", |_req, _url| { + test::make_response(200, "OK", vec![], vec![]) + }); + let resp = get("test://host/content_length_on_str") + .send_str("Hello World!!!"); + let vec = resp.to_write_vec(); + let s = String::from_utf8_lossy(&vec); + assert!(s.contains("\r\nContent-Length: 14\r\n")) +} + +#[test] +fn content_length_on_json() { + test::set_handler("/content_length_on_json", |_req, _url| { + test::make_response(200, "OK", vec![], vec![]) + }); + let mut json = SerdeMap::new(); + json.insert("Hello".to_string(), SerdeValue::String("World!!!".to_string())); + let resp = get("test://host/content_length_on_json") + .send_json(SerdeValue::Object(json)); + let vec = resp.to_write_vec(); + let s = String::from_utf8_lossy(&vec); + assert!(s.contains("\r\nContent-Length: 20\r\n")) +} diff --git a/src/test/mod.rs b/src/test/mod.rs index d38a759..2acd586 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -11,6 +11,7 @@ use std::io::Cursor; mod agent_test; mod auth; mod body_read; +mod body_send; mod simple; type RequestHandler = Fn(&Request, &Url) -> Result + Send + 'static;