1
2use std::collections::HashMap;
3
4#[derive(Clone, Debug)]
5pub struct HttpHeaders {
6 pairs: HashMap<String, Vec<String>>,
7 lower_map: HashMap<String, String>,
8}
9
10
11impl HttpHeaders {
12 pub fn new() -> Self {
14 Self {
15 pairs: HashMap::new(),
16 lower_map: HashMap::new(),
17 }
18 }
19
20 pub fn from_vec(header_lines: &Vec<String>) -> Self {
22 let mut pairs: HashMap<String, Vec<String>> = HashMap::new();
24 let mut lower_map: HashMap<String, String> = HashMap::new();
25
26 for line in header_lines {
28 if let Some(cindex) = line.find(':') {
29 let key = line[..cindex].to_string();
30 pairs
31 .entry(key.clone())
32 .or_default()
33 .push(line[cindex + 1..].trim().to_string());
34 lower_map.insert(key.to_lowercase(), key);
35 }
36 }
37
38 Self { pairs, lower_map }
39 }
40
41 pub fn from_hash(headers: &HashMap<&str, &str>) -> Self {
43 let pairs: HashMap<String, Vec<String>> = headers
44 .iter()
45 .map(|(k, v)| {
46 let value: Vec<String> = v.split(';').map(|e| e.trim().to_string()).collect();
47 (k.to_string(), value)
48 })
49 .collect();
50
51 let lower_map: HashMap<String, String> = headers
52 .keys()
53 .map(|k| (k.to_lowercase().to_string(), k.to_string()))
54 .collect();
55
56 Self { pairs, lower_map }
57 }
58
59 pub fn has(&self, key: &str) -> bool {
61 self.pairs.contains_key(&key.to_string())
62 }
63
64 pub fn has_lower(&self, key: &str) -> bool {
66 if let Some(hdr_key) = self.lower_map.get(key.to_lowercase().as_str()) {
67 return self.has(hdr_key);
68 }
69 false
70 }
71
72 pub fn get(&self, key: &str) -> Option<String> {
75 self.pairs.get(key).and_then(|val| val.get(0)).cloned()
76 }
77
78 pub fn get_lower(&self, key: &str) -> Option<String> {
80 if let Some(hdr_key) = self.lower_map.get(key.to_lowercase().as_str()) {
81 return self.get(hdr_key);
82 }
83 None
84 }
85
86 pub fn get_vec(&self, key: &str) -> Vec<String> {
88 if let Some(values) = self.pairs.get(key) {
89 return values.clone();
90 }
91 vec![]
92 }
93
94 pub fn get_lower_vec(&self, key: &str) -> Vec<String> {
96 if let Some(hdr_key) = self.lower_map.get(key.to_lowercase().as_str()) {
97 return self.get_vec(hdr_key);
98 }
99 vec![]
100 }
101
102 pub fn get_line(&self, key: &str) -> Option<String> {
104 if let Some(val) = self.pairs.get(key) {
105 return Some(val.join("; "));
106 }
107 None
108 }
109
110 pub fn get_lower_line(&self, key: &str) -> Option<String> {
112 if let Some(hdr_key) = self.lower_map.get(key.to_lowercase().as_str()) {
113 return self.get_line(hdr_key);
114 }
115 None
116 }
117
118 pub fn all(&self) -> HashMap<String, Vec<String>> {
120 self.pairs.clone()
121 }
122
123 pub fn set(&mut self, key: &str, value: &str) {
125 let val = vec![value.to_string()];
126 *self.pairs.entry(key.to_string()).or_insert(val) = val.clone();
127 *self
128 .lower_map
129 .entry(key.to_lowercase().to_string())
130 .or_insert(key.to_string()) = key.to_string();
131 }
132
133 pub fn set_vec(&mut self, key: &str, value: &Vec<&str>) {
135 let val = value.iter().map(|s| s.to_string()).collect();
136 *self.pairs.entry(key.to_string()).or_insert(val) = val.clone();
137 *self
138 .lower_map
139 .entry(key.to_lowercase().to_string())
140 .or_insert(key.to_string()) = key.to_string();
141 }
142
143 pub fn add(&mut self, key: &str, value: &str) {
145 self.pairs
146 .entry(key.to_string())
147 .or_default()
148 .push(value.to_string());
149 *self
150 .lower_map
151 .entry(key.to_lowercase().to_string())
152 .or_insert(key.to_string()) = key.to_string();
153 }
154
155 pub fn delete(&mut self, key: &str) {
157 self.lower_map.remove(&key.to_lowercase().to_string());
158 self.pairs.remove(&key.to_string());
159 }
160
161 pub fn clear(&mut self) {
163 self.pairs.clear();
164 self.lower_map.clear();
165 }
166}