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