content length

This commit is contained in:
Martin Algesten
2018-06-16 12:35:51 +02:00
parent 0d9d5d3096
commit 7e3ad42674
5 changed files with 64 additions and 15 deletions

View File

@@ -22,6 +22,12 @@ impl ConnectionPool {
) -> Result<Response, Error> {
//
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::<Header>()?);
}
}
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[..])?;

View File

@@ -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;

View File

@@ -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),

29
src/test/body_send.rs Normal file
View File

@@ -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"))
}

View File

@@ -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<Stream, Error> + Send + 'static;