feat: URL handling

This commit is contained in:
Compositr 2024-10-30 13:49:27 +11:00
parent 09fc6c1307
commit 952908292b
Signed by: compositr
GPG key ID: 91E3DE20129A0B4A
2 changed files with 48 additions and 14 deletions

View file

@ -1,12 +1,38 @@
use std::collections::HashMap;
struct Path<'a> {
pub query: HashMap<&'a str, &'a str>
pub struct URL<'a> {
pub raw: &'a str,
pub path: &'a str,
pub query: HashMap<&'a str, &'a str>,
}
impl Path {
pub fn new<'a>(path: &'a str) -> Self {
let query = path.split("?").collect();
Path { query }
}
impl<'a> URL<'a> {
pub fn new(url: &'a str) -> Option<Self> {
let raw = url;
// Query string parsing
let mut query = HashMap::new();
let mut split = url.split('?');
let path = split.nth(0)?;
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,
None => continue,
};
let value = key_value.next().unwrap_or("");
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]
} else {
path
};
Some(URL { raw, path, query })
}
}

View file

@ -5,6 +5,7 @@ use std::{
};
use ctrlc;
use http::requests::URL;
mod http;
@ -49,19 +50,26 @@ fn handle_connection(mut stream: TcpStream) {
return;
}
let (method, path) = (request_line_parts[0], request_line_parts[1]);
let (method, url_str) = (request_line_parts[0], request_line_parts[1]);
if method != "GET" {
http::responses::send_405(stream).unwrap_or_else(|_| error("Failed to send 405 response"));
return;
}
let path = if path.ends_with("/") {
&path[..path.len() - 1]
} else {
path
let url = match http::requests::URL::new(url_str) {
Some(path) => path,
None => {
http::responses::send_400(stream)
.unwrap_or_else(|_| error("Failed to send 400 response"));
return;
}
};
match path {
handle_request(url, stream);
}
fn handle_request(url: URL, stream: TcpStream) {
match url.path {
"/" => http::responses::ok(stream, "OK - luciders is working!")
.unwrap_or_else(|_| error("Failed to send 200 response")),
_ => http::responses::send_404(stream)