1 | use http::header::*; |
2 | use http::*; |
3 | |
4 | #[test] |
5 | fn smoke() { |
6 | let mut headers = HeaderMap::new(); |
7 | |
8 | assert!(headers.get("hello" ).is_none()); |
9 | |
10 | let name: HeaderName = "hello" .parse().unwrap(); |
11 | |
12 | match headers.entry(&name) { |
13 | Entry::Vacant(e) => { |
14 | e.insert("world" .parse().unwrap()); |
15 | } |
16 | _ => panic!(), |
17 | } |
18 | |
19 | assert!(headers.get("hello" ).is_some()); |
20 | |
21 | match headers.entry(&name) { |
22 | Entry::Occupied(mut e) => { |
23 | assert_eq!(e.get(), &"world" ); |
24 | |
25 | // Push another value |
26 | e.append("zomg" .parse().unwrap()); |
27 | |
28 | let mut i = e.iter(); |
29 | |
30 | assert_eq!(*i.next().unwrap(), "world" ); |
31 | assert_eq!(*i.next().unwrap(), "zomg" ); |
32 | assert!(i.next().is_none()); |
33 | } |
34 | _ => panic!(), |
35 | } |
36 | } |
37 | |
38 | #[test] |
39 | #[should_panic ] |
40 | fn reserve_over_capacity() { |
41 | // See https://github.com/hyperium/http/issues/352 |
42 | let mut headers = HeaderMap::<u32>::with_capacity(32); |
43 | headers.reserve(50_000); // over MAX_SIZE |
44 | } |
45 | |
46 | #[test] |
47 | fn with_capacity_max() { |
48 | // The largest capacity such that (cap + cap / 3) < MAX_SIZE. |
49 | HeaderMap::<u32>::with_capacity(24_576); |
50 | } |
51 | |
52 | #[test] |
53 | #[should_panic ] |
54 | fn with_capacity_overflow() { |
55 | HeaderMap::<u32>::with_capacity(24_577); |
56 | } |
57 | |
58 | #[test] |
59 | #[should_panic ] |
60 | fn reserve_overflow() { |
61 | // See https://github.com/hyperium/http/issues/352 |
62 | let mut headers = HeaderMap::<u32>::with_capacity(0); |
63 | headers.reserve(std::usize::MAX); // next_power_of_two overflows |
64 | } |
65 | |
66 | #[test] |
67 | fn drain() { |
68 | let mut headers = HeaderMap::new(); |
69 | |
70 | // Insert a single value |
71 | let name: HeaderName = "hello" .parse().unwrap(); |
72 | headers.insert(name, "world" .parse().unwrap()); |
73 | |
74 | { |
75 | let mut iter = headers.drain(); |
76 | let (name, value) = iter.next().unwrap(); |
77 | assert_eq!(name.unwrap().as_str(), "hello" ); |
78 | |
79 | assert_eq!(value, "world" ); |
80 | |
81 | assert!(iter.next().is_none()); |
82 | } |
83 | |
84 | assert!(headers.is_empty()); |
85 | |
86 | // Insert two sequential values |
87 | headers.insert( |
88 | "hello" .parse::<HeaderName>().unwrap(), |
89 | "world" .parse().unwrap(), |
90 | ); |
91 | headers.insert( |
92 | "zomg" .parse::<HeaderName>().unwrap(), |
93 | "bar" .parse().unwrap(), |
94 | ); |
95 | headers.append( |
96 | "hello" .parse::<HeaderName>().unwrap(), |
97 | "world2" .parse().unwrap(), |
98 | ); |
99 | |
100 | // Drain... |
101 | { |
102 | let mut iter = headers.drain(); |
103 | |
104 | let (name, value) = iter.next().unwrap(); |
105 | assert_eq!(name.unwrap().as_str(), "hello" ); |
106 | assert_eq!(value, "world" ); |
107 | |
108 | let (name, value) = iter.next().unwrap(); |
109 | assert_eq!(name, None); |
110 | assert_eq!(value, "world2" ); |
111 | |
112 | let (name, value) = iter.next().unwrap(); |
113 | assert_eq!(name.unwrap().as_str(), "zomg" ); |
114 | assert_eq!(value, "bar" ); |
115 | |
116 | assert!(iter.next().is_none()); |
117 | } |
118 | } |
119 | |
120 | #[test] |
121 | fn drain_drop_immediately() { |
122 | // test mem::forgetting does not double-free |
123 | |
124 | let mut headers = HeaderMap::new(); |
125 | headers.insert("hello" , "world" .parse().unwrap()); |
126 | headers.insert("zomg" , "bar" .parse().unwrap()); |
127 | headers.append("hello" , "world2" .parse().unwrap()); |
128 | |
129 | let iter = headers.drain(); |
130 | assert_eq!(iter.size_hint(), (2, Some(3))); |
131 | // not consuming `iter` |
132 | } |
133 | |
134 | #[test] |
135 | fn drain_forget() { |
136 | // test mem::forgetting does not double-free |
137 | |
138 | let mut headers = HeaderMap::<HeaderValue>::new(); |
139 | headers.insert("hello" , "world" .parse().unwrap()); |
140 | headers.insert("zomg" , "bar" .parse().unwrap()); |
141 | |
142 | assert_eq!(headers.len(), 2); |
143 | |
144 | { |
145 | let mut iter = headers.drain(); |
146 | assert_eq!(iter.size_hint(), (2, Some(2))); |
147 | let _ = iter.next().unwrap(); |
148 | std::mem::forget(iter); |
149 | } |
150 | |
151 | assert_eq!(headers.len(), 0); |
152 | } |
153 | |
154 | #[test] |
155 | fn drain_entry() { |
156 | let mut headers = HeaderMap::new(); |
157 | |
158 | headers.insert( |
159 | "hello" .parse::<HeaderName>().unwrap(), |
160 | "world" .parse().unwrap(), |
161 | ); |
162 | headers.insert( |
163 | "zomg" .parse::<HeaderName>().unwrap(), |
164 | "foo" .parse().unwrap(), |
165 | ); |
166 | headers.append( |
167 | "hello" .parse::<HeaderName>().unwrap(), |
168 | "world2" .parse().unwrap(), |
169 | ); |
170 | headers.insert( |
171 | "more" .parse::<HeaderName>().unwrap(), |
172 | "words" .parse().unwrap(), |
173 | ); |
174 | headers.append( |
175 | "more" .parse::<HeaderName>().unwrap(), |
176 | "insertions" .parse().unwrap(), |
177 | ); |
178 | assert_eq!(5, headers.len()); |
179 | |
180 | // Using insert_mult |
181 | { |
182 | let mut e = match headers.entry("hello" ) { |
183 | Entry::Occupied(e) => e, |
184 | _ => panic!(), |
185 | }; |
186 | |
187 | let vals: Vec<_> = e.insert_mult("wat" .parse().unwrap()).collect(); |
188 | assert_eq!(2, vals.len()); |
189 | assert_eq!(vals[0], "world" ); |
190 | assert_eq!(vals[1], "world2" ); |
191 | } |
192 | |
193 | assert_eq!(5-2+1, headers.len()); |
194 | } |
195 | |
196 | #[test] |
197 | fn eq() { |
198 | let mut a = HeaderMap::new(); |
199 | let mut b = HeaderMap::new(); |
200 | |
201 | assert_eq!(a, b); |
202 | |
203 | a.insert( |
204 | "hello" .parse::<HeaderName>().unwrap(), |
205 | "world" .parse().unwrap(), |
206 | ); |
207 | assert_ne!(a, b); |
208 | |
209 | b.insert( |
210 | "hello" .parse::<HeaderName>().unwrap(), |
211 | "world" .parse().unwrap(), |
212 | ); |
213 | assert_eq!(a, b); |
214 | |
215 | a.insert("foo" .parse::<HeaderName>().unwrap(), "bar" .parse().unwrap()); |
216 | a.append("foo" .parse::<HeaderName>().unwrap(), "baz" .parse().unwrap()); |
217 | assert_ne!(a, b); |
218 | |
219 | b.insert("foo" .parse::<HeaderName>().unwrap(), "bar" .parse().unwrap()); |
220 | assert_ne!(a, b); |
221 | |
222 | b.append("foo" .parse::<HeaderName>().unwrap(), "baz" .parse().unwrap()); |
223 | assert_eq!(a, b); |
224 | |
225 | a.append("a" .parse::<HeaderName>().unwrap(), "a" .parse().unwrap()); |
226 | a.append("a" .parse::<HeaderName>().unwrap(), "b" .parse().unwrap()); |
227 | b.append("a" .parse::<HeaderName>().unwrap(), "b" .parse().unwrap()); |
228 | b.append("a" .parse::<HeaderName>().unwrap(), "a" .parse().unwrap()); |
229 | |
230 | assert_ne!(a, b); |
231 | } |
232 | |
233 | #[test] |
234 | fn into_header_name() { |
235 | let mut m = HeaderMap::new(); |
236 | m.insert(HOST, "localhost" .parse().unwrap()); |
237 | m.insert(&ACCEPT, "*/*" .parse().unwrap()); |
238 | m.insert("connection" , "keep-alive" .parse().unwrap()); |
239 | |
240 | m.append(LOCATION, "/" .parse().unwrap()); |
241 | m.append(&VIA, "bob" .parse().unwrap()); |
242 | m.append("transfer-encoding" , "chunked" .parse().unwrap()); |
243 | |
244 | assert_eq!(m.len(), 6); |
245 | } |
246 | |
247 | #[test] |
248 | fn as_header_name() { |
249 | let mut m = HeaderMap::new(); |
250 | let v: HeaderValue = "localhost" .parse().unwrap(); |
251 | m.insert(HOST, v.clone()); |
252 | |
253 | let expected = Some(&v); |
254 | |
255 | assert_eq!(m.get("host" ), expected); |
256 | assert_eq!(m.get(&HOST), expected); |
257 | |
258 | let s = String::from("host" ); |
259 | assert_eq!(m.get(&s), expected); |
260 | assert_eq!(m.get(s.as_str()), expected); |
261 | } |
262 | |
263 | #[test] |
264 | fn insert_all_std_headers() { |
265 | let mut m = HeaderMap::new(); |
266 | |
267 | for (i, hdr) in STD.iter().enumerate() { |
268 | m.insert(hdr.clone(), hdr.as_str().parse().unwrap()); |
269 | |
270 | for j in 0..(i + 1) { |
271 | assert_eq!(m[&STD[j]], STD[j].as_str()); |
272 | } |
273 | |
274 | if i != 0 { |
275 | for j in (i + 1)..STD.len() { |
276 | assert!( |
277 | m.get(&STD[j]).is_none(), |
278 | "contained {}; j={}" , |
279 | STD[j].as_str(), |
280 | j |
281 | ); |
282 | } |
283 | } |
284 | } |
285 | } |
286 | |
287 | #[test] |
288 | fn insert_79_custom_std_headers() { |
289 | let mut h = HeaderMap::new(); |
290 | let hdrs = custom_std(79); |
291 | |
292 | for (i, hdr) in hdrs.iter().enumerate() { |
293 | h.insert(hdr.clone(), hdr.as_str().parse().unwrap()); |
294 | |
295 | for j in 0..(i + 1) { |
296 | assert_eq!(h[&hdrs[j]], hdrs[j].as_str()); |
297 | } |
298 | |
299 | for j in (i + 1)..hdrs.len() { |
300 | assert!(h.get(&hdrs[j]).is_none()); |
301 | } |
302 | } |
303 | } |
304 | |
305 | #[test] |
306 | fn append_multiple_values() { |
307 | let mut map = HeaderMap::new(); |
308 | |
309 | map.append(header::CONTENT_TYPE, "json" .parse().unwrap()); |
310 | map.append(header::CONTENT_TYPE, "html" .parse().unwrap()); |
311 | map.append(header::CONTENT_TYPE, "xml" .parse().unwrap()); |
312 | |
313 | let vals = map |
314 | .get_all(&header::CONTENT_TYPE) |
315 | .iter() |
316 | .collect::<Vec<_>>(); |
317 | |
318 | assert_eq!(&vals, &[&"json" , &"html" , &"xml" ]); |
319 | } |
320 | |
321 | fn custom_std(n: usize) -> Vec<HeaderName> { |
322 | (0..n) |
323 | .map(|i| { |
324 | let s = format!("{}-{}" , STD[i % STD.len()].as_str(), i); |
325 | s.parse().unwrap() |
326 | }) |
327 | .collect() |
328 | } |
329 | |
330 | const STD: &'static [HeaderName] = &[ |
331 | ACCEPT, |
332 | ACCEPT_CHARSET, |
333 | ACCEPT_ENCODING, |
334 | ACCEPT_LANGUAGE, |
335 | ACCEPT_RANGES, |
336 | ACCESS_CONTROL_ALLOW_CREDENTIALS, |
337 | ACCESS_CONTROL_ALLOW_HEADERS, |
338 | ACCESS_CONTROL_ALLOW_METHODS, |
339 | ACCESS_CONTROL_ALLOW_ORIGIN, |
340 | ACCESS_CONTROL_EXPOSE_HEADERS, |
341 | ACCESS_CONTROL_MAX_AGE, |
342 | ACCESS_CONTROL_REQUEST_HEADERS, |
343 | ACCESS_CONTROL_REQUEST_METHOD, |
344 | AGE, |
345 | ALLOW, |
346 | ALT_SVC, |
347 | AUTHORIZATION, |
348 | CACHE_CONTROL, |
349 | CACHE_STATUS, |
350 | CDN_CACHE_CONTROL, |
351 | CONNECTION, |
352 | CONTENT_DISPOSITION, |
353 | CONTENT_ENCODING, |
354 | CONTENT_LANGUAGE, |
355 | CONTENT_LENGTH, |
356 | CONTENT_LOCATION, |
357 | CONTENT_RANGE, |
358 | CONTENT_SECURITY_POLICY, |
359 | CONTENT_SECURITY_POLICY_REPORT_ONLY, |
360 | CONTENT_TYPE, |
361 | COOKIE, |
362 | DNT, |
363 | DATE, |
364 | ETAG, |
365 | EXPECT, |
366 | EXPIRES, |
367 | FORWARDED, |
368 | FROM, |
369 | HOST, |
370 | IF_MATCH, |
371 | IF_MODIFIED_SINCE, |
372 | IF_NONE_MATCH, |
373 | IF_RANGE, |
374 | IF_UNMODIFIED_SINCE, |
375 | LAST_MODIFIED, |
376 | LINK, |
377 | LOCATION, |
378 | MAX_FORWARDS, |
379 | ORIGIN, |
380 | PRAGMA, |
381 | PROXY_AUTHENTICATE, |
382 | PROXY_AUTHORIZATION, |
383 | PUBLIC_KEY_PINS, |
384 | PUBLIC_KEY_PINS_REPORT_ONLY, |
385 | RANGE, |
386 | REFERER, |
387 | REFERRER_POLICY, |
388 | RETRY_AFTER, |
389 | SERVER, |
390 | SET_COOKIE, |
391 | STRICT_TRANSPORT_SECURITY, |
392 | TE, |
393 | TRAILER, |
394 | TRANSFER_ENCODING, |
395 | USER_AGENT, |
396 | UPGRADE, |
397 | UPGRADE_INSECURE_REQUESTS, |
398 | VARY, |
399 | VIA, |
400 | WARNING, |
401 | WWW_AUTHENTICATE, |
402 | X_CONTENT_TYPE_OPTIONS, |
403 | X_DNS_PREFETCH_CONTROL, |
404 | X_FRAME_OPTIONS, |
405 | X_XSS_PROTECTION, |
406 | ]; |
407 | |
408 | #[test] |
409 | fn get_invalid() { |
410 | let mut headers = HeaderMap::new(); |
411 | headers.insert("foo" , "bar" .parse().unwrap()); |
412 | assert!(headers.get("Evil \r\nKey" ).is_none()); |
413 | } |
414 | |
415 | #[test] |
416 | #[should_panic ] |
417 | fn insert_invalid() { |
418 | let mut headers = HeaderMap::new(); |
419 | headers.insert("evil \r\nfoo" , "bar" .parse().unwrap()); |
420 | } |
421 | |
422 | #[test] |
423 | fn value_htab() { |
424 | // RFC 7230 Section 3.2: |
425 | // > field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] |
426 | HeaderValue::from_static("hello \tworld" ); |
427 | HeaderValue::from_str("hello \tworld" ).unwrap(); |
428 | } |
429 | |
430 | |
431 | #[test] |
432 | fn remove_multiple_a() { |
433 | let mut headers = HeaderMap::new(); |
434 | headers.insert(VIA, "1.1 example.com" .parse().unwrap()); |
435 | headers.insert(SET_COOKIE, "cookie_1=value 1" .parse().unwrap()); |
436 | headers.append(SET_COOKIE, "cookie_2=value 2" .parse().unwrap()); |
437 | headers.append(VIA, "1.1 other.com" .parse().unwrap()); |
438 | headers.append(SET_COOKIE, "cookie_3=value 3" .parse().unwrap()); |
439 | headers.insert(VARY, "*" .parse().unwrap()); |
440 | |
441 | assert_eq!(headers.len(), 6); |
442 | |
443 | let cookie = headers.remove(SET_COOKIE); |
444 | assert_eq!(cookie, Some("cookie_1=value 1" .parse().unwrap())); |
445 | assert_eq!(headers.len(), 3); |
446 | |
447 | let via = headers.remove(VIA); |
448 | assert_eq!(via, Some("1.1 example.com" .parse().unwrap())); |
449 | assert_eq!(headers.len(), 1); |
450 | |
451 | let vary = headers.remove(VARY); |
452 | assert_eq!(vary, Some("*" .parse().unwrap())); |
453 | assert_eq!(headers.len(), 0); |
454 | } |
455 | |
456 | #[test] |
457 | fn remove_multiple_b() { |
458 | let mut headers = HeaderMap::new(); |
459 | headers.insert(VIA, "1.1 example.com" .parse().unwrap()); |
460 | headers.insert(SET_COOKIE, "cookie_1=value 1" .parse().unwrap()); |
461 | headers.append(SET_COOKIE, "cookie_2=value 2" .parse().unwrap()); |
462 | headers.append(VIA, "1.1 other.com" .parse().unwrap()); |
463 | headers.append(SET_COOKIE, "cookie_3=value 3" .parse().unwrap()); |
464 | headers.insert(VARY, "*" .parse().unwrap()); |
465 | |
466 | assert_eq!(headers.len(), 6); |
467 | |
468 | let vary = headers.remove(VARY); |
469 | assert_eq!(vary, Some("*" .parse().unwrap())); |
470 | assert_eq!(headers.len(), 5); |
471 | |
472 | let via = headers.remove(VIA); |
473 | assert_eq!(via, Some("1.1 example.com" .parse().unwrap())); |
474 | assert_eq!(headers.len(), 3); |
475 | |
476 | let cookie = headers.remove(SET_COOKIE); |
477 | assert_eq!(cookie, Some("cookie_1=value 1" .parse().unwrap())); |
478 | assert_eq!(headers.len(), 0); |
479 | } |
480 | |
481 | #[test] |
482 | fn remove_entry_multi_0() { |
483 | let mut headers = HeaderMap::new(); |
484 | let cookies = remove_all_values(&mut headers, SET_COOKIE); |
485 | assert_eq!(cookies.len(), 0); |
486 | assert_eq!(headers.len(), 0); |
487 | } |
488 | |
489 | #[test] |
490 | fn remove_entry_multi_0_others() { |
491 | let mut headers = HeaderMap::new(); |
492 | headers.insert(VIA, "1.1 example.com" .parse().unwrap()); |
493 | headers.append(VIA, "1.1 other.com" .parse().unwrap()); |
494 | |
495 | let cookies = remove_all_values(&mut headers, SET_COOKIE); |
496 | assert_eq!(cookies.len(), 0); |
497 | assert_eq!(headers.len(), 2); |
498 | } |
499 | |
500 | #[test] |
501 | fn remove_entry_multi_1() { |
502 | let mut headers = HeaderMap::new(); |
503 | headers.insert(SET_COOKIE, "cookie_1=value 1" .parse().unwrap()); |
504 | |
505 | let cookies = remove_all_values(&mut headers, SET_COOKIE); |
506 | assert_eq!(cookies.len(), 1); |
507 | assert_eq!(headers.len(), 0); |
508 | } |
509 | |
510 | #[test] |
511 | fn remove_entry_multi_1_other() { |
512 | let mut headers = HeaderMap::new(); |
513 | headers.insert(SET_COOKIE, "cookie_1=value 1" .parse().unwrap()); |
514 | headers.insert(VIA, "1.1 example.com" .parse().unwrap()); |
515 | |
516 | let cookies = remove_all_values(&mut headers, SET_COOKIE); |
517 | assert_eq!(cookies.len(), 1); |
518 | assert_eq!(headers.len(), 1); |
519 | |
520 | let vias = remove_all_values(&mut headers, VIA); |
521 | assert_eq!(vias.len(), 1); |
522 | assert_eq!(headers.len(), 0); |
523 | } |
524 | |
525 | // For issue hyperimum/http#446 |
526 | #[test] |
527 | fn remove_entry_multi_2() { |
528 | let mut headers = HeaderMap::new(); |
529 | headers.insert(SET_COOKIE, "cookie_1=value 1" .parse().unwrap()); |
530 | headers.append(SET_COOKIE, "cookie_2=value 2" .parse().unwrap()); |
531 | |
532 | let cookies = remove_all_values(&mut headers, SET_COOKIE); |
533 | assert_eq!(cookies.len(), 2); |
534 | assert_eq!(headers.len(), 0); |
535 | } |
536 | |
537 | #[test] |
538 | fn remove_entry_multi_3() { |
539 | let mut headers = HeaderMap::new(); |
540 | headers.insert(SET_COOKIE, "cookie_1=value 1" .parse().unwrap()); |
541 | headers.append(SET_COOKIE, "cookie_2=value 2" .parse().unwrap()); |
542 | headers.append(SET_COOKIE, "cookie_3=value 3" .parse().unwrap()); |
543 | |
544 | let cookies = remove_all_values(&mut headers, SET_COOKIE); |
545 | assert_eq!(cookies.len(), 3); |
546 | assert_eq!(headers.len(), 0); |
547 | } |
548 | |
549 | #[test] |
550 | fn remove_entry_multi_3_others() { |
551 | let mut headers = HeaderMap::new(); |
552 | headers.insert(VIA, "1.1 example.com" .parse().unwrap()); |
553 | headers.insert(SET_COOKIE, "cookie_1=value 1" .parse().unwrap()); |
554 | headers.append(SET_COOKIE, "cookie_2=value 2" .parse().unwrap()); |
555 | headers.append(VIA, "1.1 other.com" .parse().unwrap()); |
556 | headers.append(SET_COOKIE, "cookie_3=value 3" .parse().unwrap()); |
557 | headers.insert(VARY, "*" .parse().unwrap()); |
558 | |
559 | let cookies = remove_all_values(&mut headers, SET_COOKIE); |
560 | assert_eq!(cookies.len(), 3); |
561 | assert_eq!(headers.len(), 3); |
562 | |
563 | let vias = remove_all_values(&mut headers, VIA); |
564 | assert_eq!(vias.len(), 2); |
565 | assert_eq!(headers.len(), 1); |
566 | |
567 | let varies = remove_all_values(&mut headers, VARY); |
568 | assert_eq!(varies.len(), 1); |
569 | assert_eq!(headers.len(), 0); |
570 | } |
571 | |
572 | fn remove_all_values<K>(headers: &mut HeaderMap, key: K) -> Vec<HeaderValue> |
573 | where K: IntoHeaderName |
574 | { |
575 | match headers.entry(key) { |
576 | Entry::Occupied(e) => e.remove_entry_mult().1.collect(), |
577 | Entry::Vacant(_) => vec![], |
578 | } |
579 | } |
580 | |
581 | #[test] |
582 | fn remove_entry_3_others_a() { |
583 | let mut headers = HeaderMap::new(); |
584 | headers.insert(VIA, "1.1 example.com" .parse().unwrap()); |
585 | headers.insert(SET_COOKIE, "cookie_1=value 1" .parse().unwrap()); |
586 | headers.append(SET_COOKIE, "cookie_2=value 2" .parse().unwrap()); |
587 | headers.append(VIA, "1.1 other.com" .parse().unwrap()); |
588 | headers.append(SET_COOKIE, "cookie_3=value 3" .parse().unwrap()); |
589 | headers.insert(VARY, "*" .parse().unwrap()); |
590 | |
591 | assert_eq!(headers.len(), 6); |
592 | |
593 | let cookie = remove_values(&mut headers, SET_COOKIE); |
594 | assert_eq!(cookie, Some("cookie_1=value 1" .parse().unwrap())); |
595 | assert_eq!(headers.len(), 3); |
596 | |
597 | let via = remove_values(&mut headers, VIA); |
598 | assert_eq!(via, Some("1.1 example.com" .parse().unwrap())); |
599 | assert_eq!(headers.len(), 1); |
600 | |
601 | let vary = remove_values(&mut headers, VARY); |
602 | assert_eq!(vary, Some("*" .parse().unwrap())); |
603 | assert_eq!(headers.len(), 0); |
604 | } |
605 | |
606 | #[test] |
607 | fn remove_entry_3_others_b() { |
608 | let mut headers = HeaderMap::new(); |
609 | headers.insert(VIA, "1.1 example.com" .parse().unwrap()); |
610 | headers.insert(SET_COOKIE, "cookie_1=value 1" .parse().unwrap()); |
611 | headers.append(SET_COOKIE, "cookie_2=value 2" .parse().unwrap()); |
612 | headers.append(VIA, "1.1 other.com" .parse().unwrap()); |
613 | headers.append(SET_COOKIE, "cookie_3=value 3" .parse().unwrap()); |
614 | headers.insert(VARY, "*" .parse().unwrap()); |
615 | |
616 | assert_eq!(headers.len(), 6); |
617 | |
618 | let vary = remove_values(&mut headers, VARY); |
619 | assert_eq!(vary, Some("*" .parse().unwrap())); |
620 | assert_eq!(headers.len(), 5); |
621 | |
622 | let via = remove_values(&mut headers, VIA); |
623 | assert_eq!(via, Some("1.1 example.com" .parse().unwrap())); |
624 | assert_eq!(headers.len(), 3); |
625 | |
626 | let cookie = remove_values(&mut headers, SET_COOKIE); |
627 | assert_eq!(cookie, Some("cookie_1=value 1" .parse().unwrap())); |
628 | assert_eq!(headers.len(), 0); |
629 | } |
630 | |
631 | fn remove_values<K>(headers: &mut HeaderMap, key: K) -> Option<HeaderValue> |
632 | where K: IntoHeaderName |
633 | { |
634 | match headers.entry(key) { |
635 | Entry::Occupied(e) => Some(e.remove_entry().1), |
636 | Entry::Vacant(_) => None, |
637 | } |
638 | } |
639 | |