diff --git a/src/main.rs b/src/main.rs index 795688c..cb449b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,11 +19,46 @@ struct HandlerPath { filename: Option, } -async fn handler(path: web::Path) -> impl Responder { - let filename = path.filename.as_deref().unwrap_or("index.html"); +#[derive(Debug, Clone, Eq, PartialEq)] +struct Schema(String); - match swagger_ui::Assets::get(filename) { - Some(f) => HttpResponse::Ok().body(f.to_vec()), +async fn handler(path: web::Path, schema: web::Data) -> impl Responder { + let filename: &str = path.filename.as_deref().unwrap_or("index.html"); + + let ext = filename + .rsplit_once('.') + .map(|r| r.1).unwrap_or_default(); + + let content_type = match ext { + "js" => "application/javascript", + "css" => "text/css", + "html" => "text/html", + "png" => "image/png", + "json" => "application/json", + "yml" | "yaml" => "application/x-yaml", + _ => "text/plain" + }; + + let filebytes = if filename.eq("schema.yaml") { + Some(schema.0.as_bytes().to_vec()) + } else { + swagger_ui::Assets::get(filename).map(|f| f.to_vec()) + }; + + match filebytes { + Some(f) => { + let mut bytes = f.to_vec(); + + if filename.eq("index.html") { + bytes = String::from_utf8_lossy(&bytes).to_string() + .replace("https://petstore.swagger.io/v2/swagger.json", "/schema.yaml") + .as_bytes().to_vec(); + } + + HttpResponse::Ok() + .insert_header(("Content-Type", content_type)) + .body(bytes) + } None => HttpResponse::NotFound().body("404 not found"), } } @@ -35,8 +70,13 @@ async fn main() -> std::io::Result<()> { log::info!("Will listen on http://{}/", args.listen_address); - HttpServer::new(|| { + let schema = Schema(std::fs::read_to_string(args.schema) + .expect("Failed to read schema!")); + + HttpServer::new(move || { App::new() + .app_data(web::Data::new(schema.clone())) + .route("/", web::get().to(handler)) .route("/{filename}", web::get().to(handler)) })