Repository: svenstaro/miniserve
Pull request #911 (2022-09-19 19:59:16)

Add support for README.txt and README files
Since we added support for readme.md I thought it'd be easy enough to do readme.txt and just plain readme.

I was thinking of adding support for readme.org like in GitHub but didn't find any libraries that can convert it easily.

Also, if I rename "README.md" from miniserve to .txt, it only shows a fraction of the file contents, I can't debug it... 


Patch:
diff --git a/Cargo.toml b/Cargo.toml
index 05baaab..39e4289 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -45,6 +45,7 @@ mime = "0.3"
 nanoid = "0.4"
 percent-encoding = "2"
 port_check = "0.1"
+regex = "1"
 rustls = { version = "0.20", optional = true }
 rustls-pemfile = { version = "1.0", optional = true }
 serde = { version = "1", features = ["derive"] }
diff --git a/src/listing.rs b/src/listing.rs
index 7477599..fbee8de 100644
--- a/src/listing.rs
+++ b/src/listing.rs
@@ -9,6 +9,7 @@ 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 regex::Regex;
 use serde::Deserialize;
 use strum_macros::{Display, EnumString};
 
@@ -224,6 +225,7 @@ pub fn directory_listing(
 
     let mut entries: Vec<Entry> = Vec::new();
     let mut readme: Option<(String, String)> = None;
+    let readme_rx: Regex = Regex::new("^readme([.](md|txt))?$").unwrap();
 
     for entry in dir.path.read_dir()? {
         if dir.is_visible(&entry) || conf.show_hidden {
@@ -274,13 +276,18 @@ pub fn directory_listing(
                         last_modification_date,
                         symlink_dest,
                     ));
-                    if conf.readme && file_name.to_lowercase() == "readme.md" {
+                    if conf.readme && readme_rx.is_match(&file_name.to_lowercase()) {
+                        let ext = file_name.split('.').last().unwrap().to_lowercase();
                         readme = Some((
                             file_name.to_string(),
-                            markdown_to_html(
-                                &std::fs::read_to_string(entry.path())?,
-                                &ComrakOptions::default(),
-                            ),
+                            if ext == "md" {
+                                markdown_to_html(
+                                    &std::fs::read_to_string(entry.path())?,
+                                    &ComrakOptions::default(),
+                                )
+                            } else {
+                                format!("<pre>{}</pre>", &std::fs::read_to_string(entry.path())?)
+                            },
                         ));
                     }
                 }


Test patch:
diff --git a/tests/readme.rs b/tests/readme.rs
index 56a3afd..3fcbe29 100644
--- a/tests/readme.rs
+++ b/tests/readme.rs
@@ -64,7 +64,11 @@ fn show_root_readme_contents(
     case("readme.md"),
     case("README.md"),
     case("README.MD"),
-    case("ReAdMe.Md")
+    case("ReAdMe.Md"),
+    case("Readme.txt"),
+    case("README.txt"),
+    case("README"),
+    case("ReAdMe")
 )]
 fn show_nested_readme_contents(
     #[with(&["--readme"])] server: TestServer,
@@ -113,13 +117,11 @@ fn assert_readme_contents(parsed_dom: &Document, filename: &str) {
         .find(Attr("id", "readme-contents"))
         .next()
         .is_some());
-    assert!(
-        parsed_dom
-            .find(Attr("id", "readme-contents"))
-            .next()
-            .unwrap()
-            .text()
-            .trim()
-            == format!("Contents of {}", filename)
-    );
+    assert!(parsed_dom
+        .find(Attr("id", "readme-contents"))
+        .next()
+        .unwrap()
+        .text()
+        .trim()
+        .contains(&format!("Contents of {}", filename)));
 }