herolib_crypt/httpsig/
components.rs1use crate::httpsig::error::HttpSigError;
6
7pub fn extract_authority(host: &str) -> String {
24 let lowercase = host.to_lowercase();
25
26 if lowercase.ends_with(":80") {
28 lowercase[..lowercase.len() - 3].to_string()
29 } else if lowercase.ends_with(":443") {
30 lowercase[..lowercase.len() - 4].to_string()
31 } else {
32 lowercase
33 }
34}
35
36pub fn extract_method(method: &str) -> String {
40 method.to_uppercase()
41}
42
43pub fn extract_path(path: &str) -> Result<String, HttpSigError> {
47 if !path.starts_with('/') {
48 return Err(HttpSigError::ParseError(format!(
49 "Path must start with '/': {}",
50 path
51 )));
52 }
53
54 Ok(path.to_string())
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn test_extract_authority_simple() {
63 assert_eq!(extract_authority("example.com"), "example.com");
64 }
65
66 #[test]
67 fn test_extract_authority_lowercase() {
68 assert_eq!(extract_authority("EXAMPLE.COM"), "example.com");
69 assert_eq!(extract_authority("Example.Com"), "example.com");
70 }
71
72 #[test]
73 fn test_extract_authority_default_ports() {
74 assert_eq!(extract_authority("example.com:80"), "example.com");
75 assert_eq!(extract_authority("example.com:443"), "example.com");
76 }
77
78 #[test]
79 fn test_extract_authority_custom_port() {
80 assert_eq!(extract_authority("example.com:8080"), "example.com:8080");
81 assert_eq!(extract_authority("example.com:3000"), "example.com:3000");
82 }
83
84 #[test]
85 fn test_extract_method() {
86 assert_eq!(extract_method("get"), "GET");
87 assert_eq!(extract_method("post"), "POST");
88 assert_eq!(extract_method("POST"), "POST");
89 }
90
91 #[test]
92 fn test_extract_path_valid() {
93 assert_eq!(extract_path("/api/v1/users").unwrap(), "/api/v1/users");
94 assert_eq!(extract_path("/").unwrap(), "/");
95 }
96
97 #[test]
98 fn test_extract_path_invalid() {
99 let result = extract_path("api/v1/users");
100 assert!(matches!(result, Err(HttpSigError::ParseError(_))));
101 }
102}