fix(client): don't read extra bytes on idle connections
This commit is contained in:
		| @@ -102,7 +102,16 @@ where I: AsyncRead + AsyncWrite, | ||||
|  | ||||
|     pub fn can_read_head(&self) -> bool { | ||||
|         match self.state.reading { | ||||
|             Reading::Init => true, | ||||
|             Reading::Init => { | ||||
|                 if T::should_read_first() { | ||||
|                     true | ||||
|                 } else { | ||||
|                     match self.state.writing { | ||||
|                         Writing::Init => false, | ||||
|                         _ => true, | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| @@ -840,25 +849,35 @@ mod tests { | ||||
|  | ||||
|     #[test] | ||||
|     fn test_conn_init_read_eof_busy() { | ||||
|         // server ignores | ||||
|         let io = AsyncIo::new_buf(vec![], 1); | ||||
|         let mut conn = Conn::<_, proto::Chunk, ServerTransaction>::new(io, Default::default()); | ||||
|         conn.state.busy(); | ||||
|         let _: Result<(), ()> = future::lazy(|| { | ||||
|             // server ignores | ||||
|             let io = AsyncIo::new_buf(vec![], 1); | ||||
|             let mut conn = Conn::<_, proto::Chunk, ServerTransaction>::new(io, Default::default()); | ||||
|             conn.state.busy(); | ||||
|  | ||||
|         match conn.poll().unwrap() { | ||||
|             Async::Ready(None) => {}, | ||||
|             other => panic!("unexpected frame: {:?}", other) | ||||
|         } | ||||
|             match conn.poll().unwrap() { | ||||
|                 Async::Ready(None) => {}, | ||||
|                 other => panic!("unexpected frame: {:?}", other) | ||||
|             } | ||||
|  | ||||
|         // client, when busy, returns the error | ||||
|         let io = AsyncIo::new_buf(vec![], 1); | ||||
|         let mut conn = Conn::<_, proto::Chunk, ClientTransaction>::new(io, Default::default()); | ||||
|         conn.state.busy(); | ||||
|             // client | ||||
|             let io = AsyncIo::new_buf(vec![], 1); | ||||
|             let mut conn = Conn::<_, proto::Chunk, ClientTransaction>::new(io, Default::default()); | ||||
|             conn.state.busy(); | ||||
|  | ||||
|         match conn.poll() { | ||||
|             Err(ref err) if err.kind() == ::std::io::ErrorKind::UnexpectedEof => {}, | ||||
|             other => panic!("unexpected frame: {:?}", other) | ||||
|         } | ||||
|             match conn.poll() { | ||||
|                 Ok(Async::NotReady) => {}, | ||||
|                 other => panic!("unexpected frame: {:?}", other) | ||||
|             } | ||||
|  | ||||
|             // once mid-request, returns the error | ||||
|             conn.state.writing = super::Writing::KeepAlive; | ||||
|             match conn.poll() { | ||||
|                 Err(ref err) if err.kind() == ::std::io::ErrorKind::UnexpectedEof => {}, | ||||
|                 other => panic!("unexpected frame: {:?}", other) | ||||
|             } | ||||
|             Ok(()) | ||||
|         }).wait(); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|   | ||||
| @@ -136,6 +136,10 @@ impl Http1Transaction for ServerTransaction { | ||||
|     fn should_error_on_parse_eof() -> bool { | ||||
|         false | ||||
|     } | ||||
|  | ||||
|     fn should_read_first() -> bool { | ||||
|         true | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ServerTransaction { | ||||
| @@ -289,6 +293,10 @@ impl Http1Transaction for ClientTransaction { | ||||
|     fn should_error_on_parse_eof() -> bool { | ||||
|         true | ||||
|     } | ||||
|  | ||||
|     fn should_read_first() -> bool { | ||||
|         false | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ClientTransaction { | ||||
|   | ||||
| @@ -149,6 +149,7 @@ pub trait Http1Transaction { | ||||
|     fn encode(head: MessageHead<Self::Outgoing>, has_body: bool, method: &mut Option<Method>, dst: &mut Vec<u8>) -> h1::Encoder; | ||||
|  | ||||
|     fn should_error_on_parse_eof() -> bool; | ||||
|     fn should_read_first() -> bool; | ||||
| } | ||||
|  | ||||
| pub type ParseResult<T> = ::Result<Option<(MessageHead<T>, usize)>>; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user