| 1 | use http::header::*; |
| 2 | use http::*; |
| 3 | |
| 4 | #[test] |
| 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 ] |
| 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] |
| 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 ] |
| 54 | fn with_capacity_overflow() { |
| 55 | HeaderMap::<u32>::with_capacity(24_577); |
| 56 | } |
| 57 | |
| 58 | #[test] |
| 59 | #[should_panic ] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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 | |
| 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] |
| 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 ] |
| 417 | fn insert_invalid() { |
| 418 | let mut headers = HeaderMap::new(); |
| 419 | headers.insert("evil \r\nfoo" , "bar" .parse().unwrap()); |
| 420 | } |
| 421 | |
| 422 | #[test] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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] |
| 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 | |
| 572 | 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] |
| 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] |
| 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 | |
| 631 | 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 | |