feat: URL handling
This commit is contained in:
parent
09fc6c1307
commit
952908292b
2 changed files with 48 additions and 14 deletions
|
@ -1,12 +1,38 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
struct Path<'a> {
|
pub struct URL<'a> {
|
||||||
pub query: HashMap<&'a str, &'a str>
|
pub raw: &'a str,
|
||||||
|
pub path: &'a str,
|
||||||
|
pub query: HashMap<&'a str, &'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Path {
|
impl<'a> URL<'a> {
|
||||||
pub fn new<'a>(path: &'a str) -> Self {
|
pub fn new(url: &'a str) -> Option<Self> {
|
||||||
let query = path.split("?").collect();
|
let raw = url;
|
||||||
Path { query }
|
|
||||||
}
|
// 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 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -5,6 +5,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use ctrlc;
|
use ctrlc;
|
||||||
|
use http::requests::URL;
|
||||||
|
|
||||||
mod http;
|
mod http;
|
||||||
|
|
||||||
|
@ -49,19 +50,26 @@ fn handle_connection(mut stream: TcpStream) {
|
||||||
return;
|
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" {
|
if method != "GET" {
|
||||||
http::responses::send_405(stream).unwrap_or_else(|_| error("Failed to send 405 response"));
|
http::responses::send_405(stream).unwrap_or_else(|_| error("Failed to send 405 response"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = if path.ends_with("/") {
|
let url = match http::requests::URL::new(url_str) {
|
||||||
&path[..path.len() - 1]
|
Some(path) => path,
|
||||||
} else {
|
None => {
|
||||||
path
|
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!")
|
"/" => http::responses::ok(stream, "OK - luciders is working!")
|
||||||
.unwrap_or_else(|_| error("Failed to send 200 response")),
|
.unwrap_or_else(|_| error("Failed to send 200 response")),
|
||||||
_ => http::responses::send_404(stream)
|
_ => http::responses::send_404(stream)
|
||||||
|
|
Loading…
Reference in a new issue