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     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]
get_invalid()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]
insert_invalid()417 fn insert_invalid() {
418     let mut headers = HeaderMap::new();
419     headers.insert("evil\r\nfoo", "bar".parse().unwrap());
420 }
421 
422 #[test]
value_htab()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]
remove_multiple_a()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]
remove_multiple_b()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]
remove_entry_multi_0()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]
remove_entry_multi_0_others()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]
remove_entry_multi_1()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]
remove_entry_multi_1_other()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]
remove_entry_multi_2()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]
remove_entry_multi_3()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]
remove_entry_multi_3_others()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 
remove_all_values<K>(headers: &mut HeaderMap, key: K) -> Vec<HeaderValue> where K: IntoHeaderName572 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]
remove_entry_3_others_a()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]
remove_entry_3_others_b()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 
remove_values<K>(headers: &mut HeaderMap, key: K) -> Option<HeaderValue> where K: IntoHeaderName631 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