add a request handler

This commit is contained in:
2022-09-08 10:45:58 +01:00
parent f7a7cddde5
commit 81d9b0f38d
3 changed files with 121 additions and 3 deletions
+3
View File
@@ -0,0 +1,3 @@
pub mod request;
pub use request::handle_request;
+108
View File
@@ -0,0 +1,108 @@
//! request handles properly the incoming request
//! it will parse the request according to the HTTP message specifications
//! see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages
#[derive(Debug)]
pub enum HTTPVersion {
HTTP1,
HTTP2,
}
impl Into<String> for HTTPVersion {
fn into(self) -> String {
match self {
HTTP1 => "HTTP/1.1".to_string(),
HTTP2 => "HTTP/2.2".to_string(),
_ => "UNKNOWN".to_string(),
}
}
}
/// Request defined the HTTP request
// TODO: method, target, version must be set in new struct : `HTTPStartLine`
#[derive(Debug)]
pub struct HTTPRequest {
pub method: String,
pub target: String,
pub version: HTTPVersion,
}
impl HTTPRequest {
// associated function to build a new HTTPRequest
fn new(method: String, target: String, version: HTTPVersion) -> Self {
HTTPRequest {
method,
target,
version,
}
}
fn parse(request: &str) -> Result<Self, &str> {
// declare a new `request` var to borrow to &str `request`
let request = request.to_string();
let request_parts: Vec<&str> = request.split(" ").collect();
if request_parts.len() < 3 {
return Err("unable to parse the request correctly");
}
Ok(HTTPRequest::new(
request_parts[0].to_string(),
request_parts[1].to_string(),
HTTPVersion::HTTP1,
))
}
fn is_valid(self) -> bool {
return self.method != "" && self.target != "";
}
// TODO: to be tested
pub fn start_line(self) -> String {
let version: String = self.version.into();
return format!("{} {} {}", self.method, self.target, version);
}
}
impl Default for HTTPRequest {
fn default() -> Self {
HTTPRequest {
method: "".to_string(),
target: "".to_string(),
version: HTTPVersion::HTTP1,
}
}
}
impl From<&str> for HTTPRequest {
fn from(request: &str) -> Self {
match Self::parse(request) {
Ok(v) => v,
Err(v) => {
eprintln!("{}", format!("[ERR]: {v}"));
return HTTPRequest::default();
}
}
}
}
pub fn handle_request(request: &str) -> HTTPRequest {
return HTTPRequest::from(request);
}
#[test]
fn test_handle_request() {
let test_cases: [(&str, bool); 5] = [
("GET / HTTP/1.1", true),
("POST HTTP/1.1", false),
("", false),
("fjlqskjd /oks?id=65 HTTP/2", true),
(" ", false),
];
for (request, is_valid) in test_cases {
let http_request = HTTPRequest::from(request);
println!("{:?}", http_request);
assert_eq!(http_request.is_valid(), is_valid);
}
}