File size: 1,873 Bytes
9552aa0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
pub fn match_location(path: &str, req_path: &str) -> bool {
  let mut path_without_trailing_slashes = path;
  while path_without_trailing_slashes.ends_with("/") {
    path_without_trailing_slashes =
      &path_without_trailing_slashes[..(path_without_trailing_slashes.len() - 1)];
  }

  let mut path_prepared = path_without_trailing_slashes.to_owned();
  let mut req_path_prepared = req_path.to_owned();

  while path_prepared.contains("//") {
    path_prepared = path_prepared.replace("//", "/");
  }

  while req_path_prepared.contains("//") {
    req_path_prepared = path_prepared.replace("//", "/");
  }

  if cfg!(windows) {
    path_prepared = path_prepared.to_lowercase();
    req_path_prepared = req_path_prepared.to_lowercase();
  }

  path_prepared == req_path_prepared
    || req_path_prepared.starts_with(&format!("{}/", path_prepared))
}

#[cfg(test)]
mod tests {
  use super::match_location;

  #[test]
  fn test_exact_match() {
    assert!(match_location("/home", "/home"));
    assert!(match_location("/api/v1", "/api/v1"));
  }

  #[test]
  fn test_trailing_slash() {
    assert!(match_location("/home/", "/home"));
    assert!(match_location("/home", "/home/"));
    assert!(match_location("/api/v1/", "/api/v1"));
  }

  #[test]
  fn test_subpath_match() {
    assert!(match_location("/api", "/api/v1"));
    assert!(match_location("/users", "/users/profile"));
  }

  #[test]
  fn test_non_matching_paths() {
    assert!(!match_location("/home", "/dashboard"));
    assert!(!match_location("/api", "/user"));
  }

  #[test]
  fn test_multiple_slashes() {
    assert!(match_location("/api//v1", "/api/v1"));
    assert!(match_location("//home///", "/home"));
  }

  #[test]
  fn test_case_insensitivity_on_windows() {
    #[cfg(windows)]
    {
      assert!(match_location("/API", "/api"));
      assert!(match_location("/Home", "/home"));
    }
  }
}