Simplify percent-encoding of paths.

This commit is contained in:
Matt Brubeck 2020-12-31 14:54:26 -08:00
parent fe62be214e
commit 879422c2cc

View file

@ -11,7 +11,16 @@ use rustls::{
internal::pemfile::{certs, pkcs8_private_keys}, internal::pemfile::{certs, pkcs8_private_keys},
NoClientAuth, ServerConfig, 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}; use url::{Host, Url};
fn main() -> Result { 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 { 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' ') 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'>')
.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'=');
log::info!("Listing directory {:?}", path); log::info!("Listing directory {:?}", path);
send_text_gemini_header(stream).await?; 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() { if entry.file_type().await?.is_dir() {
name += "/"; name += "/";
} }
if name.contains(char::is_whitespace) { let line = match percent_encode(name.as_bytes(), &ENCODE_SET).into() {
let url = percent_encode(name.as_bytes(), &ENCODE_SET); Cow::Owned(url) => format!("=> {} {}\n", url, name),
lines.push(format!("=> {} {}\n", url, name)); Cow::Borrowed(url) => format!("=> {}\n", url), // url and name are identical
} else { };
lines.push(format!("=> {}\n", name)); lines.push(line);
}
} }
lines.sort(); lines.sort();
for line in lines { for line in lines {