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 
179     // Using insert
180     {
181         let mut e = match headers.entry("hello") {
182             Entry::Occupied(e) => e,
183             _ => panic!(),
184         };
185 
186         let vals: Vec<_> = e.insert_mult("wat".parse().unwrap()).collect();
187         assert_eq!(2, vals.len());
188         assert_eq!(vals[0], "world");
189         assert_eq!(vals[1], "world2");
190     }
191 }
192 
193 #[test]
eq()194 fn eq() {
195     let mut a = HeaderMap::new();
196     let mut b = HeaderMap::new();
197 
198     assert_eq!(a, b);
199 
200     a.insert(
201         "hello".parse::<HeaderName>().unwrap(),
202         "world".parse().unwrap(),
203     );
204     assert_ne!(a, b);
205 
206     b.insert(
207         "hello".parse::<HeaderName>().unwrap(),
208         "world".parse().unwrap(),
209     );
210     assert_eq!(a, b);
211 
212     a.insert("foo".parse::<HeaderName>().unwrap(), "bar".parse().unwrap());
213     a.append("foo".parse::<HeaderName>().unwrap(), "baz".parse().unwrap());
214     assert_ne!(a, b);
215 
216     b.insert("foo".parse::<HeaderName>().unwrap(), "bar".parse().unwrap());
217     assert_ne!(a, b);
218 
219     b.append("foo".parse::<HeaderName>().unwrap(), "baz".parse().unwrap());
220     assert_eq!(a, b);
221 
222     a.append("a".parse::<HeaderName>().unwrap(), "a".parse().unwrap());
223     a.append("a".parse::<HeaderName>().unwrap(), "b".parse().unwrap());
224     b.append("a".parse::<HeaderName>().unwrap(), "b".parse().unwrap());
225     b.append("a".parse::<HeaderName>().unwrap(), "a".parse().unwrap());
226 
227     assert_ne!(a, b);
228 }
229 
230 #[test]
into_header_name()231 fn into_header_name() {
232     let mut m = HeaderMap::new();
233     m.insert(HOST, "localhost".parse().unwrap());
234     m.insert(&ACCEPT, "*/*".parse().unwrap());
235     m.insert("connection", "keep-alive".parse().unwrap());
236 
237     m.append(LOCATION, "/".parse().unwrap());
238     m.append(&VIA, "bob".parse().unwrap());
239     m.append("transfer-encoding", "chunked".parse().unwrap());
240 
241     assert_eq!(m.len(), 6);
242 }
243 
244 #[test]
as_header_name()245 fn as_header_name() {
246     let mut m = HeaderMap::new();
247     let v: HeaderValue = "localhost".parse().unwrap();
248     m.insert(HOST, v.clone());
249 
250     let expected = Some(&v);
251 
252     assert_eq!(m.get("host"), expected);
253     assert_eq!(m.get(&HOST), expected);
254 
255     let s = String::from("host");
256     assert_eq!(m.get(&s), expected);
257     assert_eq!(m.get(s.as_str()), expected);
258 }
259 
260 #[test]
insert_all_std_headers()261 fn insert_all_std_headers() {
262     let mut m = HeaderMap::new();
263 
264     for (i, hdr) in STD.iter().enumerate() {
265         m.insert(hdr.clone(), hdr.as_str().parse().unwrap());
266 
267         for j in 0..(i + 1) {
268             assert_eq!(m[&STD[j]], STD[j].as_str());
269         }
270 
271         if i != 0 {
272             for j in (i + 1)..STD.len() {
273                 assert!(
274                     m.get(&STD[j]).is_none(),
275                     "contained {}; j={}",
276                     STD[j].as_str(),
277                     j
278                 );
279             }
280         }
281     }
282 }
283 
284 #[test]
insert_79_custom_std_headers()285 fn insert_79_custom_std_headers() {
286     let mut h = HeaderMap::new();
287     let hdrs = custom_std(79);
288 
289     for (i, hdr) in hdrs.iter().enumerate() {
290         h.insert(hdr.clone(), hdr.as_str().parse().unwrap());
291 
292         for j in 0..(i + 1) {
293             assert_eq!(h[&hdrs[j]], hdrs[j].as_str());
294         }
295 
296         for j in (i + 1)..hdrs.len() {
297             assert!(h.get(&hdrs[j]).is_none());
298         }
299     }
300 }
301 
302 #[test]
append_multiple_values()303 fn append_multiple_values() {
304     let mut map = HeaderMap::new();
305 
306     map.append(header::CONTENT_TYPE, "json".parse().unwrap());
307     map.append(header::CONTENT_TYPE, "html".parse().unwrap());
308     map.append(header::CONTENT_TYPE, "xml".parse().unwrap());
309 
310     let vals = map
311         .get_all(&header::CONTENT_TYPE)
312         .iter()
313         .collect::<Vec<_>>();
314 
315     assert_eq!(&vals, &[&"json", &"html", &"xml"]);
316 }
317 
custom_std(n: usize) -> Vec<HeaderName>318 fn custom_std(n: usize) -> Vec<HeaderName> {
319     (0..n)
320         .map(|i| {
321             let s = format!("{}-{}", STD[i % STD.len()].as_str(), i);
322             s.parse().unwrap()
323         })
324         .collect()
325 }
326 
327 const STD: &'static [HeaderName] = &[
328     ACCEPT,
329     ACCEPT_CHARSET,
330     ACCEPT_ENCODING,
331     ACCEPT_LANGUAGE,
332     ACCEPT_RANGES,
333     ACCESS_CONTROL_ALLOW_CREDENTIALS,
334     ACCESS_CONTROL_ALLOW_HEADERS,
335     ACCESS_CONTROL_ALLOW_METHODS,
336     ACCESS_CONTROL_ALLOW_ORIGIN,
337     ACCESS_CONTROL_EXPOSE_HEADERS,
338     ACCESS_CONTROL_MAX_AGE,
339     ACCESS_CONTROL_REQUEST_HEADERS,
340     ACCESS_CONTROL_REQUEST_METHOD,
341     AGE,
342     ALLOW,
343     ALT_SVC,
344     AUTHORIZATION,
345     CACHE_CONTROL,
346     CONNECTION,
347     CONTENT_DISPOSITION,
348     CONTENT_ENCODING,
349     CONTENT_LANGUAGE,
350     CONTENT_LENGTH,
351     CONTENT_LOCATION,
352     CONTENT_RANGE,
353     CONTENT_SECURITY_POLICY,
354     CONTENT_SECURITY_POLICY_REPORT_ONLY,
355     CONTENT_TYPE,
356     COOKIE,
357     DNT,
358     DATE,
359     ETAG,
360     EXPECT,
361     EXPIRES,
362     FORWARDED,
363     FROM,
364     HOST,
365     IF_MATCH,
366     IF_MODIFIED_SINCE,
367     IF_NONE_MATCH,
368     IF_RANGE,
369     IF_UNMODIFIED_SINCE,
370     LAST_MODIFIED,
371     LINK,
372     LOCATION,
373     MAX_FORWARDS,
374     ORIGIN,
375     PRAGMA,
376     PROXY_AUTHENTICATE,
377     PROXY_AUTHORIZATION,
378     PUBLIC_KEY_PINS,
379     PUBLIC_KEY_PINS_REPORT_ONLY,
380     RANGE,
381     REFERER,
382     REFERRER_POLICY,
383     RETRY_AFTER,
384     SERVER,
385     SET_COOKIE,
386     STRICT_TRANSPORT_SECURITY,
387     TE,
388     TRAILER,
389     TRANSFER_ENCODING,
390     USER_AGENT,
391     UPGRADE,
392     UPGRADE_INSECURE_REQUESTS,
393     VARY,
394     VIA,
395     WARNING,
396     WWW_AUTHENTICATE,
397     X_CONTENT_TYPE_OPTIONS,
398     X_DNS_PREFETCH_CONTROL,
399     X_FRAME_OPTIONS,
400     X_XSS_PROTECTION,
401 ];
402 
403 #[test]
get_invalid()404 fn get_invalid() {
405     let mut headers = HeaderMap::new();
406     headers.insert("foo", "bar".parse().unwrap());
407     assert!(headers.get("Evil\r\nKey").is_none());
408 }
409 
410 #[test]
411 #[should_panic]
insert_invalid()412 fn insert_invalid() {
413     let mut headers = HeaderMap::new();
414     headers.insert("evil\r\nfoo", "bar".parse().unwrap());
415 }
416 
417 #[test]
value_htab()418 fn value_htab() {
419     // RFC 7230 Section 3.2:
420     // > field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
421     HeaderValue::from_static("hello\tworld");
422     HeaderValue::from_str("hello\tworld").unwrap();
423 }
424