Serve files

This commit is contained in:
Pierre HUBERT 2022-03-27 13:44:53 +02:00
parent 55eca7fd71
commit b462262ef1
4 changed files with 1471 additions and 2 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
/target
.idea
storage

1369
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -6,3 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "3.1.6", features = ["derive", "env"] }
actix-web = "4"
actix-files = "0.6"
env_logger = "0.9.0"
log = "0.4"

View File

@ -1,3 +1,97 @@
fn main() {
println!("Hello, world!");
use std::path::{Path, PathBuf};
use actix_files::{Files, NamedFile};
use actix_web::{App, HttpResponse, HttpServer};
use actix_web::dev::{fn_service, ServiceRequest, ServiceResponse};
use actix_web::middleware::Logger;
use clap::Parser;
/// Simple pages server
#[derive(Parser, Debug, Clone)]
#[clap(author, version, about, long_about = None)]
struct Args {
/// The address and port this server will listen on
#[clap(short, long, env, default_value = "0.0.0.0:8000")]
listen_address: String,
/// The place wheres files to serve are hosted
#[clap(short, long, env)]
files_path: String,
/// Update token
#[clap(short, long, env)]
update_token: String,
/// The IP addresses allowed to perform updates
#[clap(short, long, env, default_value = "*")]
allowed_ips_for_update: String,
/// Index file name
#[clap(short, long, env, default_value = "index.html")]
index_file: String,
/// Handle for not found files. By default, a basic message is returned
#[clap(short, long, env, default_value = "")]
not_found_file: String,
}
impl Args {
pub fn storage_path(&self) -> &Path {
Path::new(&self.files_path)
}
pub fn default_handler_path(&self) -> Option<PathBuf> {
match self.not_found_file.is_empty() {
true => None,
false => Some(self.storage_path().join(&self.not_found_file))
}
}
}
static mut ARGS: Option<Args> = None;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let args: Args = Args::parse();
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
log::info!("starting HTTP server at {}", args.listen_address);
let listen_address = args.listen_address.to_string();
if !args.storage_path().exists() {
panic!("Specified files path does not exists!");
}
unsafe { ARGS = Some(args.clone()); }
HttpServer::new(move || {
App::new()
// Serve a tree of static files at the web root and specify the index file.
// Note that the root path should always be defined as the last item. The paths are
// resolved in the order they are defined. If this would be placed before the `/images`
// path then the service for the static images would never be reached.
.service(Files::new("/", &args.files_path)
.index_file(&args.index_file)
.default_handler(fn_service(|req: ServiceRequest| async {
let (req, _) = req.into_parts();
if let Some(h) = unsafe { ARGS.as_ref().unwrap() }.default_handler_path().as_ref() {
let file = NamedFile::open_async(h).await?;
let res = file.into_response(&req);
Ok(ServiceResponse::new(req, res))
} else {
Ok(ServiceResponse::new(req, HttpResponse::NotFound()
.body("404 Not found")))
}
}))
)
// Enable the logger.
.wrap(Logger::default())
})
.bind(listen_address)?
.run()
.await
}