1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use std::fs::metadata;
use std::path::PathBuf;
const INDEX_FILES: [&'static str; 3] = ["index.html", "index.htm", "index.php"];
pub struct LocatedPath {
pub path: PathBuf,
pub was_redirected: bool,
}
pub fn try_find_path(directory: &str, request_path: &str) -> Option<LocatedPath> {
if request_path.contains("..") || request_path.contains(":") {
return None;
}
let request_path = request_path.trim_start_matches("/");
let directory = directory.trim_end_matches("/");
let mut paths: Vec<String> = INDEX_FILES
.iter()
.map(|s| format!("{}/{}/{}", directory, request_path, s))
.collect();
paths.insert(0, format!("{}/{}", directory, request_path));
for (index, path) in paths.iter().enumerate() {
if let Ok(meta) = metadata(path) {
if meta.is_file() {
return Some(LocatedPath {
path: PathBuf::from(path).canonicalize().unwrap(),
was_redirected: index != 0,
});
}
}
}
None
}