diff options
author | Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> | 2021-04-08 06:45:37 +0000 |
---|---|---|
committer | Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> | 2021-04-08 06:45:37 +0000 |
commit | 1beb4c992393b774b11cc3bad444c104dd263562 (patch) | |
tree | 9293c918a1d863ad962a45e5a9fd2b62c433151b /src/listing.rs | |
parent | Test URL encoding for special characters (diff) | |
download | miniserve-1beb4c992393b774b11cc3bad444c104dd263562.tar.gz miniserve-1beb4c992393b774b11cc3bad444c104dd263562.zip |
Avoid double-encoding file URL
Now that the '%' char itself is accepted in the file name and is encoded
into '%25', this exposed a previously silent bug:
`base` is already percent-encoded but it is encoded again when setting
`file_url`. This produces erroneous URLs such as:
'/%2523/x.y' instead of '/%23/x.y' for the path '/#/x.y'
Diffstat (limited to 'src/listing.rs')
-rw-r--r-- | src/listing.rs | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/src/listing.rs b/src/listing.rs index 2a62fd6..8c01b4b 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -15,7 +15,7 @@ use strum_macros::{Display, EnumString}; use crate::archive::CompressionMethod; use crate::errors::{self, ContextualError}; use crate::renderer; -use percent_encode_sets::{PATH, PATH_SEGMENT}; +use percent_encode_sets::PATH_SEGMENT; /// "percent-encode sets" as defined by WHATWG specs: /// https://url.spec.whatwg.org/#percent-encoded-bytes @@ -260,13 +260,12 @@ pub fn directory_listing( for entry in dir.path.read_dir()? { if dir.is_visible(&entry) || show_hidden { let entry = entry?; - let p = match entry.path().strip_prefix(&dir.path) { - Ok(p) => base.join(p), - Err(_) => continue, - }; // show file url as relative to static path - let file_url = utf8_percent_encode(&p.to_string_lossy(), PATH).to_string(); let file_name = entry.file_name().to_string_lossy().to_string(); + let file_url = base + .join(&utf8_percent_encode(&file_name, PATH_SEGMENT).to_string()) + .to_string_lossy() + .to_string(); // if file is a directory, add '/' to the end of the name if let Ok(metadata) = entry.metadata() { |