From fa11b1243e704c6fd9490a6382155d4e8088df9b Mon Sep 17 00:00:00 2001 From: Andrew Date: Sun, 14 Feb 2021 17:16:35 +0400 Subject: Changed request parsing so that it now parses body as bytes --- spider/src/http_server.rs | 12 ++---------- spider/src/request.rs | 48 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/spider/src/http_server.rs b/spider/src/http_server.rs index 12c410f..675a25a 100644 --- a/spider/src/http_server.rs +++ b/spider/src/http_server.rs @@ -55,18 +55,10 @@ impl HttpServer where T: HttpHandler { fn handle_client(&self, mut stream: &TcpStream) { let mut buf: [u8; 1024] = [0; 1024]; - stream.peek(&mut buf).expect("Couldn't read from socket"); - - // TODO(andrew): parse only headers as string and leave decoding of - // body to handler. // TODO(andrew): read all body, not first 1024 bytes. - // TODO(andrew): remove panic. - let s = match str::from_utf8(&buf) { - Ok(v) => v, - Err(_) => panic!("Couldn't convert u8 to character") - }; + stream.peek(&mut buf).expect("Couldn't read from socket"); - let request = Request::from(&s); + let request = Request::from(&buf); // TODO(andrew): remove panic. let request = match request { Some(r) => r, diff --git a/spider/src/request.rs b/spider/src/request.rs index c7d5ab0..fa32bbd 100644 --- a/spider/src/request.rs +++ b/spider/src/request.rs @@ -8,34 +8,62 @@ pub struct Request { path: String, http_version: String, headers: HashMap, - // body: &'a [u8] + body: Vec, } impl Request { pub fn new( method: HttpMethod , path: String , http_version: String - , headers: HashMap) -> Request { + , headers: HashMap + , body: Vec ) -> Request { return Request { method, path, http_version, - headers + headers, + body, }; } - // TODO(andrew): accept &[u8] instead of &str and add parsing of body. // TODO(andrew): add some error handling. - pub fn from(data: &str) -> Option { - let lines = data.split("\r\n").collect::>(); + pub fn from(data: &[u8]) -> Option { + let mut lines: Vec = Vec::new(); + let mut line = String::new(); + let mut idx = 0; + let mut char_count = 0; + + // Parsing headers until first empty line (char_count == 0). + for c in data { + let c = *c as char; + line.push(c); + idx += 1; + + if c == '\n' { + lines.push(line); + if char_count == 0 { break; } + else { line = String::new(); } + } + if c != '\r' && c != '\n' { + char_count += 1; + } + } + + let body = data[idx..].to_vec(); let mut headers: HashMap = HashMap::new(); for line in &lines[1..] { - let line = line.split(": ").collect::>(); + let line = line + .trim_end_matches("\r\n") + .split(": ") + .collect::>(); headers.insert(String::from(line[0]), line[1..].join(" ")); } - let first_line = lines[0].split(" ").collect::>(); + let first_line = lines[0] + .trim_end_matches("\r\n") + .split(" ") + .collect::>(); let method = String::from(first_line[0]); match HttpMethod::parse(method) { @@ -44,7 +72,8 @@ impl Request { method, String::from(first_line[1]), String::from(first_line[2]), - headers )), + headers, + body )), None => return None }; } @@ -55,3 +84,4 @@ impl fmt::Display for Request { return write!(f, "Request({}, {})", self.method, self.path); } } + -- cgit v1.2.3