diff options
author | Lukas Stabe <lukas@stabe.de> | 2020-09-24 03:22:45 +0000 |
---|---|---|
committer | Lukas Stabe <lukas@stabe.de> | 2020-09-24 03:22:45 +0000 |
commit | 746535b7645b6aeb6eb58dced984530744fef161 (patch) | |
tree | 58b5a8df0d9185fc707e7c57104af21b58db1aa5 /src/listing.rs | |
parent | Sorry cargo fmt (diff) | |
download | miniserve-746535b7645b6aeb6eb58dced984530744fef161.tar.gz miniserve-746535b7645b6aeb6eb58dced984530744fef161.zip |
add title option (#335) and breadcrumb links in heading
Diffstat (limited to 'src/listing.rs')
-rw-r--r-- | src/listing.rs | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/src/listing.rs b/src/listing.rs index a70e237..7f09fa4 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -8,7 +8,7 @@ use percent_encoding::{percent_decode_str, utf8_percent_encode, AsciiSet, CONTRO use qrcodegen::{QrCode, QrCodeEcc}; use serde::Deserialize; use std::io; -use std::path::{Path, PathBuf}; +use std::path::{Component, Path, PathBuf}; use std::time::SystemTime; use strum_macros::{Display, EnumString}; @@ -123,6 +123,21 @@ impl Entry { } } +/// One entry in the path to the listed directory +pub struct Breadcrumb { + /// Name of directory + pub name: String, + + /// Link to get to directory, relative to listed directory + pub link: String, +} + +impl Breadcrumb { + fn new(name: String, link: String) -> Self { + Breadcrumb { name, link } + } +} + pub async fn file_handler(req: HttpRequest) -> Result<actix_files::NamedFile> { let path = &req.app_data::<crate::MiniserveConfig>().unwrap().path; actix_files::NamedFile::open(path).map_err(Into::into) @@ -143,6 +158,7 @@ pub fn directory_listing( upload_route: String, tar_enabled: bool, zip_enabled: bool, + title: Option<String>, ) -> Result<ServiceResponse, io::Error> { use actix_web::dev::BodyEncoding; let serve_path = req.path(); @@ -173,13 +189,31 @@ pub fn directory_listing( .display() .to_string(); - let display_dir = { + let connection_info = actix_web::dev::ConnectionInfo::get(req.head(), req.app_config()); + let title = title.unwrap_or_else(|| connection_info.host().into()); + + let breadcrumbs = { let decoded = percent_decode_str(&encoded_dir).decode_utf8_lossy(); - if is_root { - decoded.to_string() - } else { - format!("{}/", decoded) - } + let components = Path::new(&*decoded).components(); + components + .collect::<Vec<_>>() + .iter() + .rev() + .enumerate() + .rev() + .map(|(i, c)| { + let link = if i == 0 { + ".".into() + } else { + (0..i).map(|_| "..").collect::<Vec<_>>().join("/") + }; + match c { + Component::RootDir => Breadcrumb::new(title.clone(), link), + Component::Normal(s) => Breadcrumb::new(s.to_string_lossy().into(), link), + _ => panic!(""), + } + }) + .collect() }; let query_params = extract_query_parameters(req); @@ -360,7 +394,7 @@ pub fn directory_listing( &upload_route, &favicon_route, &encoded_dir, - &display_dir, + breadcrumbs, tar_enabled, zip_enabled, ) |