use axum::{ body::Body, headers::HeaderName, http::{HeaderValue, Request, StatusCode}, response::{Response, IntoResponse}, routing::get, Router, }; use tower::ServiceExt; use tower_http::services::ServeFile; use crate::types::http::ResponseCode; pub mod admin; pub mod console; pub mod docs; pub mod file; pub mod pages; pub fn router() -> Router { Router::new() .nest("/", pages::router()) .route("/favicon.ico", get(file::favicon)) .route("/robots.txt", get(file::robots)) .route("/js/*path", get(file::js)) .route("/css/*path", get(file::css)) .route("/fonts/*path", get(file::fonts)) .route("/image/*path", get(file::image)) .route("/image/avatar", get(file::avatar)) .route("/image/banner", get(file::banner)) } pub async fn serve(path: &str) -> Response { if !path.chars().any(|c| c == '.') { return ResponseCode::BadRequest.text("Invalid file path"); } let path = format!("public{path}"); let file = ServeFile::new(path); let Ok(mut res) = file.oneshot(Request::new(Body::empty())).await else { tracing::error!("Error while fetching file"); return ResponseCode::InternalServerError.text("Error while fetching file"); }; if res.status() != StatusCode::OK { return ResponseCode::NotFound.text("File not found"); } res.headers_mut().insert( HeaderName::from_static("cache-control"), HeaderValue::from_static("max-age=300"), ); res.into_response() }