bug: #4 fix HTTP request parsing

This commit is contained in:
landrigun 2022-09-15 09:40:32 +01:00
parent 5fc2a07bce
commit 73f3e3ccec

View File

@ -6,8 +6,12 @@
use json; use json;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use regex::Regex; use regex::Regex;
use std::collections::VecDeque;
type RequestParts = (String, String, String); type RequestParts = (String, VecDeque<String>, String);
const HTTP_REQUEST_SEPARATOR: &'static str = "\r\n";
const NULL_CHAR: &'static str = "\0";
// TODO: put this const in a conf file ? // TODO: put this const in a conf file ?
const HTTP_METHODS: [&'static str; 1] = ["POST"]; const HTTP_METHODS: [&'static str; 1] = ["POST"];
@ -86,7 +90,6 @@ impl HTTPStartLine {
return Err("http version validation failed, unknown version"); return Err("http version validation failed, unknown version");
} }
// TODO: parse correctly the different parts (using regex ?)
Ok(HTTPStartLine::new( Ok(HTTPStartLine::new(
method, method,
target, target,
@ -157,6 +160,7 @@ impl HTTPBody {
impl TryFrom<String> for HTTPBody { impl TryFrom<String> for HTTPBody {
type Error = String; type Error = String;
fn try_from(body: String) -> Result<HTTPBody, Self::Error> { fn try_from(body: String) -> Result<HTTPBody, Self::Error> {
let body = body.replace(NULL_CHAR, "");
match json::parse(&body) { match json::parse(&body) {
Ok(v) => Ok(HTTPBody::new(v)), Ok(v) => Ok(HTTPBody::new(v)),
Err(e) => Err(format!( Err(e) => Err(format!(
@ -186,21 +190,24 @@ impl HTTPRequest {
/// * data (if exists) /// * data (if exists)
fn get_request_parts(request: &str) -> Result<RequestParts, String> { fn get_request_parts(request: &str) -> Result<RequestParts, String> {
// separate the body part from the start_line and the headers // separate the body part from the start_line and the headers
let request_parts: Vec<&str> = request.split("\r\n").collect(); let mut request_parts: VecDeque<String> = request
println!("request_parts : {:?}", request_parts); .split(HTTP_REQUEST_SEPARATOR)
.map(|r| r.to_string())
.collect();
println!("request parts : {:?}", request_parts);
if request_parts.len() < 3 { if request_parts.len() < 3 {
return Err("request has no enough informations to be correctly parsed".to_string()); return Err("request has no enough informations to be correctly parsed".to_string());
} }
Ok(( let start_line = request_parts.pop_front().unwrap();
request_parts[0].to_string(), let body = request_parts.pop_back().unwrap();
request_parts[1].to_string(),
request_parts[2].to_string(), Ok((start_line, request_parts, body))
))
} }
/// parse parses the request by spliting the incoming request with the separator `\r\n` /// parse parses the request by spliting the incoming request with the separator `\r\n`
fn parse(request: &str) -> Result<HTTPRequest, String> { fn parse(request: &str) -> Result<HTTPRequest, String> {
// declare a new `request` var to borrow to &str `request`
let request = request.to_string(); let request = request.to_string();
match HTTPRequest::get_request_parts(&request) { match HTTPRequest::get_request_parts(&request) {