From 73f3e3ccec87ae23cf8579ea34a436e0f5d4a261 Mon Sep 17 00:00:00 2001 From: landrigun Date: Thu, 15 Sep 2022 09:40:32 +0100 Subject: [PATCH] bug: #4 fix HTTP request parsing --- src/handlers/request.rs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/handlers/request.rs b/src/handlers/request.rs index 74a7b75..b6bcb65 100644 --- a/src/handlers/request.rs +++ b/src/handlers/request.rs @@ -6,8 +6,12 @@ use json; use lazy_static::lazy_static; use regex::Regex; +use std::collections::VecDeque; -type RequestParts = (String, String, String); +type RequestParts = (String, VecDeque, String); + +const HTTP_REQUEST_SEPARATOR: &'static str = "\r\n"; +const NULL_CHAR: &'static str = "\0"; // TODO: put this const in a conf file ? const HTTP_METHODS: [&'static str; 1] = ["POST"]; @@ -86,7 +90,6 @@ impl HTTPStartLine { return Err("http version validation failed, unknown version"); } - // TODO: parse correctly the different parts (using regex ?) Ok(HTTPStartLine::new( method, target, @@ -157,6 +160,7 @@ impl HTTPBody { impl TryFrom for HTTPBody { type Error = String; fn try_from(body: String) -> Result { + let body = body.replace(NULL_CHAR, ""); match json::parse(&body) { Ok(v) => Ok(HTTPBody::new(v)), Err(e) => Err(format!( @@ -186,21 +190,24 @@ impl HTTPRequest { /// * data (if exists) fn get_request_parts(request: &str) -> Result { // separate the body part from the start_line and the headers - let request_parts: Vec<&str> = request.split("\r\n").collect(); - println!("request_parts : {:?}", request_parts); + let mut request_parts: VecDeque = request + .split(HTTP_REQUEST_SEPARATOR) + .map(|r| r.to_string()) + .collect(); + + println!("request parts : {:?}", request_parts); + if request_parts.len() < 3 { return Err("request has no enough informations to be correctly parsed".to_string()); } - Ok(( - request_parts[0].to_string(), - request_parts[1].to_string(), - request_parts[2].to_string(), - )) + let start_line = request_parts.pop_front().unwrap(); + let body = request_parts.pop_back().unwrap(); + + Ok((start_line, request_parts, body)) } /// parse parses the request by spliting the incoming request with the separator `\r\n` fn parse(request: &str) -> Result { - // declare a new `request` var to borrow to &str `request` let request = request.to_string(); match HTTPRequest::get_request_parts(&request) {