@@ -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