60 lines
1.4 KiB
Rust

use std::{
net::{IpAddr, SocketAddr},
num::NonZeroUsize,
path::PathBuf,
thread::available_parallelism,
};
use actix_web::{App, HttpServer};
use clap::{crate_name, crate_version, Parser};
#[derive(Parser, Debug)]
#[clap(name = crate_name!(), version = crate_version!())]
struct Args {
/// Directory to expose
#[clap(default_value = ".", value_parser = parse_valid_dir)]
dir: PathBuf,
/// IP address to use
#[clap(default_value = "0.0.0.0")]
ip: IpAddr,
/// Port number to connect
#[clap(default_value = "8080")]
port: u16,
}
fn parse_valid_dir(dir: &str) -> Result<PathBuf, String> {
let path = std::path::Path::new(dir);
if path.is_dir() {
Ok(path.to_path_buf())
} else {
Err(format!("{} is not a valid directory", path.display()))
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let args = Args::parse();
let dir = args.dir;
let sock = SocketAddr::new(args.ip, args.port);
println!(
"Starting HTTP server on {sock} exposing dir {}",
dir.display()
);
HttpServer::new(move || {
App::new().service(
actix_files::Files::new("/", dir.clone())
.show_files_listing()
.prefer_utf8(true),
)
})
.workers(available_parallelism().map_or(1, NonZeroUsize::get))
.bind(sock)?
.run()
.await
}