Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix using Transfer-Encoding: identity with no content length #126

Merged
merged 1 commit into from Dec 15, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/response.rs
Expand Up @@ -60,6 +60,7 @@ pub type ResponseBox = Response<Box<Read + Send>>;

/// Transfer encoding to use when sending the message.
/// Note that only *supported* encoding are listed here.
#[derive(Copy, Clone)]
enum TransferEncoding {
Identity,
Chunked,
Expand Down Expand Up @@ -298,6 +299,20 @@ impl<R> Response<R> where R: Read {
transfer_encoding = None;
}

// if the transfer encoding is identity, the content length must be known ; therefore if
// we don't know it, we buffer the entire response first here
// while this is an expensive operation, it is only ever needed for clients using HTTP 1.0
let (mut reader, data_length) = match (self.data_length, transfer_encoding) {
(Some(l), _) => (Box::new(self.reader) as Box<Read>, Some(l)),
(None, Some(TransferEncoding::Identity)) => {
let mut buf = Vec::new();
try!(self.reader.read_to_end(&mut buf));
let l = buf.len();
(Box::new(Cursor::new(buf)) as Box<Read>, Some(l))
},
_ => (Box::new(self.reader) as Box<Read>, None),
};

// checking whether to ignore the body of the response
let do_not_send_body = do_not_send_body ||
match self.status_code.0 {
Expand All @@ -315,8 +330,8 @@ impl<R> Response<R> where R: Read {
},

Some(TransferEncoding::Identity) => {
assert!(self.data_length.is_some());
let data_length = self.data_length.unwrap();
assert!(data_length.is_some());
let data_length = data_length.unwrap();

self.headers.push(
Header::from_bytes(&b"Content-Length"[..], format!("{}", data_length).as_bytes()).unwrap()
Expand All @@ -338,18 +353,18 @@ impl<R> Response<R> where R: Read {
use chunked_transfer::Encoder;

let mut writer = Encoder::new(writer);
try!(io::copy(&mut self.reader, &mut writer));
try!(io::copy(&mut reader, &mut writer));
},

Some(TransferEncoding::Identity) => {
use util::EqualReader;

assert!(self.data_length.is_some());
let data_length = self.data_length.unwrap();
assert!(data_length.is_some());
let data_length = data_length.unwrap();

if data_length >= 1 {
let (mut equ_reader, _) =
EqualReader::new(self.reader.by_ref(), data_length);
EqualReader::new(reader.by_ref(), data_length);
try!(io::copy(&mut equ_reader, &mut writer));
}
},
Expand Down