aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/args.rs4
-rw-r--r--src/config.rs20
-rw-r--r--src/listing.rs14
-rw-r--r--src/renderer.rs8
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())
}