"tokio-rustls",
"tokio-stream",
"tokio-util",
+ "urlencoding",
"uuid",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+[[package]]
+name = "urlencoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68b90931029ab9b034b300b797048cf23723400aa757e8a2bfb9d748102f9821"
+
[[package]]
name = "uuid"
version = "1.1.1"
let uri_prefix = if path_prefix.is_empty() {
"/".to_owned()
} else {
- format!("/{}/", &path_prefix)
+ format!("/{}/", encode_uri(&path_prefix))
};
let cors = matches.is_present("cors");
let auth = match matches.value_of("auth") {
}
Ok(PrivateKey(keys[0].to_owned()))
}
+
+pub fn encode_uri(v: &str) -> String {
+ let parts: Vec<_> = v.split('/').map(urlencoding::encode).collect();
+ parts.join("/")
+}
pub type BoxResult<T> = Result<T, Box<dyn std::error::Error>>;
-use crate::args::{matches, Args};
+use crate::args::{encode_uri, matches, Args};
use crate::server::serve;
#[tokio::main]
use crate::auth::{generate_www_auth, valid_digest};
-use crate::{Args, BoxResult};
+use crate::{encode_uri, Args, BoxResult};
use async_walkdir::WalkDir;
use async_zip::write::{EntryOptions, ZipFileWriter};
*res.body_mut() = Body::wrap_stream(stream);
res.headers_mut().insert(
CONTENT_DISPOSITION,
- HeaderValue::from_str(&format!("attachment; filename=\"{}.zip\"", filename,)).unwrap(),
+ HeaderValue::from_str(&format!(
+ "attachment; filename=\"{}.zip\"",
+ encode_uri(filename),
+ ))
+ .unwrap(),
);
Ok(())
}
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>"#,
- prefix, self.name, self.base_name, mtime
+ prefix,
+ encode_uri(&self.name),
+ urlencoding::encode(&self.base_name),
+ mtime
),
PathType::File | PathType::SymlinkFile => format!(
r#"<D:response>
</D:propstat>
</D:response>"#,
prefix,
- self.name,
- self.base_name,
+ encode_uri(&self.name),
+ urlencoding::encode(&self.base_name),
self.size.unwrap_or_default(),
mtime
),