commit a0079082483db6b659dd31cc97c39c91300abf76
parent e4dacd1315dec45a51db57525aa85d3c1637a326
Author: Matt Brubeck <mbrubeck@limpet.net>
Date: Sun, 27 Dec 2020 12:11:38 -0800
Facter directory listing into a function
Diffstat:
M | src/main.rs | | | 61 | ++++++++++++++++++++++++++++++------------------------------- |
1 file changed, 30 insertions(+), 31 deletions(-)
diff --git a/src/main.rs b/src/main.rs
@@ -188,33 +188,9 @@ async fn send_response<W: Write + Unpin>(url: Url, stream: &mut W) -> Result {
// if the path ends with a slash or the path is empty, the links will work the same
// without a redirect
path.push("index.gmi");
- if path.exists() {
- // index file exists
- } else if path.with_file_name(".directory-listing-ok").exists() {
- // no index file, but directory listing allowed
+ if !path.exists() && path.with_file_name(".directory-listing-ok").exists() {
path.pop();
- log::info!("Listing directory {:?}", path);
- let entries = std::fs::read_dir(path)?;
- let listing = entries
- .filter(Result::is_ok)
- .map(Result::unwrap)
- .map(|entry| {
- // transform filenames into gemini link lines
- let mut name = String::from("=> ");
- name += &entry.file_name().to_string_lossy();
- if entry.path().is_dir() {
- // to avoid redirects link to directories with a trailing slash
- name += "/";
- }
- name + "\n"
- })
- // filter out files starting with a dot
- .filter(|entry| !entry.starts_with("=> ."))
- .collect::<String>();
-
- respond(stream, "20", &["text/gemini"]).await?;
- stream.write_all(listing.as_bytes()).await?;
- return Ok(());
+ return list_directory(stream, &path).await;
}
} else {
// if client is not redirected, links may not work as expected without trailing slash
@@ -227,11 +203,7 @@ async fn send_response<W: Write + Unpin>(url: Url, stream: &mut W) -> Result {
// Send header.
if path.extension() == Some(OsStr::new("gmi")) {
- if let Some(lang) = ARGS.language.as_deref() {
- respond(stream, "20", &["text/gemini;lang=", lang]).await?;
- } else {
- respond(stream, "20", &["text/gemini"]).await?;
- }
+ send_text_gemini_header(stream).await?;
} else {
let mime = mime_guess::from_path(&path).first_or_octet_stream();
respond(stream, "20", &[mime.essence_str()]).await?;
@@ -252,3 +224,30 @@ async fn respond<W: Write + Unpin>(stream: &mut W, status: &str, meta: &[&str])
stream.write_all(b"\r\n").await?;
Ok(())
}
+
+async fn list_directory<W: Write + Unpin>(stream: &mut W, path: &Path) -> Result {
+ log::info!("Listing directory {:?}", path);
+ send_text_gemini_header(stream).await?;
+ for entry in std::fs::read_dir(path)? {
+ let entry = entry?;
+ let mut name = entry.file_name().into_string().or(Err("Non-Unicode filename"))?;
+ if name.starts_with('.') {
+ continue;
+ }
+ if entry.file_type()?.is_dir() {
+ name += "/";
+ }
+ stream.write_all(b"=> ").await?;
+ stream.write_all(name.as_bytes()).await?;
+ stream.write_all(b"\n").await?;
+ }
+ Ok(())
+}
+
+async fn send_text_gemini_header<W: Write + Unpin>(stream: &mut W) -> Result {
+ if let Some(lang) = ARGS.language.as_deref() {
+ respond(stream, "20", &["text/gemini;lang=", lang]).await
+ } else {
+ respond(stream, "20", &["text/gemini"]).await
+ }
+}