use rocket::{fs::FileServer, get, launch, routes, serde::json::{json, Value}}; use std::{env, os::unix::fs::MetadataExt, path::PathBuf}; use std::fs::read_dir; use humansize::{format_size, DECIMAL}; use rocket::http::Header; use rocket::{Request, Response}; use rocket::fairing::{Fairing, Info, Kind}; pub struct Cors; #[rocket::async_trait] impl Fairing for Cors { fn info(&self) -> Info { Info { name: "Cross-Origin-Resource-Sharing Middleware", kind: Kind::Response, } } async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) { response.set_header(Header::new( "access-control-allow-origin", "http://127.0.0.1", )); response.set_header(Header::new( "access-control-allow-methods", "GET, PATCH, OPTIONS", )); } } #[get("/ls/")] fn _list_dir(mut path: PathBuf) -> Value { if path.to_string_lossy().is_empty() { path = PathBuf::from("."); } let dir = read_dir(path); match dir { Ok(ls) => { let mut v: Vec = Vec::new(); for elem in ls { if elem.is_err() { continue; } let e = elem.unwrap(); let p = e.path(); let name = e.file_name().to_string_lossy().to_string(); if p.is_file() { let meta = e.metadata().unwrap(); let size = meta.size(); if name.starts_with(".") { v.push(json!({"name": name.clone(), "type": "FILE", "size": format_size(size, DECIMAL), "hidden": true})); } else { v.push(json!({"name": name.clone(), "type": "FILE", "size": format_size(size, DECIMAL)})); } } else if p.is_symlink() { if name.starts_with(".") { v.push(json!({"name": name.clone(), "type": "LINK", "hidden": true})); } else { v.push(json!({"name": name.clone(), "type": "LINK"})); } } else { if name.starts_with(".") { v.push(json!({"name": name.clone(), "type": "DIR", "hidden": true})) } else { v.push(json!({"name": name.clone(), "type": "DIR"})) } } } return json!({"status": 200, "dir": v}); } Err(_) => { return json!({"status": 404}) } } } #[launch] fn rocket() -> _ { let mut args: Vec = Vec::new(); for a in env::args() { args.push(a); } let mut port: u16 = 9000; if args.len() != 1 { let mut index = 0; for a in args.iter() { let ptry: Result = a.parse(); match ptry { Ok(val) => { port = val; break; } Err(err) => { println!("arg #{} : {}", index, err); } } index += 1; } } println!("Launching @ 127.0.0.1:{}", port); let rock = rocket::build(); let fig = rock.figment().clone() .merge((rocket::Config::PORT, port)); rock .configure(fig) .attach(Cors) .mount("/", FileServer::from(".")) // This is a DEBUG only feature, it gives the option to list the given directory //.mount("/", routes![_list_dir]) }