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.
This commit is contained in:
parent
ccd4da433b
commit
1e83969ebd
|
@ -15,13 +15,13 @@ impl<Req: Request, Res: Response> Connection<Req, Res> {
|
|||
stream,
|
||||
address,
|
||||
token,
|
||||
state: RequestState::Incoming(Vec::new()),
|
||||
state: RequestState::Incoming(Req::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum RequestState<Req: Request, Res: Response> {
|
||||
Incoming(Vec<u8>),
|
||||
Incoming(Req),
|
||||
Processing(Req),
|
||||
Outgoing(Res),
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
pub trait Request {
|
||||
type Response;
|
||||
fn from_bytes(request_bytes: &[u8]) -> RequestParseResult<Self, Self::Response>
|
||||
|
||||
fn new() -> Self;
|
||||
fn push_bytes(&mut self, bytes: &[u8]);
|
||||
fn parse(&mut self) -> RequestParseResult<Self, Self::Response>
|
||||
where
|
||||
Self: Sized,
|
||||
Self::Response: Response;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue