refactor: remove &ownership issues

This commit is contained in:
Compositr 2024-10-31 13:07:10 +11:00
parent b9c51fc657
commit 1b19b2b935
Signed by: compositr
GPG key ID: 91E3DE20129A0B4A

View file

@ -1,38 +1,81 @@
use std::collections::HashMap;
use std::{
collections::HashMap,
io::{prelude::*, BufReader},
net::TcpStream,
};
pub struct URL<'a> {
pub raw: &'a str,
pub path: &'a str,
pub query: HashMap<&'a str, &'a str>,
pub struct URL {
raw: String,
pub path: String,
pub query: HashMap<String, String>,
}
impl<'a> URL<'a> {
pub fn new(url: &'a str) -> Option<Self> {
impl URL {
pub fn new(url: String) -> Option<Self> {
let raw = url;
let mut split = raw.split('?');
// Query string parsing
let mut query = HashMap::new();
let mut split = url.split('?');
let path = split.nth(0)?;
let path = split.next()?.to_string();
let query_string = split.next();
for pair in query_string.unwrap_or("").split('&') {
let mut key_value = pair.split('=');
let key = match key_value.next() {
Some(key) => key,
Some(key) => key.to_string(),
None => continue,
};
let value = key_value.next().unwrap_or("");
let value = key_value.next().unwrap_or("").to_string();
query.insert(key, value);
}
// Drop trailing slash but not for root path
let path = if path.ends_with("/") && path.len() > 1 {
&path[..path.len() - 1]
path[..path.len() - 1].to_string()
} else {
path
};
Some(URL { raw, path, query })
Some(URL { path, query, raw })
}
}
pub struct Request {
stream: TcpStream,
pub method: String,
pub url: URL,
}
pub enum RequestStatus {
Ok(Request),
MalformedHTTP,
}
impl<'a> Request {
pub fn parse_stream(stream: TcpStream) -> RequestStatus {
let reader = BufReader::new(&stream);
let mut lines = reader.lines();
let request_line = match lines.next() {
Some(Ok(line)) => line,
_ => return RequestStatus::MalformedHTTP,
};
let request_line_parts = request_line.split(" ").collect::<Vec<_>>();
if request_line_parts.len() != 3 {
return RequestStatus::MalformedHTTP;
}
let (method, url_str) = (
request_line_parts[0].to_string().clone(),
request_line_parts[1].to_string().clone(),
);
let url = match URL::new(url_str) {
Some(path) => path,
None => return RequestStatus::MalformedHTTP,
};
RequestStatus::Ok(Request { stream, method, url })
}
}