Skip to content

Commit b5e9983

Browse files
committed
WIP: parse multiple occurences of headers
1 parent 0e5fb5f commit b5e9983

File tree

3 files changed

+168
-29
lines changed

3 files changed

+168
-29
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

header-plz/src/body_headers/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use content_encoding::ContentEncoding;
22
use mime_plz::ContentType;
33
use transfer_types::TransferType;
4+
mod encoding_struct;
45

56
pub mod content_encoding;
67
pub mod transfer_types;

header-plz/src/header_map/mod.rs

Lines changed: 166 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ impl HeaderMap {
4343
}
4444

4545
// Entire header
46-
pub fn find_header_pos(&self, to_find: &str) -> Option<usize> {
47-
let (key, val) = to_find
46+
pub fn header_position(&self, to_find_hdr: &str) -> Option<usize> {
47+
let (key, val) = to_find_hdr
4848
.split_once(COLON)
4949
.map(|(k, v)| (k, v.trim()))
5050
.unwrap_or_default();
@@ -53,44 +53,105 @@ impl HeaderMap {
5353
.position(|h| h.key_as_str() == key && h.value_as_str() == val)
5454
}
5555

56+
pub fn header_position_all(&self, to_find_hdr: &str) -> Option<Vec<usize>> {
57+
let (key, val) = to_find_hdr
58+
.split_once(COLON)
59+
.map(|(k, v)| (k, v.trim()))
60+
.unwrap_or_default();
61+
let pos: Vec<usize> = self
62+
.headers
63+
.iter()
64+
.enumerate()
65+
.filter_map(|(i, h)| {
66+
if h.key_as_str() == key && h.value_as_str() == val {
67+
Some(i)
68+
} else {
69+
None
70+
}
71+
})
72+
.collect();
73+
74+
Some(pos).filter(|v| !v.is_empty())
75+
}
76+
5677
// old : Content-Length: 20
5778
// new : Content-Length: 10
5879
pub fn change_header(&mut self, old: &str, new: &str) -> bool {
59-
if let Some(index) = self.find_header_pos(old) {
80+
let mut result = false;
81+
if let Some(position) = self.header_position(old) {
82+
result = true;
6083
let (new_key, new_val) = new
6184
.split_once(COLON)
6285
.map(|(k, v)| (k, v.trim()))
6386
.unwrap_or_default();
64-
self.headers[index].change_key(new_key);
65-
self.headers[index].change_value(new_val);
66-
return true;
87+
self.headers[position].change_key(new_key);
88+
self.headers[position].change_value(new_val);
6789
}
68-
false
90+
result
91+
}
92+
93+
pub fn change_header_all(&mut self, old: &str, new: &str) -> bool {
94+
let mut result = false;
95+
if let Some(positions) = self.header_position_all(old) {
96+
result = true;
97+
let (new_key, new_val) = new
98+
.split_once(COLON)
99+
.map(|(k, v)| (k, v.trim()))
100+
.unwrap_or_default();
101+
for index in positions {
102+
self.headers[index].change_key(new_key);
103+
self.headers[index].change_value(new_val);
104+
}
105+
}
106+
result
107+
}
108+
109+
// Content-Length: 10
110+
pub fn remove_header_all(&mut self, to_remove: &str) -> bool {
111+
let mut result = false;
112+
if let Some(positions) = self.header_position_all(to_remove) {
113+
result = true;
114+
for index in positions.into_iter().rev() {
115+
self.headers.remove(index);
116+
}
117+
}
118+
result
69119
}
70120

71121
pub fn remove_header(&mut self, to_remove: &str) -> bool {
72-
if let Some(index) = self.find_header_pos(to_remove) {
73-
self.headers.remove(index);
74-
return true;
122+
let mut result = false;
123+
if let Some(position) = self.header_position(to_remove) {
124+
result = true;
125+
self.headers.remove(position);
75126
}
76-
false
127+
result
77128
}
78129

79130
pub fn add_header(&mut self, header: Header) {
80131
self.headers.push(header);
81132
}
82133

83-
pub fn remove_header_on_pos(&mut self, pos: usize) {
134+
pub fn remove_header_on_position(&mut self, pos: usize) {
84135
self.headers.remove(pos);
85136
}
86137

87138
// Key
88-
pub fn has_header_key(&self, key: &str) -> Option<usize> {
139+
pub fn header_key_position(&self, key: &str) -> Option<usize> {
89140
self.headers
90141
.iter()
91142
.position(|header| header.key_as_str().eq_ignore_ascii_case(key))
92143
}
93144

145+
pub fn header_key_position_all(&self, key: &str) -> Option<Vec<usize>> {
146+
let pos: Vec<usize> = self
147+
.headers
148+
.iter()
149+
.enumerate()
150+
.filter_map(|(i, h)| if h.key_as_str() == key { Some(i) } else { None })
151+
.collect();
152+
Some(pos).filter(|v| !v.is_empty())
153+
}
154+
94155
pub fn change_header_key(&mut self, old_key: &str, new_key: &str) -> bool {
95156
for h in self.headers.iter_mut() {
96157
if h.key_as_str().eq_ignore_ascii_case(old_key) {
@@ -101,6 +162,17 @@ impl HeaderMap {
101162
false
102163
}
103164

165+
pub fn change_header_key_all(&mut self, old_key: &str, new_key: &str) -> bool {
166+
let mut result = false;
167+
if let Some(positions) = self.header_key_position_all(old_key) {
168+
result = true;
169+
for index in positions {
170+
self.headers[index].change_key(new_key);
171+
}
172+
}
173+
result
174+
}
175+
104176
pub fn remove_header_on_key(&mut self, key: &str) -> bool {
105177
for (index, h) in self.headers.iter().enumerate() {
106178
if h.key_as_str().eq_ignore_ascii_case(key) {
@@ -111,6 +183,17 @@ impl HeaderMap {
111183
false
112184
}
113185

186+
pub fn remove_header_on_key_all(&mut self, key: &str) -> bool {
187+
let mut result = false;
188+
if let Some(positions) = self.header_key_position_all(key) {
189+
result = true;
190+
for index in positions.into_iter().rev() {
191+
self.headers.remove(index);
192+
}
193+
}
194+
result
195+
}
196+
114197
// Value
115198
pub fn change_header_value_on_key(&mut self, key: &str, value: &str) -> bool {
116199
for h in self.headers.iter_mut() {
@@ -140,7 +223,7 @@ impl HeaderMap {
140223
T: AsRef<str>,
141224
E: IntoIterator<Item = T>,
142225
{
143-
let Some(pos) = self.has_header_key(key) else {
226+
let Some(pos) = self.header_key_position(key) else {
144227
return;
145228
};
146229

@@ -197,23 +280,37 @@ mod tests {
197280

198281
use super::*;
199282

283+
//..........Entire Header
284+
// find_header_pos
200285
#[test]
201-
fn test_header_map_has_header_key() {
202-
let raw_header: BytesMut = "Content-Length: 20\r\n\r\n".into();
203-
let map = HeaderMap::from(raw_header);
204-
let key = "Content-Length";
205-
let result = map.has_header_key(key);
206-
assert_eq!(result, Some(0));
286+
fn test_header_map_find_header_pos_single() {
287+
let input = "Content-Length: 20\r\n\r\n";
288+
let map = HeaderMap::from(BytesMut::from(input));
289+
let key = "Content-Length: 20";
290+
let result = map.header_position_all(key);
291+
assert_eq!(result, Some(vec![0]));
207292
}
208293

209294
#[test]
210-
fn test_header_map_change_header() {
295+
fn test_header_map_find_header_pos_multiple() {
296+
let input = "Content-Length: 20\r\n\
297+
Content-Type: application/json\r\n\
298+
Content-Length: 20\r\n\r\n";
299+
let map = HeaderMap::from(BytesMut::from(input));
300+
let key = "Content-Length: 20";
301+
let result = map.header_position_all(key);
302+
assert_eq!(result, Some(vec![0, 2]));
303+
}
304+
305+
// change_header
306+
#[test]
307+
fn test_header_map_change_header_single() {
211308
let input: BytesMut = "Content-Length: 20\r\n\r\n".into();
212309
let input_range = input.as_ptr_range();
213310
let mut map = HeaderMap::from(input);
214311
let old = "Content-Length: 20";
215312
let new = "Content-Length: 10";
216-
let result = map.change_header(old, new);
313+
let result = map.change_header_all(old, new);
217314
assert!(result);
218315
let val = map.into_bytes();
219316
let verify = "Content-Length: 10\r\n\r\n";
@@ -222,14 +319,32 @@ mod tests {
222319
assert_eq!(input_range, result_range);
223320
}
224321

322+
#[test]
323+
fn test_header_map_change_header_multiple() {
324+
let input = "Content-Length: 20\r\n\
325+
Content-Type: application/json\r\n\
326+
Content-Length: 20\r\n\r\n";
327+
let mut map = HeaderMap::from(BytesMut::from(input));
328+
let old = "Content-Length: 20";
329+
let new = "Content-Length: 10";
330+
let result = map.change_header_all(old, new);
331+
assert!(result);
332+
let val = map.into_bytes();
333+
let verify = "Content-Length: 10\r\n\
334+
Content-Type: application/json\r\n\
335+
Content-Length: 10\r\n\r\n";
336+
assert_eq!(val, verify);
337+
}
338+
339+
// remove header
225340
#[test]
226341
fn test_header_map_remove_header_first() {
227342
let raw_header: BytesMut = "Content-Type: application/json\r\n\
228-
Content-Length: 20\r\n\r\n"
343+
Content-Length: 20\r\n\r\n"
229344
.into();
230345
let mut map = HeaderMap::from(raw_header);
231346
let to_remove = "Content-Length: 20";
232-
let result = map.remove_header(to_remove);
347+
let result = map.remove_header_all(to_remove);
233348
assert!(result);
234349
let val = map.into_bytes();
235350
let verify = "Content-Type: application/json\r\n\r\n";
@@ -238,18 +353,40 @@ mod tests {
238353

239354
#[test]
240355
fn test_header_map_remove_header_second() {
241-
let raw_header: BytesMut = "Content-Type: application/json\r\n\
242-
Content-Length: 20\r\n\r\n"
243-
.into();
244-
let mut map = HeaderMap::from(raw_header);
356+
let input = "Content-Type: application/json\r\n\
357+
Content-Length: 20\r\n\r\n";
358+
let mut map = HeaderMap::from(BytesMut::from(input));
359+
let to_remove = "Content-Type: application/json";
360+
let result = map.remove_header_all(to_remove);
361+
assert!(result);
362+
let val = map.into_bytes();
363+
let verify = "Content-Length: 20\r\n\r\n";
364+
assert_eq!(val, verify);
365+
}
366+
367+
#[test]
368+
fn test_header_map_remove_header_multiple() {
369+
let input = "Content-Type: application/json\r\n\
370+
Content-Length: 20\r\n\
371+
Content-Type: application/json\r\n\r\n";
372+
let mut map = HeaderMap::from(BytesMut::from(input));
245373
let to_remove = "Content-Type: application/json";
246-
let result = map.remove_header(to_remove);
374+
let result = map.remove_header_all(to_remove);
247375
assert!(result);
248376
let val = map.into_bytes();
249377
let verify = "Content-Length: 20\r\n\r\n";
250378
assert_eq!(val, verify);
251379
}
252380

381+
#[test]
382+
fn test_header_map_has_header_key() {
383+
let raw_header: BytesMut = "Content-Length: 20\r\n\r\n".into();
384+
let map = HeaderMap::from(raw_header);
385+
let key = "Content-Length";
386+
let result = map.header_key_position(key);
387+
assert_eq!(result, Some(0));
388+
}
389+
253390
#[test]
254391
fn test_header_map_change_header_key() {
255392
let raw_header: BytesMut = "Content-Length: 20\r\n\r\n".into();

0 commit comments

Comments
 (0)