1 use http::header::*;
2 use http::*;
3 
4 #[test]
smoke()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]
reserve_over_capacity()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]
with_capacity_max()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]
with_capacity_overflow()54 fn with_capacity_overflow() {
55     HeaderMap::<u32>::with_capacity(24_577);
56 }
57 
58 #[test]
59 #[should_panic]
reserve_overflow()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]
drain()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]
drain_drop_immediately()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]
drain_forget()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]
drain_entry()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]
eq()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]
into_header_name()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]
as_header_name()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]
insert_all_std_headers()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]
insert_79_custom_std_headers()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]
append_multiple_values()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 
custom_std(n: usize) -> Vec<HeaderName>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     CONNECTION,
350     CONTENT_DISPOSITION,
351     CONTENT_ENCODING,
352     CONTENT_LANGUAGE,
353     CONTENT_LENGTH,
354     CONTENT_LOCATION,
355     CONTENT_RANGE,
356     CONTENT_SECURITY_POLICY,
357     CONTENT_SECURITY_POLICY_REPORT_ONLY,
358     CONTENT_TYPE,
359     COOKIE,
360     DNT,
361     DATE,
362     ETAG,
363     EXPECT,
364     EXPIRES,
365     FORWARDED,
366     FROM,
367     HOST,
368     IF_MATCH,
369     IF_MODIFIED_SINCE,
370     IF_NONE_MATCH,
371     IF_RANGE,
372     IF_UNMODIFIED_SINCE,
373     LAST_MODIFIED,
374     LINK,
375     LOCATION,
376     MAX_FORWARDS,
377     ORIGIN,
378     PRAGMA,
379     PROXY_AUTHENTICATE,
380     PROXY_AUTHORIZATION,
381     PUBLIC_KEY_PINS,
382     PUBLIC_KEY_PINS_REPORT_ONLY,
383     RANGE,
384     REFERER,
385     REFERRER_POLICY,
386     RETRY_AFTER,
387     SERVER,
388     SET_COOKIE,
389     STRICT_TRANSPORT_SECURITY,
390     TE,
391     TRAILER,
392     TRANSFER_ENCODING,
393     USER_AGENT,
394     UPGRADE,
395     UPGRADE_INSECURE_REQUESTS,
396     VARY,
397     VIA,
398     WARNING,
399     WWW_AUTHENTICATE,
400     X_CONTENT_TYPE_OPTIONS,
401     X_DNS_PREFETCH_CONTROL,
402     X_FRAME_OPTIONS,
403     X_XSS_PROTECTION,
404 ];
405 
406 #[test]
get_invalid()407 fn get_invalid() {
408     let mut headers = HeaderMap::new();
409     headers.insert("foo", "bar".parse().unwrap());
410     assert!(headers.get("Evil\r\nKey").is_none());
411 }
412 
413 #[test]
414 #[should_panic]
insert_invalid()415 fn insert_invalid() {
416     let mut headers = HeaderMap::new();
417     headers.insert("evil\r\nfoo", "bar".parse().unwrap());
418 }
419 
420 #[test]
value_htab()421 fn value_htab() {
422     // RFC 7230 Section 3.2:
423     // > field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
424     HeaderValue::from_static("hello\tworld");
425     HeaderValue::from_str("hello\tworld").unwrap();
426 }
427 
428 
429 #[test]
remove_multiple_a()430 fn remove_multiple_a() {
431     let mut headers = HeaderMap::new();
432     headers.insert(VIA, "1.1 example.com".parse().unwrap());
433     headers.insert(SET_COOKIE, "cookie_1=value 1".parse().unwrap());
434     headers.append(SET_COOKIE, "cookie_2=value 2".parse().unwrap());
435     headers.append(VIA, "1.1 other.com".parse().unwrap());
436     headers.append(SET_COOKIE, "cookie_3=value 3".parse().unwrap());
437     headers.insert(VARY, "*".parse().unwrap());
438 
439     assert_eq!(headers.len(), 6);
440 
441     let cookie = headers.remove(SET_COOKIE);
442     assert_eq!(cookie, Some("cookie_1=value 1".parse().unwrap()));
443     assert_eq!(headers.len(), 3);
444 
445     let via = headers.remove(VIA);
446     assert_eq!(via, Some("1.1 example.com".parse().unwrap()));
447     assert_eq!(headers.len(), 1);
448 
449     let vary = headers.remove(VARY);
450     assert_eq!(vary, Some("*".parse().unwrap()));
451     assert_eq!(headers.len(), 0);
452 }
453 
454 #[test]
remove_multiple_b()455 fn remove_multiple_b() {
456     let mut headers = HeaderMap::new();
457     headers.insert(VIA, "1.1 example.com".parse().unwrap());
458     headers.insert(SET_COOKIE, "cookie_1=value 1".parse().unwrap());
459     headers.append(SET_COOKIE, "cookie_2=value 2".parse().unwrap());
460     headers.append(VIA, "1.1 other.com".parse().unwrap());
461     headers.append(SET_COOKIE, "cookie_3=value 3".parse().unwrap());
462     headers.insert(VARY, "*".parse().unwrap());
463 
464     assert_eq!(headers.len(), 6);
465 
466     let vary = headers.remove(VARY);
467     assert_eq!(vary, Some("*".parse().unwrap()));
468     assert_eq!(headers.len(), 5);
469 
470     let via = headers.remove(VIA);
471     assert_eq!(via, Some("1.1 example.com".parse().unwrap()));
472     assert_eq!(headers.len(), 3);
473 
474     let cookie = headers.remove(SET_COOKIE);
475     assert_eq!(cookie, Some("cookie_1=value 1".parse().unwrap()));
476     assert_eq!(headers.len(), 0);
477 }
478 
479 #[test]
remove_entry_multi_0()480 fn remove_entry_multi_0() {
481     let mut headers = HeaderMap::new();
482     let cookies = remove_all_values(&mut headers, SET_COOKIE);
483     assert_eq!(cookies.len(), 0);
484     assert_eq!(headers.len(), 0);
485 }
486 
487 #[test]
remove_entry_multi_0_others()488 fn remove_entry_multi_0_others() {
489     let mut headers = HeaderMap::new();
490     headers.insert(VIA, "1.1 example.com".parse().unwrap());
491     headers.append(VIA, "1.1 other.com".parse().unwrap());
492 
493     let cookies = remove_all_values(&mut headers, SET_COOKIE);
494     assert_eq!(cookies.len(), 0);
495     assert_eq!(headers.len(), 2);
496 }
497 
498 #[test]
remove_entry_multi_1()499 fn remove_entry_multi_1() {
500     let mut headers = HeaderMap::new();
501     headers.insert(SET_COOKIE, "cookie_1=value 1".parse().unwrap());
502 
503     let cookies = remove_all_values(&mut headers, SET_COOKIE);
504     assert_eq!(cookies.len(), 1);
505     assert_eq!(headers.len(), 0);
506 }
507 
508 #[test]
remove_entry_multi_1_other()509 fn remove_entry_multi_1_other() {
510     let mut headers = HeaderMap::new();
511     headers.insert(SET_COOKIE, "cookie_1=value 1".parse().unwrap());
512     headers.insert(VIA, "1.1 example.com".parse().unwrap());
513 
514     let cookies = remove_all_values(&mut headers, SET_COOKIE);
515     assert_eq!(cookies.len(), 1);
516     assert_eq!(headers.len(), 1);
517 
518     let vias = remove_all_values(&mut headers, VIA);
519     assert_eq!(vias.len(), 1);
520     assert_eq!(headers.len(), 0);
521 }
522 
523 // For issue hyperimum/http#446
524 #[test]
remove_entry_multi_2()525 fn remove_entry_multi_2() {
526     let mut headers = HeaderMap::new();
527     headers.insert(SET_COOKIE, "cookie_1=value 1".parse().unwrap());
528     headers.append(SET_COOKIE, "cookie_2=value 2".parse().unwrap());
529 
530     let cookies = remove_all_values(&mut headers, SET_COOKIE);
531     assert_eq!(cookies.len(), 2);
532     assert_eq!(headers.len(), 0);
533 }
534 
535 #[test]
remove_entry_multi_3()536 fn remove_entry_multi_3() {
537     let mut headers = HeaderMap::new();
538     headers.insert(SET_COOKIE, "cookie_1=value 1".parse().unwrap());
539     headers.append(SET_COOKIE, "cookie_2=value 2".parse().unwrap());
540     headers.append(SET_COOKIE, "cookie_3=value 3".parse().unwrap());
541 
542     let cookies = remove_all_values(&mut headers, SET_COOKIE);
543     assert_eq!(cookies.len(), 3);
544     assert_eq!(headers.len(), 0);
545 }
546 
547 #[test]
remove_entry_multi_3_others()548 fn remove_entry_multi_3_others() {
549     let mut headers = HeaderMap::new();
550     headers.insert(VIA, "1.1 example.com".parse().unwrap());
551     headers.insert(SET_COOKIE, "cookie_1=value 1".parse().unwrap());
552     headers.append(SET_COOKIE, "cookie_2=value 2".parse().unwrap());
553     headers.append(VIA, "1.1 other.com".parse().unwrap());
554     headers.append(SET_COOKIE, "cookie_3=value 3".parse().unwrap());
555     headers.insert(VARY, "*".parse().unwrap());
556 
557     let cookies = remove_all_values(&mut headers, SET_COOKIE);
558     assert_eq!(cookies.len(), 3);
559     assert_eq!(headers.len(), 3);
560 
561     let vias = remove_all_values(&mut headers, VIA);
562     assert_eq!(vias.len(), 2);
563     assert_eq!(headers.len(), 1);
564 
565     let varies = remove_all_values(&mut headers, VARY);
566     assert_eq!(varies.len(), 1);
567     assert_eq!(headers.len(), 0);
568 }
569 
remove_all_values<K>(headers: &mut HeaderMap, key: K) -> Vec<HeaderValue> where K: IntoHeaderName570 fn remove_all_values<K>(headers: &mut HeaderMap, key: K) -> Vec<HeaderValue>
571     where K: IntoHeaderName
572 {
573     match headers.entry(key) {
574         Entry::Occupied(e) => e.remove_entry_mult().1.collect(),
575         Entry::Vacant(_) => vec![],
576     }
577 }
578 
579 #[test]
remove_entry_3_others_a()580 fn remove_entry_3_others_a() {
581     let mut headers = HeaderMap::new();
582     headers.insert(VIA, "1.1 example.com".parse().unwrap());
583     headers.insert(SET_COOKIE, "cookie_1=value 1".parse().unwrap());
584     headers.append(SET_COOKIE, "cookie_2=value 2".parse().unwrap());
585     headers.append(VIA, "1.1 other.com".parse().unwrap());
586     headers.append(SET_COOKIE, "cookie_3=value 3".parse().unwrap());
587     headers.insert(VARY, "*".parse().unwrap());
588 
589     assert_eq!(headers.len(), 6);
590 
591     let cookie = remove_values(&mut headers, SET_COOKIE);
592     assert_eq!(cookie, Some("cookie_1=value 1".parse().unwrap()));
593     assert_eq!(headers.len(), 3);
594 
595     let via = remove_values(&mut headers, VIA);
596     assert_eq!(via, Some("1.1 example.com".parse().unwrap()));
597     assert_eq!(headers.len(), 1);
598 
599     let vary = remove_values(&mut headers, VARY);
600     assert_eq!(vary, Some("*".parse().unwrap()));
601     assert_eq!(headers.len(), 0);
602 }
603 
604 #[test]
remove_entry_3_others_b()605 fn remove_entry_3_others_b() {
606     let mut headers = HeaderMap::new();
607     headers.insert(VIA, "1.1 example.com".parse().unwrap());
608     headers.insert(SET_COOKIE, "cookie_1=value 1".parse().unwrap());
609     headers.append(SET_COOKIE, "cookie_2=value 2".parse().unwrap());
610     headers.append(VIA, "1.1 other.com".parse().unwrap());
611     headers.append(SET_COOKIE, "cookie_3=value 3".parse().unwrap());
612     headers.insert(VARY, "*".parse().unwrap());
613 
614     assert_eq!(headers.len(), 6);
615 
616     let vary = remove_values(&mut headers, VARY);
617     assert_eq!(vary, Some("*".parse().unwrap()));
618     assert_eq!(headers.len(), 5);
619 
620     let via = remove_values(&mut headers, VIA);
621     assert_eq!(via, Some("1.1 example.com".parse().unwrap()));
622     assert_eq!(headers.len(), 3);
623 
624     let cookie = remove_values(&mut headers, SET_COOKIE);
625     assert_eq!(cookie, Some("cookie_1=value 1".parse().unwrap()));
626     assert_eq!(headers.len(), 0);
627 }
628 
remove_values<K>(headers: &mut HeaderMap, key: K) -> Option<HeaderValue> where K: IntoHeaderName629 fn remove_values<K>(headers: &mut HeaderMap, key: K) -> Option<HeaderValue>
630     where K: IntoHeaderName
631 {
632     match headers.entry(key) {
633         Entry::Occupied(e) => Some(e.remove_entry().1),
634         Entry::Vacant(_) => None,
635     }
636 }
637