about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs71
1 files changed, 38 insertions, 33 deletions
diff --git a/src/main.rs b/src/main.rs
index a3da041..6423ad7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,6 @@
 use core::fmt;
 use std::{
-	borrow::{Borrow, Cow},
-	clone,
+	borrow::Cow,
 	collections::HashMap,
 	io::{self, BufRead, BufReader, BufWriter, Write},
 	net::{IpAddr, SocketAddr},
@@ -34,6 +33,8 @@ fn main() {
 	future::block_on(arxc.run(async move { async_main(moving_arxc, moving_arcdb).await }));
 }
 
+/// This function is what's run during the lifetime of the program by our
+/// [LocalExecutor]
 async fn async_main(ex: Arc<LocalExecutor<'_>>, db: Arc<RwLock<Database>>) {
 	let addr = SocketAddr::from(([0, 0, 0, 0], 12345));
 	let listen = TcpListener::bind(addr).await.unwrap();
@@ -47,6 +48,7 @@ async fn async_main(ex: Arc<LocalExecutor<'_>>, db: Arc<RwLock<Database>>) {
 	}
 }
 
+/// Handles a single connection from a client.
 async fn handle_request(mut stream: TcpStream, caddr: SocketAddr, db: Arc<RwLock<Database>>) {
 	let mut buffer = vec![0; 1024];
 	let mut data_end = 0;
@@ -102,6 +104,8 @@ async fn handle_request(mut stream: TcpStream, caddr: SocketAddr, db: Arc<RwLock
 	}
 }
 
+/// Form a simple HTTP/1.1 error response with no body and the specified status
+/// code and message.
 fn error(code: u16, msg: &'static str) -> Vec<u8> {
 	format!(
 		"HTTP/1.1 {code} {msg}\n\
@@ -113,6 +117,12 @@ fn error(code: u16, msg: &'static str) -> Vec<u8> {
 	.to_vec()
 }
 
+/// Get the request header with the case-insensetive `key`.
+///
+/// Returns:
+/// - Ok(None) the header was not present
+/// - Ok(Some(value)) the header value, interpreted as a utf8 string
+/// - Err(Utf8Error) if the header value could not be parsed as a utf8 string
 fn get_header<'h>(
 	headers: &'h [httparse::Header<'h>],
 	key: &'static str,
@@ -124,15 +134,13 @@ fn get_header<'h>(
 		.transpose()
 }
 
+/// Small struct containing details from the request we might want in the
+/// response
 struct Response {
 	/// IP the request came from. This is very important in our application.
 	client_addr: IpAddr,
 	/// HTTP minor version. Read this from the request so we can respond properly.
 	http_minor: u8,
-	/// Response status code
-	status: u16,
-	/// Response status message
-	message: &'static str,
 	/// Indicates if this is a GET or a HEAD request
 	is_head: bool,
 }
@@ -154,9 +162,6 @@ async fn form_response<'req>(
 	};
 
 	let minor = request.version.unwrap();
-	let status = 200;
-	let message = "Gotcha";
-
 	let requested_type = match get_header(request.headers, "content-type") {
 		Err(e) => return e,
 		Ok(None) | Ok(Some("text/plain")) => ContentType::Plain,
@@ -167,8 +172,6 @@ async fn form_response<'req>(
 	let response = Response {
 		client_addr: caddr.ip(),
 		http_minor: minor,
-		status,
-		message,
 		is_head,
 	};
 
@@ -221,12 +224,12 @@ async fn form_response<'req>(
 	}
 }
 
+/// Form a `200 Gotcha` response containing the client's address and with the
+/// correct content-type.
 fn make_ip_response(requested_type: ContentType, response: Response) -> Vec<u8> {
 	let Response {
 		client_addr,
 		http_minor,
-		status,
-		message,
 		is_head,
 	} = response;
 
@@ -238,7 +241,7 @@ fn make_ip_response(requested_type: ContentType, response: Response) -> Vec<u8>
 	let length = body.len();
 
 	// And now we form the request :D
-	let mut response = format!("HTTP/1.{http_minor} {status} {message}\n");
+	let mut response = format!("HTTP/1.{http_minor} 200 Gotcha\n");
 
 	macro_rules! header {
 		($content:expr) => {
@@ -259,6 +262,7 @@ fn make_ip_response(requested_type: ContentType, response: Response) -> Vec<u8>
 	response.into_bytes()
 }
 
+/// Possible responses when a client includes an `Authorization` header
 enum AuthResponse {
 	/// Returned when the key has never been seen before.
 	NewAuth,
@@ -305,20 +309,6 @@ async fn handle_auth(
 	}
 }
 
-enum ContentType {
-	Plain,
-	Json,
-}
-
-impl fmt::Display for ContentType {
-	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-		match self {
-			ContentType::Plain => write!(f, "text/plain"),
-			ContentType::Json => write!(f, "application/json"),
-		}
-	}
-}
-
 #[derive(Clone, Debug, Hash, PartialEq, Eq)]
 pub struct AuthKey<'a>(Cow<'a, str>);
 const BASE64: &'static str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+/=";
@@ -434,11 +424,19 @@ impl Database {
 	}
 }
 
-#[derive(Clone, Copy, Debug)]
-enum DatabaseMalformation {
-	AuthKey,
-	IpAddr,
-	Line,
+/// Content types we know about
+enum ContentType {
+	Plain,
+	Json,
+}
+
+impl fmt::Display for ContentType {
+	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+		match self {
+			ContentType::Plain => write!(f, "text/plain"),
+			ContentType::Json => write!(f, "application/json"),
+		}
+	}
 }
 
 #[derive(Debug)]
@@ -475,3 +473,10 @@ impl RuntimeError {
 		}
 	}
 }
+
+#[derive(Clone, Copy, Debug)]
+enum DatabaseMalformation {
+	AuthKey,
+	IpAddr,
+	Line,
+}