Merge pull request #936 from jwilm/fix-chunked-decode

fix(http): Chunked decoder reads last \r\n
This commit is contained in:
Sean McArthur
2016-10-17 21:43:37 -07:00
committed by GitHub

View File

@@ -58,6 +58,8 @@ enum ChunkedState {
Body, Body,
BodyCr, BodyCr,
BodyLf, BodyLf,
EndCr,
EndLf,
End, End,
} }
@@ -148,6 +150,8 @@ impl ChunkedState {
Body => try!(ChunkedState::read_body(body, size, buf, read)), Body => try!(ChunkedState::read_body(body, size, buf, read)),
BodyCr => try!(ChunkedState::read_body_cr(body)), BodyCr => try!(ChunkedState::read_body_cr(body)),
BodyLf => try!(ChunkedState::read_body_lf(body)), BodyLf => try!(ChunkedState::read_body_lf(body)),
EndCr => try!(ChunkedState::read_end_cr(body)),
EndLf => try!(ChunkedState::read_end_lf(body)),
End => ChunkedState::End, End => ChunkedState::End,
}) })
} }
@@ -201,10 +205,11 @@ impl ChunkedState {
trace!("Chunk size is {:?}", size); trace!("Chunk size is {:?}", size);
match byte!(rdr) { match byte!(rdr) {
b'\n' if *size > 0 => Ok(ChunkedState::Body), b'\n' if *size > 0 => Ok(ChunkedState::Body),
b'\n' if *size == 0 => Ok(ChunkedState::End), b'\n' if *size == 0 => Ok(ChunkedState::EndCr),
_ => Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk size LF")), _ => Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk size LF")),
} }
} }
fn read_body<R: Read>(rdr: &mut R, fn read_body<R: Read>(rdr: &mut R,
rem: &mut u64, rem: &mut u64,
buf: &mut [u8], buf: &mut [u8],
@@ -250,6 +255,19 @@ impl ChunkedState {
_ => Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk body LF")), _ => Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk body LF")),
} }
} }
fn read_end_cr<R: Read>(rdr: &mut R) -> io::Result<ChunkedState> {
match byte!(rdr) {
b'\r' => Ok(ChunkedState::EndLf),
_ => Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk end CR")),
}
}
fn read_end_lf<R: Read>(rdr: &mut R) -> io::Result<ChunkedState> {
match byte!(rdr) {
b'\n' => Ok(ChunkedState::End),
_ => Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk end LF")),
}
}
} }
#[cfg(test)] #[cfg(test)]
@@ -276,7 +294,7 @@ mod tests {
let desc = format!("read_size failed for {:?}", s); let desc = format!("read_size failed for {:?}", s);
state = result.expect(desc.as_str()); state = result.expect(desc.as_str());
trace!("State {:?}", state); trace!("State {:?}", state);
if state == ChunkedState::Body || state == ChunkedState::End { if state == ChunkedState::Body || state == ChunkedState::EndCr {
break; break;
} }
} }
@@ -375,7 +393,7 @@ mod tests {
#[test] #[test]
fn test_read_chunked_after_eof() { fn test_read_chunked_after_eof() {
let content = b"10\r\n1234567890abcdef\r\n0\r\n"; let content = b"10\r\n1234567890abcdef\r\n0\r\n\r\n";
let mut mock_buf = io::Cursor::new(content); let mut mock_buf = io::Cursor::new(content);
let mut buf = [0u8; 50]; let mut buf = [0u8; 50];
let mut decoder = Decoder::chunked(); let mut decoder = Decoder::chunked();