agate

Simple gemini server for static files
git clone https://github.com/mbrubeck/agate.git
Log | Files | Refs | README

commit 879422c2ccc2b1a9821c1598d68a540426501f74
parent fe62be214e5de2d3fda9990533a8d4539d6b630a
Author: Matt Brubeck <mbrubeck@limpet.net>
Date:   Thu, 31 Dec 2020 14:54:26 -0800

Simplify percent-encoding of paths.

Diffstat:
Msrc/main.rs | 30+++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/src/main.rs b/src/main.rs @@ -11,7 +11,16 @@ use rustls::{ internal::pemfile::{certs, pkcs8_private_keys}, NoClientAuth, ServerConfig, }; -use std::{error::Error, ffi::OsStr, fs::File, io::BufReader, marker::Unpin, path::Path, sync::Arc}; +use std::{ + borrow::Cow, + error::Error, + ffi::OsStr, + fs::File, + io::BufReader, + marker::Unpin, + path::Path, + sync::Arc, +}; use url::{Host, Url}; fn main() -> Result { @@ -229,14 +238,10 @@ async fn send_header<W: Write + Unpin>(stream: &mut W, status: u8, meta: &[&str] } async fn list_directory<W: Write + Unpin>(stream: &mut W, path: &Path) -> Result { + // https://url.spec.whatwg.org/#path-percent-encode-set const ENCODE_SET: AsciiSet = CONTROLS.add(b' ') - // https://url.spec.whatwg.org/#path-percent-encode-set .add(b'"').add(b'#').add(b'<').add(b'>') - .add(b'?').add(b'`').add(b'{').add(b'}') - // https://tools.ietf.org/html/rfc3986#section-2.2 - .add(b':').add(b'/').add(b'?').add(b'#').add(b'[').add(b']').add(b'@') - .add(b'!').add(b'$').add(b'&').add(b'\'').add(b'(').add(b')') - .add(b'*').add(b'+').add(b',').add(b';').add(b'='); + .add(b'?').add(b'`').add(b'{').add(b'}'); log::info!("Listing directory {:?}", path); send_text_gemini_header(stream).await?; @@ -251,12 +256,11 @@ async fn list_directory<W: Write + Unpin>(stream: &mut W, path: &Path) -> Result if entry.file_type().await?.is_dir() { name += "/"; } - if name.contains(char::is_whitespace) { - let url = percent_encode(name.as_bytes(), &ENCODE_SET); - lines.push(format!("=> {} {}\n", url, name)); - } else { - lines.push(format!("=> {}\n", name)); - } + let line = match percent_encode(name.as_bytes(), &ENCODE_SET).into() { + Cow::Owned(url) => format!("=> {} {}\n", url, name), + Cow::Borrowed(url) => format!("=> {}\n", url), // url and name are identical + }; + lines.push(line); } lines.sort(); for line in lines {