refactor: mod responses; send stream back on error

This commit is contained in:
Compositr 2024-11-01 10:03:17 +11:00
parent 3861096e1d
commit db268687f5
Signed by: compositr
GPG key ID: 91E3DE20129A0B4A
2 changed files with 38 additions and 20 deletions

View file

@ -4,6 +4,8 @@ use std::{
net::TcpStream, net::TcpStream,
}; };
use super::responses;
pub struct URL { pub struct URL {
raw: String, raw: String,
pub path: String, pub path: String,
@ -49,7 +51,9 @@ pub struct Request {
pub enum RequestStatus { pub enum RequestStatus {
Ok(Request), Ok(Request),
MalformedHTTP, // Send stream back to the caller to decide what to do with it
// (usually close it)
MalformedHTTP(TcpStream),
} }
impl Request { impl Request {
@ -59,12 +63,12 @@ impl Request {
let request_line = match lines.next() { let request_line = match lines.next() {
Some(Ok(line)) => line, Some(Ok(line)) => line,
_ => return RequestStatus::MalformedHTTP, _ => return RequestStatus::MalformedHTTP(stream),
}; };
let request_line_parts = request_line.split(" ").collect::<Vec<_>>(); let request_line_parts = request_line.split(" ").collect::<Vec<_>>();
if request_line_parts.len() != 3 { if request_line_parts.len() != 3 {
return RequestStatus::MalformedHTTP; return RequestStatus::MalformedHTTP(stream);
} }
let (method, url_str) = ( let (method, url_str) = (
@ -73,9 +77,17 @@ impl Request {
); );
let url = match URL::new(url_str) { let url = match URL::new(url_str) {
Some(path) => path, Some(path) => path,
None => return RequestStatus::MalformedHTTP, None => return RequestStatus::MalformedHTTP(stream),
}; };
RequestStatus::Ok(Request { stream, method, url }) RequestStatus::Ok(Request { stream, method, url })
} }
pub fn send_404(&self) -> responses::UnitOrBoxedError {
responses::send_response(&self.stream, 404, "Not Found")
}
pub fn send_ok(&self, body: &str) -> responses::UnitOrBoxedError {
responses::send_response(&self.stream, 200, body)
}
} }

View file

@ -2,9 +2,27 @@ use std::error::Error;
use std::io::prelude::*; use std::io::prelude::*;
use std::net::TcpStream; use std::net::TcpStream;
type UnitOrBoxedError = Result<(), Box<dyn Error>>; pub struct Response<'a> {
stream: &'a mut TcpStream,
pub status: u16,
}
fn send_response(mut stream: TcpStream, status: u16, body: &str) -> UnitOrBoxedError { impl<'a> Response<'a> {
pub fn new(stream: &'a mut TcpStream, status: u16) -> Self {
Response {
stream,
status,
}
}
pub fn send(&mut self) -> UnitOrBoxedError {
send_response(self.stream, self.status, "")
}
}
pub type UnitOrBoxedError = Result<(), Box<dyn Error>>;
pub fn send_response(mut stream: &TcpStream, status: u16, body: &str) -> UnitOrBoxedError {
let status_line = match status { let status_line = match status {
200 => "HTTP/1.1 200 OK", 200 => "HTTP/1.1 200 OK",
400 => "HTTP/1.1 400 BAD REQUEST", 400 => "HTTP/1.1 400 BAD REQUEST",
@ -14,7 +32,7 @@ fn send_response(mut stream: TcpStream, status: u16, body: &str) -> UnitOrBoxedE
}; };
let response = format!( let response = format!(
"{}\r\nContent-Length: {}\r\n\r\n{}", "{}\r\nContent-Length: {}\r\nServer: luciders/0.1.0\r\n\r\n{}",
status_line, status_line,
body.len(), body.len(),
body body
@ -37,18 +55,6 @@ fn send_response(mut stream: TcpStream, status: u16, body: &str) -> UnitOrBoxedE
Ok(()) Ok(())
} }
pub fn ok(stream: TcpStream, body: &str) -> UnitOrBoxedError { pub fn ok(stream: &TcpStream, body: &str) -> UnitOrBoxedError {
send_response(stream, 200, body) send_response(stream, 200, body)
} }
pub fn send_400(stream: TcpStream) -> UnitOrBoxedError {
send_response(stream, 400, "Bad Request")
}
pub fn send_404(stream: TcpStream) -> UnitOrBoxedError {
send_response(stream, 404, "Not Found")
}
pub fn send_405(stream: TcpStream) -> UnitOrBoxedError {
send_response(stream, 405, "Method Not Allowed")
}