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