Serve files
This commit is contained in:
parent
55eca7fd71
commit
b462262ef1
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
.idea
|
.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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[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() {
|
use std::path::{Path, PathBuf};
|
||||||
println!("Hello, world!");
|
|
||||||
|
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