From 7c81a93403140581f18c6714c6b1712e46aaad90 Mon Sep 17 00:00:00 2001 From: Dendy Faist Date: Fri, 13 Jan 2023 17:03:37 +0100 Subject: [PATCH] Basic file serving and rendering --- .gitignore | 4 ++++ Cargo.toml | 12 ++++++++++ src/main.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..381145d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/debug +/target +/blog/* +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0db9dfa --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "blogit" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +hyper = { version = "0.14", features = ["full"] } +tokio = { version = "1", features = ["full"] } +futures = "0.3" +pulldown-cmark = "0.9.2" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ee713c2 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,63 @@ +use std::convert::Infallible; + +use hyper::service::{make_service_fn, service_fn}; +use hyper::{Body, Method, Request, Response, Server, StatusCode}; +use pulldown_cmark::{html, Options, Parser}; + +async fn hello_world(req: Request) -> Result, Infallible> { + println!("New request to '{}'", req.uri()); + + let path = &req + .uri() + .path()[1..] // Remove the first "/". We don't need it + .replace("..", "") // Don't allow to go up in the hierarchy + ; + + // Get the first part so we can route it + let until = path.find('/').unwrap_or(path.len()); + + let mut response = Response::new(Body::empty()); + + match (req.method(), &path[..until]) { + (&Method::GET, "") => { + *response.body_mut() = Body::from("You shouldn't be reading this."); + } + (&Method::GET, "blog") => { + *response.body_mut() = Body::from(file_to_md(path)); + } + (_, path) => { + *response.body_mut() = Body::from(format!("Path {path} not found.")); + *response.status_mut() = StatusCode::NOT_FOUND; + } + } + + Ok(response) +} + +fn file_to_md(path: &str) -> String { + let file = std::fs::read_to_string(path).unwrap_or("File not found.".to_string()); + + //let mut options = Options::empty(); + //options.insert(Options::ENABLE_STRIKETHROUGH); + let parser = Parser::new_ext(file.as_str(), Options::ENABLE_STRIKETHROUGH); + + // Write to String buffer. + let mut html_output: String = String::with_capacity(file.len() * 3 / 2); + html::push_html(&mut html_output, parser); + + html_output +} + +#[tokio::main] +async fn main() { + let addr = ([127, 0, 0, 1], 3000).into(); + + let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(hello_world)) }); + + let server = Server::bind(&addr).serve(make_svc); + + println!("Server listening on: http://{}", addr); + if let Err(e) = server.await { + eprintln!("server error: {}", e); + } +}