use std::path::Path; use actix_files; use actix_web::{ dev::{ServiceRequest, ServiceResponse}, App, HttpServer, }; use clap::{arg, command, Parser}; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct ServantArgs { #[arg(long, default_value_t = 8080)] port: u16, #[arg(long, default_value_t = String::from("0.0.0.0"))] host: String, #[arg(long, default_value_t = String::from("/"))] mount: String, #[arg(long)] serve_dir: String, #[arg(long, default_value_t = String::from("index.html"))] index_file: String, } #[actix_web::main] async fn main() -> std::io::Result<()> { let args = ServantArgs::parse(); let bind_addr = format!("{}:{}", args.host, args.port); println!("Listening on http://{}", bind_addr); let index_path = Path::new(args.serve_dir.as_str()) .join(args.index_file.as_str()) .display() .to_string(); let mount_point = args.mount.clone(); HttpServer::new(move || { let index_path = index_path.to_owned(); App::new().service( actix_files::Files::new(&mount_point, args.serve_dir.as_str()) .index_file(args.index_file.as_str()) .default_handler(move |req: ServiceRequest| { let (http_req, _payload) = req.into_parts(); let index_path = index_path.to_owned(); async { let response = actix_files::NamedFile::open(index_path)?.into_response(&http_req); Ok(ServiceResponse::new(http_req, response)) } }), ) }) .bind(bind_addr)? .run() .await }