From 88eaaa0016d6f321898b37a48aa950e912c71f5b Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 7 Mar 2017 12:16:10 -0800 Subject: [PATCH] fix(http): dont return Error frame with idle eof --- src/http/conn.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++---- src/http/io.rs | 1 - 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/http/conn.rs b/src/http/conn.rs index fbb45807..41ac3e62 100644 --- a/src/http/conn.rs +++ b/src/http/conn.rs @@ -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 }))) @@ -583,9 +583,7 @@ impl State { 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(); } @@ -610,6 +608,12 @@ impl State { 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, @@ -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); diff --git a/src/http/io.rs b/src/http/io.rs index 6655c426..6548d774 100644 --- a/src/http/io.rs +++ b/src/http/io.rs @@ -73,7 +73,6 @@ impl Buffered { match try!(parse::(&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 => {