use axum::{extract::Path, http::StatusCode, routing::get, Router}; use super::types::AppState; async fn doc_redirect() -> axum::response::Redirect { axum::response::Redirect::to("/doc-wasm") } async fn wasm_doc_handler() -> Result { let path = std::path::Path::new("/Users/accusys/momentry_core/docs_v1.0/doc_wasm/index.html"); match tokio::fs::read_to_string(path).await { Ok(html) => Ok(([("content-type", "text/html; charset=utf-8")], html)), Err(_) => Err((StatusCode::NOT_FOUND, "Doc not found")), } } async fn wasm_doc_file_handler( Path(file): Path, ) -> Result { if file.contains("..") || file.contains("//") { return Err((StatusCode::NOT_FOUND, "Invalid path")); } let base = std::path::Path::new("/Users/accusys/momentry_core/docs_v1.0/doc_wasm"); let path = base.join(&file); if !path.exists() || !path.starts_with(base) { return Err((StatusCode::NOT_FOUND, "File not found")); } let data = tokio::fs::read(&path) .await .map_err(|_| (StatusCode::NOT_FOUND, "Read error"))?; let mime = if file.ends_with(".wasm") { "application/wasm" } else if file.ends_with(".js") { "application/javascript" } else if file.ends_with(".md") { "text/markdown; charset=utf-8" } else if file.ends_with(".css") { "text/css" } else { "application/octet-stream" }; Ok(([("content-type", mime)], data)) } pub fn doc_routes() -> Router { Router::new() .route("/doc", get(doc_redirect)) .route("/doc/*file", get(doc_redirect)) .route("/dev-doc", get(doc_redirect)) .route("/doc-wasm", get(wasm_doc_handler)) .route("/doc-wasm/*file", get(wasm_doc_file_handler)) }