diff --git a/Cargo.lock b/Cargo.lock index 48aa698..356208c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "webbisitey" version = "0.1.0" +dependencies = [ + "urlencoding", +] diff --git a/Cargo.toml b/Cargo.toml index 57dda76..deb0588 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,3 +2,6 @@ name = "webbisitey" version = "0.1.0" edition = "2024" + +[dependencies] +urlencoding = "2.1.3" diff --git a/src/main.rs b/src/main.rs index 2898c81..0f83418 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ use std::{ env::current_dir, ffi::OsStr, - io::{BufRead, BufReader, Write}, + fs::DirEntry, + io::{BufRead, BufReader, Read, Write}, net::{TcpListener, TcpStream}, path::PathBuf, }; @@ -59,7 +60,7 @@ impl Request { path.push("public"); path.push( - PathBuf::from(self.path.as_ref().unwrap()) + PathBuf::from(urlencoding::decode(self.path.as_ref().unwrap()).unwrap().to_string()) .strip_prefix("/") .expect("Failed to strip prefix"), ); @@ -106,6 +107,101 @@ fn handle_connection(mut stream: TcpStream) { let req = Request::from(http_request.get(0).expect("Empty request")); + if req.path == Some("/posts/index".to_string()) { + stream + .write_all( + { + match std::fs::read_dir("./public/posts/") { + Ok(files) => { + let mut entries = files + .filter_map(|x| if x.is_ok() { Some(x.unwrap()) } else { None }) + .filter(|x| { + let file_name = x.file_name(); + let y = file_name.to_str(); + if y.is_some() { + if y.unwrap().ends_with(".md") { + true + } else { + false + } + } else { + false + } + }) + .collect::>(); + entries.sort_by(|a, b| { + let mut a = if let Ok(a) = std::fs::File::open(a.path()) { + a + } else { + return std::cmp::Ordering::Equal; + }; + let mut b = if let Ok(b) = std::fs::File::open(b.path()) { + b + } else { + return std::cmp::Ordering::Equal; + }; + + let mut buf: &mut [u8] = &mut [0; 16]; + let _ = a.read(&mut buf); + + let a = String::from_utf8_lossy(buf); + + let buf: &mut [u8] = &mut [0; 16]; + let _ = b.read(&mut *buf); + let b = String::from_utf8_lossy(buf); + + let a = if let Ok(a) = a + .chars() + .take_while(|x| x != &'\n') + .collect::() + .parse::() + { + a + } else { + return std::cmp::Ordering::Equal; + }; + + let b = if let Ok(b) = b + .chars() + .take_while(|x| x != &'\n') + .collect::() + .parse::() + { + b + } else { + return std::cmp::Ordering::Equal; + }; + + return a.cmp(&b); + }); + entries + .into_iter() + .filter_map(|x| { + if let Some(n) = x.file_name().to_str() { + if n.ends_with(".md") { + Some(n.to_owned().replace(".md","")) + } else { + None + } + } else { + None + } + }) + .reduce(|a, b| format!("{}\n{}", b, a)) + .unwrap() + } + // .reduce(|i, x| format!("{}\n{}", i, x)) + // .unwrap() + // .to_string(), + Err(e) => format!("HTTP/1.1 500\r\n\r\n{}", e), + } + } + .as_bytes(), + ) + .unwrap(); + return; + } + println!("Requested file: {:#?}", req.file()); let mut response_content = vec![]; @@ -116,11 +212,12 @@ fn handle_connection(mut stream: TcpStream) { let len = &content.len(); response_content = content; format!( - "HTTP/1.1 200 OK{0}Content-Type: {2}{0}Content-Length: {1}{0}{0}", - CLRF, - len, - get_mime_type(path.extension()) - )}, + "HTTP/1.1 200 OK{0}Content-Type: {2}{0}Content-Length: {1}{0}{0}", + CLRF, + len, + get_mime_type(path.extension()) + ) + } Err(e) => format!("HTTP/1.1 404{0}{0}{e}", CLRF), }, None => format!("HTTP/1.1 404{0}{0}", CLRF),