summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spider/src/http_server.rs12
-rw-r--r--spider/src/request.rs48
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<T> HttpServer<T> 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<String, String>,
- // body: &'a [u8]
+ body: Vec<u8>,
}
impl Request {
pub fn new( method: HttpMethod
, path: String
, http_version: String
- , headers: HashMap<String, String>) -> Request {
+ , headers: HashMap<String, String>
+ , body: Vec<u8> ) -> 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<Request> {
- let lines = data.split("\r\n").collect::<Vec<&str>>();
+ pub fn from(data: &[u8]) -> Option<Request> {
+ let mut lines: Vec<String> = 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<String, String> = HashMap::new();
for line in &lines[1..] {
- let line = line.split(": ").collect::<Vec<&str>>();
+ let line = line
+ .trim_end_matches("\r\n")
+ .split(": ")
+ .collect::<Vec<&str>>();
headers.insert(String::from(line[0]), line[1..].join(" "));
}
- let first_line = lines[0].split(" ").collect::<Vec<&str>>();
+ let first_line = lines[0]
+ .trim_end_matches("\r\n")
+ .split(" ")
+ .collect::<Vec<&str>>();
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);
}
}
+