Serve files
This commit is contained in:
parent
55eca7fd71
commit
b462262ef1
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/target
|
||||
.idea
|
||||
storage
|
||||
|
1369
Cargo.lock
generated
1369
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -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"
|
98
src/main.rs
98
src/main.rs
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user