From 9b69d6460e91244bfd77d8ea77c13d21d9050e4c Mon Sep 17 00:00:00 2001 From: Andrew Guschin Date: Thu, 18 Feb 2021 00:25:11 +0400 Subject: Added parsing of query params in GET requests handler --- spider/Cargo.toml | 2 -- spider/src/http_method.rs | 1 + spider/src/request.rs | 63 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 46 insertions(+), 20 deletions(-) (limited to 'spider') diff --git a/spider/Cargo.toml b/spider/Cargo.toml index 84e5702..b35cb43 100644 --- a/spider/Cargo.toml +++ b/spider/Cargo.toml @@ -4,6 +4,4 @@ version = "0.1.0" authors = ["Andrew "] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] diff --git a/spider/src/http_method.rs b/spider/src/http_method.rs index a0b2e17..814c93b 100644 --- a/spider/src/http_method.rs +++ b/spider/src/http_method.rs @@ -1,5 +1,6 @@ use std::fmt; +#[derive(PartialEq)] pub enum HttpMethod { GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH } diff --git a/spider/src/request.rs b/spider/src/request.rs index db1f2ad..3bd6a8f 100644 --- a/spider/src/request.rs +++ b/spider/src/request.rs @@ -5,21 +5,21 @@ use crate::http_method::HttpMethod; pub struct Request { pub method: HttpMethod, - resource: String, - http_version: String, - headers: HashMap, - body: Vec, + pub path: String, + pub http_version: String, + pub headers: HashMap, + pub body: Vec, } impl Request { pub fn new( method: HttpMethod - , resource: String + , path: String , http_version: String , headers: HashMap , body: Vec ) -> Request { return Request { method, - resource, + path, http_version, headers, body, @@ -49,15 +49,17 @@ impl Request { } } - let body = data[idx..].to_vec(); + let mut body = data[idx..].to_vec(); let mut headers: HashMap = HashMap::new(); - for line in &lines[1..] { - let line = line - .trim_end_matches("\r\n") - .split(": ") - .collect::>(); - headers.insert(String::from(line[0]), line[1..].join(" ")); + if lines.len() > 0 { + for line in &lines[1..] { + let line = line + .trim_end_matches("\r\n") + .split(": ") + .collect::>(); + headers.insert(String::from(line[0]), line[1..].join(" ")); + } } let request_line = lines[0] @@ -65,23 +67,48 @@ impl Request { .split(" ") .collect::>(); + let (path, params) = split_path(String::from(request_line[1])); + let method = String::from(request_line[0]); match HttpMethod::parse(method) { - Some(method) => + Some(method) => { + if method == HttpMethod::GET { + if let Some(p) = params { + body = p.as_bytes().to_vec(); + } + } return Some(Request::new( method, - // TODO(andrew): add parsing of resource line. - String::from(request_line[1]), + path, String::from(request_line[2]), headers, - body )), + body )); + } None => return None }; } } +fn split_path(resource: String) -> (String, Option) { + let mut idx = None; + for (i, c) in resource.chars().enumerate() { + if c == '?' { + idx = Some(i); + break; + } + } + match idx { + Some(n) => { + let path = &resource[..n]; + let params = &resource[n + 1..]; + return (path.to_string(), Some(params.to_string())); + }, + None => return (resource, None) + }; +} + impl fmt::Display for Request { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - return write!(f, "Request({}, {})", self.method, self.resource); + return write!(f, "Request({}, {})", self.method, self.path); } } -- cgit v1.2.3