From 1e83969ebd63e84e2fe715bb750ca732ca3c757a Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Sat, 7 Aug 2021 15:05:48 +1200 Subject: [PATCH] Give control of the partial request bytes to Request Before, the partially constructed byte sequence for the request was held outside of the Request object, and each time the program tried to create a Request out of the byte sequence the entire sequence would need to be re-parsed. Now, a Request is constructed up-front, and bytes are periodically pushed to it. This enables the library user to parse more efficiently, by keeping partial parse results inside the Request object and only parsing bytes when they're new to the Request. --- src/connection.rs | 4 ++-- src/request_response.rs | 5 ++++- src/tcp_server.rs | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/connection.rs b/src/connection.rs index 83145a9..5a20abf 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -15,13 +15,13 @@ impl Connection { stream, address, token, - state: RequestState::Incoming(Vec::new()), + state: RequestState::Incoming(Req::new()), } } } pub enum RequestState { - Incoming(Vec), + Incoming(Req), Processing(Req), Outgoing(Res), } diff --git a/src/request_response.rs b/src/request_response.rs index 6e4c3eb..5996604 100644 --- a/src/request_response.rs +++ b/src/request_response.rs @@ -1,6 +1,9 @@ pub trait Request { type Response; - fn from_bytes(request_bytes: &[u8]) -> RequestParseResult + + fn new() -> Self; + fn push_bytes(&mut self, bytes: &[u8]); + fn parse(&mut self) -> RequestParseResult where Self: Sized, Self::Response: Response; diff --git a/src/tcp_server.rs b/src/tcp_server.rs index b49f654..ec4f3bf 100644 --- a/src/tcp_server.rs +++ b/src/tcp_server.rs @@ -136,7 +136,7 @@ impl< fn process_read_event(&mut self, event: &Event) { let token = event.token(); let connection = self.connections[token.0].as_mut().unwrap(); - if let RequestState::Incoming(ref mut request_data) = connection.state { + if let RequestState::Incoming(ref mut req) = connection.state { loop { let mut buffer = [0 as u8; 1024]; match connection.stream.read(&mut buffer) { @@ -144,13 +144,13 @@ impl< self.remove_connection(event.token()).unwrap(); return; } - Ok(len) => request_data.extend_from_slice(&buffer[..len]), + Ok(len) => req.push_bytes(&buffer[..len]), Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break, Err(e) => panic!("Unexpected error: {}", e), }; } - match Req::from_bytes(&request_data) { + match req.parse() { RequestParseResult::Complete(request) => { let mut connection = std::mem::replace(&mut self.connections[token.0], None).unwrap();