pub path_is_file: bool,
pub path_prefix: String,
pub uri_prefix: String,
- pub hidden: String,
+ pub hidden: Vec<String>,
pub auth_method: AuthMethod,
pub auth: AccessControl,
pub allow_upload: bool,
} else {
format!("/{}/", &encode_uri(&path_prefix))
};
- let hidden: String = matches
+ let hidden: Vec<String> = matches
.value_of("hidden")
- .map(|v| format!(",{},", v))
+ .map(|v| v.split(',').map(|x| x.to_string()).collect())
.unwrap_or_default();
let enable_cors = matches.is_present("enable-cors");
let auth: Vec<&str> = matches
use crate::streamer::Streamer;
-use crate::utils::{decode_uri, encode_uri, get_file_name, try_get_file_name};
+use crate::utils::{decode_uri, encode_uri, get_file_name, glob, try_get_file_name};
use crate::{Args, BoxResult};
use walkdir::WalkDir;
use xml::escape::escape_str_pcdata;
) -> BoxResult<()> {
let mut paths: Vec<PathItem> = vec![];
let path_buf = path.to_path_buf();
- let hidden = self.args.hidden.to_string();
+ let hidden = Arc::new(self.args.hidden.to_vec());
+ let hidden = hidden.clone();
let running = self.running.clone();
let search = search.to_lowercase();
let search_paths = tokio::task::spawn_blocking(move || {
async fn zip_dir<W: AsyncWrite + Unpin>(
writer: &mut W,
dir: &Path,
- hidden: &str,
+ hidden: &[String],
running: Arc<AtomicBool>,
) -> BoxResult<()> {
let mut writer = ZipFileWriter::new(writer);
- let hidden = Arc::new(hidden.to_string());
- let hidden = hidden.to_string();
+ let hidden = Arc::new(hidden.to_vec());
+ let hidden = hidden.clone();
let dir_path_buf = dir.to_path_buf();
let zip_paths = tokio::task::spawn_blocking(move || {
let mut it = WalkDir::new(&dir_path_buf).into_iter();
*res.status_mut() = StatusCode::NO_CONTENT;
}
-fn is_hidden(hidden: &str, file_name: &str) -> bool {
- hidden.contains(&format!(",{},", file_name))
+fn is_hidden(hidden: &[String], file_name: &str) -> bool {
+ hidden.iter().any(|v| glob(v, file_name))
}
fn set_webdav_headers(res: &mut Response) {
.and_then(|v| v.to_str())
.ok_or_else(|| format!("Failed to get file name of `{}`", path.display()).into())
}
+
+pub fn glob(source: &str, target: &str) -> bool {
+ let ss: Vec<char> = source.chars().collect();
+ let mut iter = target.chars();
+ let mut i = 0;
+ 'outer: while i < ss.len() {
+ let s = ss[i];
+ match s {
+ '*' => match ss.get(i + 1) {
+ Some(s_next) => {
+ for t in iter.by_ref() {
+ if t == *s_next {
+ i += 2;
+ continue 'outer;
+ }
+ }
+ return true;
+ }
+ None => return true,
+ },
+ '?' => match iter.next() {
+ Some(_) => {
+ i += 1;
+ continue;
+ }
+ None => return false,
+ },
+ _ => match iter.next() {
+ Some(t) => {
+ if s == t {
+ i += 1;
+ continue;
+ }
+ return false;
+ }
+ None => return false,
+ },
+ }
+ }
+ iter.next().is_none()
+}
+
+#[test]
+fn test_glob_key() {
+ assert!(glob("", ""));
+ assert!(glob(".*", ".git"));
+ assert!(glob("abc", "abc"));
+ assert!(glob("a*c", "abc"));
+ assert!(glob("a?c", "abc"));
+ assert!(glob("a*c", "abbc"));
+ assert!(glob("*c", "abc"));
+ assert!(glob("a*", "abc"));
+ assert!(glob("?c", "bc"));
+ assert!(glob("a?", "ab"));
+ assert!(!glob("abc", "adc"));
+ assert!(!glob("abc", "abcd"));
+ assert!(!glob("a?c", "abbc"));
+}