🚧 wip: threading the multi-root stuff into the file server module

main
Trisha 2022-03-25 15:40:36 -05:00
parent 81141e2faf
commit e6273209f9
3 changed files with 23 additions and 12 deletions

View File

@ -5,7 +5,7 @@
use std::{ use std::{
cmp::min, cmp::min,
collections::HashMap, collections::*,
convert::{Infallible, TryFrom}, convert::{Infallible, TryFrom},
io::SeekFrom, io::SeekFrom,
path::{ path::{
@ -56,6 +56,7 @@ use errors::FileServerError;
#[derive (Default)] #[derive (Default)]
pub struct Config { pub struct Config {
pub file_server_root: PathBuf, pub file_server_root: PathBuf,
pub file_server_roots: BTreeMap <String, PathBuf>,
} }
pub struct FileServer { pub struct FileServer {
@ -68,7 +69,7 @@ pub struct FileServer {
impl FileServer { impl FileServer {
pub fn new ( pub fn new (
file_server_root: PathBuf, config: Config,
asset_root: &Path, asset_root: &Path,
name: String, name: String,
metrics_interval: Arc <ArcSwap <Option <metrics::Interval>>>, metrics_interval: Arc <ArcSwap <Option <metrics::Interval>>>,
@ -76,9 +77,7 @@ impl FileServer {
) -> Result <Self, FileServerError> ) -> Result <Self, FileServerError>
{ {
Ok (Self { Ok (Self {
config: Config { config,
file_server_root,
},
handlebars: load_templates (asset_root)?, handlebars: load_templates (asset_root)?,
metrics_startup: metrics::Startup::new (name), metrics_startup: metrics::Startup::new (name),
metrics_interval, metrics_interval,
@ -374,9 +373,12 @@ impl FileServer {
resp resp
} }
let root: &std::path::Path = &self.config.file_server_root; let roots = internal::FileRoots {
files: &self.config.file_server_root,
dirs: &self.config.file_server_roots,
};
Ok (match internal::serve_all (root, method, uri, headers, self.hidden_path.as_deref ()).await? { Ok (match internal::serve_all (roots, method, uri, headers, self.hidden_path.as_deref ()).await? {
Favicon => serve_error (StatusCode::NotFound, "Not found\n"), Favicon => serve_error (StatusCode::NotFound, "Not found\n"),
Forbidden => serve_error (StatusCode::Forbidden, "403 Forbidden\n"), Forbidden => serve_error (StatusCode::Forbidden, "403 Forbidden\n"),
MethodNotAllowed => serve_error (StatusCode::MethodNotAllowed, "Unsupported method\n"), MethodNotAllowed => serve_error (StatusCode::MethodNotAllowed, "Unsupported method\n"),

View File

@ -4,7 +4,7 @@
// human-readable HTML // human-readable HTML
use std::{ use std::{
collections::HashMap, collections::*,
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
@ -244,11 +244,17 @@ async fn serve_api (
Ok (NotFound) Ok (NotFound)
} }
#[derive (Clone, Copy)]
pub struct FileRoots <'a> {
pub files: &'a Path,
pub dirs: &'a BTreeMap <String, PathBuf>,
}
// Handle the requests internally without knowing anything about PTTH or // Handle the requests internally without knowing anything about PTTH or
// HTML / handlebars // HTML / handlebars
pub async fn serve_all ( pub async fn serve_all (
root: &Path, roots: FileRoots <'_>,
method: Method, method: Method,
uri: &str, uri: &str,
headers: &HashMap <String, Vec <u8>>, headers: &HashMap <String, Vec <u8>>,
@ -283,7 +289,7 @@ pub async fn serve_all (
} }
if let Some (path) = path.strip_prefix ("/api") { if let Some (path) = path.strip_prefix ("/api") {
return serve_api (root, &uri, hidden_path, path).await; return serve_api (roots.files, &uri, hidden_path, path).await;
} }
let path = match path.strip_prefix ("/files/") { let path = match path.strip_prefix ("/files/") {
@ -298,7 +304,7 @@ pub async fn serve_all (
let path_s = percent_decode (encoded_path.as_bytes ()).decode_utf8 ().map_err (FileServerError::PathNotUtf8)?; let path_s = percent_decode (encoded_path.as_bytes ()).decode_utf8 ().map_err (FileServerError::PathNotUtf8)?;
let path = Path::new (&*path_s); let path = Path::new (&*path_s);
let full_path = root.join (path); let full_path = roots.files.join (path);
trace! ("full_path = {:?}", full_path); trace! ("full_path = {:?}", full_path);

View File

@ -319,7 +319,10 @@ pub async fn run_server (
}); });
let file_server = file_server::FileServer::new ( let file_server = file_server::FileServer::new (
config_file.file_server_root.clone (), file_server::Config {
file_server_root: config_file.file_server_root.clone (),
file_server_roots: config_file.file_server_roots.clone (),
},
&asset_root.clone ().unwrap_or_else (|| PathBuf::from (".")), &asset_root.clone ().unwrap_or_else (|| PathBuf::from (".")),
config_file.name.clone (), config_file.name.clone (),
metrics_interval, metrics_interval,