ferron/util/
match_hostname.rs

1// Hostname matching function from SVR.JS rewritten from JavaScript to Rust
2pub fn match_hostname(hostname: Option<&str>, req_hostname: Option<&str>) -> bool {
3  if hostname.is_none() || hostname == Some("*") {
4    return true;
5  }
6
7  if let (Some(hostname), Some(req_hostname)) = (hostname, req_hostname) {
8    if hostname.starts_with("*.") && hostname != "*." {
9      let hostnames_root = &hostname[2..];
10      if req_hostname == hostnames_root
11        || (req_hostname.len() > hostnames_root.len()
12          && req_hostname.ends_with(&format!(".{}", hostnames_root)[..]))
13      {
14        return true;
15      }
16    } else if req_hostname == hostname {
17      return true;
18    }
19  }
20
21  false
22}
23
24#[cfg(test)]
25mod tests {
26  use super::*;
27
28  #[test]
29  fn should_return_true_if_hostname_is_undefined() {
30    assert!(match_hostname(None, Some("example.com")));
31  }
32
33  #[test]
34  fn should_return_true_if_hostname_is_star() {
35    assert!(match_hostname(Some("*"), Some("example.com")));
36  }
37
38  #[test]
39  fn should_return_true_if_req_hostname_matches_hostname_exactly() {
40    assert!(match_hostname(Some("example.com"), Some("example.com")));
41  }
42
43  #[test]
44  fn should_return_false_if_req_hostname_does_not_match_hostname_exactly() {
45    assert!(!match_hostname(Some("example.com"), Some("example.org")));
46  }
47
48  #[test]
49  fn should_return_true_if_hostname_starts_with_star_dot_and_req_hostname_matches_the_root() {
50    assert!(match_hostname(
51      Some("*.example.com"),
52      Some("sub.example.com")
53    ));
54  }
55
56  #[test]
57  fn should_return_false_if_hostname_starts_with_star_dot_and_req_hostname_does_not_match_the_root()
58  {
59    assert!(!match_hostname(Some("*.example.com"), Some("example.org")));
60  }
61
62  #[test]
63  fn should_return_true_if_hostname_starts_with_star_dot_and_req_hostname_is_the_root() {
64    assert!(match_hostname(Some("*.example.com"), Some("example.com")));
65  }
66
67  #[test]
68  fn should_return_false_if_hostname_is_star_dot() {
69    assert!(!match_hostname(Some("*."), Some("example.com")));
70  }
71
72  #[test]
73  fn should_return_false_if_req_hostname_is_undefined() {
74    assert!(!match_hostname(Some("example.com"), None));
75  }
76
77  #[test]
78  fn should_return_false_if_hostname_does_not_start_with_star_dot_and_req_hostname_does_not_match()
79  {
80    assert!(!match_hostname(
81      Some("sub.example.com"),
82      Some("example.com")
83    ));
84  }
85
86  #[test]
87  fn should_return_true_if_hostname_starts_with_star_dot_and_req_hostname_matches_the_root_with_additional_subdomains(
88  ) {
89    assert!(match_hostname(
90      Some("*.example.com"),
91      Some("sub.sub.example.com")
92    ));
93  }
94
95  #[test]
96  fn should_return_false_if_hostname_starts_with_star_dot_and_req_hostname_does_not_match_the_root_with_additional_subdomains(
97  ) {
98    assert!(!match_hostname(
99      Some("*.example.com"),
100      Some("sub.sub.example.org")
101    ));
102  }
103}