diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/args.rs | 4 | ||||
-rw-r--r-- | src/config.rs | 20 | ||||
-rw-r--r-- | src/listing.rs | 14 | ||||
-rw-r--r-- | src/renderer.rs | 8 |
4 files changed, 43 insertions, 3 deletions
diff --git a/src/args.rs b/src/args.rs index 687649d..a769256 100644 --- a/src/args.rs +++ b/src/args.rs @@ -197,6 +197,10 @@ pub struct CliArgs { #[cfg(feature = "tls")] #[clap(long = "tls-key", requires = "tls-cert", value_hint = ValueHint::FilePath)] pub tls_key: Option<PathBuf>, + + /// Enable README.md rendering in directories + #[clap(long)] + pub readme: bool, } /// Checks wether an interface is valid, i.e. it can be parsed into an IP address diff --git a/src/config.rs b/src/config.rs index 2ee014f..5bcbd62 100644 --- a/src/config.rs +++ b/src/config.rs @@ -123,6 +123,9 @@ pub struct MiniserveConfig { /// If enabled, display a wget command to recursively download the current directory pub show_wget_footer: bool, + /// If enabled, render the readme from the current directory + pub readme: bool, + /// If set, use provided rustls config for TLS #[cfg(feature = "tls")] pub tls_rustls_config: Option<rustls::ServerConfig>, @@ -151,8 +154,20 @@ impl MiniserveConfig { // Generate some random routes for the favicon and css so that they are very unlikely to conflict with // real files. - let favicon_route = format!("/{}", nanoid::nanoid!(10, &ROUTE_ALPHABET)); - let css_route = format!("/{}", nanoid::nanoid!(10, &ROUTE_ALPHABET)); + // If --random-route is enabled , in order to not leak the random generated route, we must not use it + // as static files prefix. + // Otherwise, we should apply route_prefix to static files. + let (favicon_route, css_route) = if args.random_route { + ( + format!("/{}", nanoid::nanoid!(10, &ROUTE_ALPHABET)), + format!("/{}", nanoid::nanoid!(10, &ROUTE_ALPHABET)), + ) + } else { + ( + format!("{}/{}", route_prefix, nanoid::nanoid!(10, &ROUTE_ALPHABET)), + format!("{}/{}", route_prefix, nanoid::nanoid!(10, &ROUTE_ALPHABET)), + ) + }; let default_color_scheme = args.color_scheme; let default_color_scheme_dark = args.color_scheme_dark; @@ -244,6 +259,7 @@ impl MiniserveConfig { hide_version_footer: args.hide_version_footer, hide_theme_selector: args.hide_theme_selector, show_wget_footer: args.show_wget_footer, + readme: args.readme, tls_rustls_config: tls_rustls_server_config, }) } diff --git a/src/listing.rs b/src/listing.rs index 25f50fa..82b4cdb 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -7,6 +7,7 @@ use actix_web::dev::ServiceResponse; use actix_web::web::Query; use actix_web::{HttpMessage, HttpRequest, HttpResponse}; use bytesize::ByteSize; +use comrak::{markdown_to_html, ComrakOptions}; use percent_encoding::{percent_decode_str, utf8_percent_encode}; use qrcodegen::{QrCode, QrCodeEcc}; use serde::Deserialize; @@ -232,6 +233,7 @@ pub fn directory_listing( } let mut entries: Vec<Entry> = Vec::new(); + let mut readme: Option<(String, String)> = None; for entry in dir.path.read_dir()? { if dir.is_visible(&entry) || conf.show_hidden { @@ -275,13 +277,22 @@ pub fn directory_listing( )); } else if metadata.is_file() { entries.push(Entry::new( - file_name, + file_name.clone(), EntryType::File, file_url, Some(ByteSize::b(metadata.len())), last_modification_date, symlink_dest, )); + if conf.readme && file_name.to_lowercase() == "readme.md" { + readme = Some(( + file_name.to_string(), + markdown_to_html( + &std::fs::read_to_string(entry.path())?, + &ComrakOptions::default(), + ), + )); + } } } else { continue; @@ -372,6 +383,7 @@ pub fn directory_listing( HttpResponse::Ok().content_type(mime::TEXT_HTML_UTF_8).body( renderer::page( entries, + readme, is_root, query_params, breadcrumbs, diff --git a/src/renderer.rs b/src/renderer.rs index 75d2c71..7ec48b0 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -10,9 +10,11 @@ use crate::auth::CurrentUser; use crate::listing::{Breadcrumb, Entry, QueryParameters, SortingMethod, SortingOrder}; use crate::{archive::ArchiveMethod, MiniserveConfig}; +#[allow(clippy::too_many_arguments)] /// Renders the file listing pub fn page( entries: Vec<Entry>, + readme: Option<(String, String)>, is_root: bool, query_params: QueryParameters, breadcrumbs: Vec<Breadcrumb>, @@ -165,6 +167,12 @@ pub fn page( } } } + @if let Some(readme) = readme { + div { + h3 { (readme.0) } + (PreEscaped (readme.1)); + } + } a.back href="#top" { (arrow_up()) } |