Skip to content

Commit

Permalink
fix(http): dont return Error frame with idle eof
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmonstar committed Mar 7, 2017
1 parent c51a999 commit 88eaaa0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
49 changes: 45 additions & 4 deletions src/http/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ where I: Io,
Ok(Some(head)) => (head.version, head),
Ok(None) => return Ok(Async::NotReady),
Err(e) => {
let must_respond_with_error = !self.state.is_idle();
self.state.close_read();
self.io.consume_leading_lines();
let was_mid_parse = !self.io.read_buf().is_empty();
let must_respond_with_error = !self.state.is_idle();
return if was_mid_parse {
debug!("parse error ({}) with bytes: {:?}", e, self.io.read_buf());
Ok(Async::Ready(Some(Frame::Error { error: e })))
Expand Down Expand Up @@ -583,9 +583,7 @@ impl<B, K: KeepAlive> State<B, K> {
match (&self.reading, &self.writing) {
(&Reading::KeepAlive, &Writing::KeepAlive) => {
if let KA::Busy = self.keep_alive.status() {
self.reading = Reading::Init;
self.writing = Writing::Init;
self.keep_alive.idle();
self.idle();
} else {
self.close();
}
Expand All @@ -610,6 +608,12 @@ impl<B, K: KeepAlive> State<B, K> {
self.keep_alive.busy();
}

fn idle(&mut self) {
self.reading = Reading::Init;
self.writing = Writing::Init;
self.keep_alive.idle();
}

fn is_read_closed(&self) -> bool {
match self.reading {
Reading::Closed => true,
Expand Down Expand Up @@ -717,6 +721,43 @@ mod tests {
}).wait();
}

#[test]
fn test_conn_init_read_eof_idle() {
let io = AsyncIo::new_buf(vec![], 1);
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
conn.state.idle();

match conn.poll().unwrap() {
Async::Ready(None) => {},
other => panic!("frame is not None: {:?}", other)
}
}

#[test]
fn test_conn_init_read_eof_idle_partial_parse() {
let io = AsyncIo::new_buf(b"GET / HTTP/1.1".to_vec(), 100);
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
conn.state.idle();

assert!(conn.poll().unwrap().is_not_ready());
match conn.poll().unwrap() {
Async::Ready(Some(Frame::Error { .. })) => {},
other => panic!("frame is not Error: {:?}", other)
}
}

#[test]
fn test_conn_init_read_eof_busy() {
let io = AsyncIo::new_buf(vec![], 1);
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
conn.state.busy();

match conn.poll().unwrap() {
Async::Ready(Some(Frame::Error { .. })) => {},
other => panic!("frame is not Error: {:?}", other)
}
}

#[test]
fn test_conn_closed_read() {
let io = AsyncIo::new_buf(vec![], 0);
Expand Down
1 change: 0 additions & 1 deletion src/http/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ impl<T: Io> Buffered<T> {
match try!(parse::<S, _>(&mut self.read_buf)) {
Some(head) => {
//trace!("parsed {} bytes out of {}", len, self.read_buf.len());
//self.read_buf.slice(len);
Ok(Some(head.0))
},
None => {
Expand Down

0 comments on commit 88eaaa0

Please sign in to comment.