Files
fleen/src/server.rs
T

60 lines
2.1 KiB
Rust
Raw Normal View History

2025-09-01 19:15:30 -05:00
use std::fs;
2025-09-01 17:32:45 -05:00
use std::path::PathBuf;
2025-09-01 19:15:30 -05:00
use axum::body::Body;
2025-09-01 17:32:45 -05:00
use axum::extract::State;
2025-09-01 19:15:30 -05:00
use axum::http::Uri;
2025-09-01 17:32:45 -05:00
use axum::response::{IntoResponse, Response};
use axum::Router;
use axum::routing::get;
2025-09-06 00:28:51 -05:00
use crate::renderer::{server_render, RenderOutput};
2025-09-01 17:32:45 -05:00
2025-09-01 19:28:21 -05:00
pub async fn start_server(root: PathBuf, port: u32) {
2025-09-01 17:32:45 -05:00
let app = Router::new()
2025-09-01 19:28:21 -05:00
.route("/", get(|State(root): State<PathBuf>| async move {
// We need a separate route for the default path because {*p} must match at least one thing
2025-09-06 00:28:51 -05:00
serve_path("index.html".to_string(), root.clone())
2025-09-01 19:15:30 -05:00
}))
2025-09-01 19:28:21 -05:00
.route("/{*path}", get(|State(root): State<PathBuf>, uri: Uri| async move {
serve_path(String::from(uri.path()), root.clone())
2025-09-01 19:15:30 -05:00
}))
2025-09-01 19:28:21 -05:00
.with_state(root);
2025-09-01 17:32:45 -05:00
2025-09-01 19:28:21 -05:00
let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port)).await.unwrap();
2025-09-01 17:32:45 -05:00
axum::serve(listener, app).await.unwrap();
}
2025-09-01 19:28:21 -05:00
fn serve_path(path: String, root: PathBuf) -> impl IntoResponse {
2025-09-01 19:15:30 -05:00
let path = path.strip_prefix("/").unwrap_or(path.as_str());
2025-09-06 00:28:51 -05:00
let render = server_render(path.into(), root.as_ref());
2025-09-01 19:15:30 -05:00
2025-09-01 17:32:45 -05:00
match render {
2025-09-01 19:15:30 -05:00
Ok(RenderOutput::Rendered(_, content)) |
Ok(RenderOutput::Hidden(_, content)) => {
2025-09-06 21:49:55 -05:00
// We rendered some output so spit it back
2025-09-01 19:15:30 -05:00
Response::builder()
.status(200)
.body(Body::from(content)).unwrap()
}
Ok(RenderOutput::RawFile(file)) => {
2025-09-06 21:49:55 -05:00
// We were pointed at the raw contents of a file:
2025-09-01 17:32:45 -05:00
Response::builder()
.status(200)
2025-09-06 00:28:51 -05:00
.body(Body::from(fs::read(root.join(file)).unwrap_or(vec![]))).unwrap()
2025-09-01 17:32:45 -05:00
}
Ok(RenderOutput::NoOutput) |
Ok(RenderOutput::Dir(_)) => {
2025-09-06 21:49:55 -05:00
// Asked for something that doesn't exist:
2025-09-01 17:32:45 -05:00
Response::builder()
.status(404)
2025-09-01 19:15:30 -05:00
.body(Body::from(include_str!("../templates/404.html"))).unwrap()
2025-09-01 17:32:45 -05:00
}
Err(err) => {
2025-09-06 21:49:55 -05:00
// Oh no!
2025-09-01 17:32:45 -05:00
Response::builder()
.status(500)
2025-09-01 19:15:30 -05:00
.body(Body::from(format!("{}", err))).unwrap()
2025-09-01 17:32:45 -05:00
}
}
}