1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 //! HTTP [`Header`][header], which is called `Field` in [`RFC9110`]. 15 //! 16 //! The module provides [`Header`], [`HeaderName`], [`HeaderValue`], [`Headers`] 17 //! and a number of types used for interacting with `Headers`. 18 //! 19 //! These types allow representing both `HTTP/1` and `HTTP/2` headers. 20 //! 21 //! [header]: https://httpwg.org/specs/rfc9110.html#fields 22 //! [`RFC9110`]: https://httpwg.org/specs/rfc9110.html 23 //! [`Header`]: Header 24 //! [`HeaderName`]: HeaderName 25 //! [`HeaderValue`]: HeaderValue 26 //! [`Headers`]: Headers 27 //! 28 //! # Examples 29 //! 30 //! ``` 31 //! use ylong_http::headers::Headers; 32 //! 33 //! let mut headers = Headers::new(); 34 //! headers.insert("Accept", "text/html").unwrap(); 35 //! headers.insert("Content-Length", "3495").unwrap(); 36 //! 37 //! assert_eq!( 38 //! headers.get("accept").unwrap().to_string().unwrap(), 39 //! "text/html" 40 //! ); 41 //! assert_eq!( 42 //! headers.get("content-length").unwrap().to_string().unwrap(), 43 //! "3495" 44 //! ); 45 //! ``` 46 47 use core::convert::TryFrom; 48 use core::{fmt, slice, str}; 49 use std::collections::hash_map::Entry; 50 use std::collections::{hash_map, HashMap}; 51 52 use crate::error::{ErrorKind, HttpError}; 53 54 /// HTTP `Header`, which consists of [`HeaderName`] and [`HeaderValue`]. 55 /// 56 /// `Header` is called `Field` in RFC9110. HTTP uses fields to provide data in 57 /// the form of extensible name/value pairs with a registered key namespace. 58 /// 59 /// [`HeaderName`]: HeaderName 60 /// [`HeaderValue`]: HeaderValue 61 /// 62 /// # Examples 63 /// 64 /// ``` 65 /// use core::convert::TryFrom; 66 /// 67 /// use ylong_http::headers::Header; 68 /// 69 /// // This header name string will be normalized to lowercase. 70 /// let header = Header::try_from(("Example-Field", "Foo")).unwrap(); 71 /// assert_eq!(header.name().as_bytes(), b"example-field"); 72 /// 73 /// // All characters of this header string can be displayed, so the `to_string` 74 /// // interface can be used to output. 75 /// assert_eq!(header.value().to_string().unwrap(), "Foo"); 76 /// ``` 77 #[derive(Clone, Debug, Eq, PartialEq)] 78 pub struct Header { 79 name: HeaderName, 80 value: HeaderValue, 81 } 82 83 impl Header { 84 /// Combines a `HeaderName` and a `HeaderValue` into a `Header`. 85 /// 86 /// # Examples 87 /// 88 /// ``` 89 /// use ylong_http::headers::{Header, HeaderName, HeaderValue}; 90 /// 91 /// let name = HeaderName::from_bytes(b"Example-Field").unwrap(); 92 /// let value = HeaderValue::from_bytes(b"Foo").unwrap(); 93 /// 94 /// let header = Header::from_raw_parts(name, value); 95 /// assert_eq!(header.name().as_bytes(), b"example-field"); 96 /// assert_eq!(header.value().to_string().unwrap(), "Foo"); 97 /// ``` from_raw_parts(name: HeaderName, value: HeaderValue) -> Self98 pub fn from_raw_parts(name: HeaderName, value: HeaderValue) -> Self { 99 Self { name, value } 100 } 101 102 /// Gets a reference to the underlying `HeaderName`. 103 /// 104 /// # Examples 105 /// 106 /// ``` 107 /// use core::convert::TryFrom; 108 /// 109 /// use ylong_http::headers::Header; 110 /// 111 /// let header = Header::try_from(("Example-Field", "Foo")).unwrap(); 112 /// 113 /// let name = header.name(); 114 /// assert_eq!(name.as_bytes(), b"example-field"); 115 /// ``` name(&self) -> &HeaderName116 pub fn name(&self) -> &HeaderName { 117 &self.name 118 } 119 120 /// Gets a reference to the underlying `HeaderValue`. 121 /// 122 /// # Examples 123 /// 124 /// ``` 125 /// use core::convert::TryFrom; 126 /// 127 /// use ylong_http::headers::Header; 128 /// 129 /// let header = Header::try_from(("Example-Field", "Foo")).unwrap(); 130 /// 131 /// let value = header.value(); 132 /// assert_eq!(value.to_string().unwrap(), "Foo"); 133 /// ``` value(&self) -> &HeaderValue134 pub fn value(&self) -> &HeaderValue { 135 &self.value 136 } 137 138 /// Consumes this `Header`, get the underlying `HeaderName` and 139 /// `HeaderValue`. 140 /// 141 /// # Examples 142 /// 143 /// ``` 144 /// use core::convert::TryFrom; 145 /// 146 /// use ylong_http::headers::Header; 147 /// 148 /// let header = Header::try_from(("Example-Field", "Foo")).unwrap(); 149 /// let (name, value) = header.into_parts(); 150 /// 151 /// assert_eq!(name.as_bytes(), b"example-field"); 152 /// assert_eq!(value.to_string().unwrap(), "Foo"); 153 /// ``` into_parts(self) -> (HeaderName, HeaderValue)154 pub fn into_parts(self) -> (HeaderName, HeaderValue) { 155 (self.name, self.value) 156 } 157 } 158 159 impl<N, V> TryFrom<(N, V)> for Header 160 where 161 HeaderName: TryFrom<N>, 162 <HeaderName as TryFrom<N>>::Error: Into<HttpError>, 163 HeaderValue: TryFrom<V>, 164 <HeaderValue as TryFrom<V>>::Error: Into<HttpError>, 165 { 166 type Error = HttpError; 167 try_from(pair: (N, V)) -> Result<Self, Self::Error>168 fn try_from(pair: (N, V)) -> Result<Self, Self::Error> { 169 Ok(Self::from_raw_parts( 170 HeaderName::try_from(pair.0).map_err(Into::into)?, 171 HeaderValue::try_from(pair.1).map_err(Into::into)?, 172 )) 173 } 174 } 175 176 /// HTTP `Header Name`, which is called [`Field Name`] in RFC9110. 177 /// 178 /// A field name labels the corresponding field value as having the semantics 179 /// defined by that name. 180 /// 181 /// [`Field Name`]: https://httpwg.org/specs/rfc9110.html#fields.names 182 /// 183 /// # Examples 184 /// 185 /// ``` 186 /// use ylong_http::headers::HeaderName; 187 /// 188 /// let name = HeaderName::from_bytes(b"Example-Field").unwrap(); 189 /// assert_eq!(name.as_bytes(), b"example-field"); 190 /// ``` 191 // TODO: `StandardHeader` implementation. 192 #[derive(Clone, Debug, Eq, Hash, PartialEq)] 193 pub struct HeaderName { 194 name: String, 195 } 196 197 impl HeaderName { 198 /// Converts a slice of bytes to a `HeaderName`. 199 /// 200 /// Since `HeaderName` is case-insensitive, characters of the input will be 201 /// checked and then converted to lowercase. 202 /// 203 /// # Examples 204 /// 205 /// ``` 206 /// use ylong_http::headers::HeaderName; 207 /// 208 /// let name = HeaderName::from_bytes(b"Example-Field").unwrap(); 209 /// ``` from_bytes(bytes: &[u8]) -> Result<Self, HttpError>210 pub fn from_bytes(bytes: &[u8]) -> Result<Self, HttpError> { 211 Ok(Self { 212 name: Self::normalize(bytes)?, 213 }) 214 } 215 216 /// Returns a bytes representation of the `HeaderName`. 217 /// 218 /// # Examples 219 /// 220 /// ``` 221 /// use ylong_http::headers::HeaderName; 222 /// 223 /// let name = HeaderName::from_bytes(b"Example-Field").unwrap(); 224 /// let bytes = name.as_bytes(); 225 /// assert_eq!(bytes, b"example-field"); 226 /// ``` as_bytes(&self) -> &[u8]227 pub fn as_bytes(&self) -> &[u8] { 228 self.name.as_bytes() 229 } 230 231 // Returns a Vec<u8> of the `HeaderName`. into_bytes(self) -> Vec<u8>232 pub(crate) fn into_bytes(self) -> Vec<u8> { 233 self.name.into_bytes() 234 } 235 236 /// Normalizes the input bytes. normalize(input: &[u8]) -> Result<String, HttpError>237 fn normalize(input: &[u8]) -> Result<String, HttpError> { 238 let mut dst = Vec::new(); 239 for b in input.iter() { 240 // HEADER_CHARS maps all bytes to valid single-byte UTF-8. 241 let b = HEADER_CHARS[*b as usize]; 242 if b == 0 { 243 return Err(ErrorKind::InvalidInput.into()); 244 } 245 dst.push(b); 246 } 247 Ok(unsafe { String::from_utf8_unchecked(dst) }) 248 } 249 } 250 251 /// Returns a `String` value of the `HeaderName`. 252 /// 253 /// # Examples 254 /// 255 /// ``` 256 /// use ylong_http::headers::HeaderName; 257 /// 258 /// let name = HeaderName::from_bytes(b"Example-Field").unwrap(); 259 /// let name_str = name.to_string(); 260 /// assert_eq!(name_str, "example-field"); 261 /// ``` 262 impl ToString for HeaderName { to_string(&self) -> String263 fn to_string(&self) -> String { 264 self.name.clone() 265 } 266 } 267 268 impl TryFrom<&str> for HeaderName { 269 type Error = HttpError; 270 try_from(name: &str) -> Result<Self, Self::Error>271 fn try_from(name: &str) -> Result<Self, Self::Error> { 272 Self::from_bytes(name.as_bytes()) 273 } 274 } 275 276 impl TryFrom<&[u8]> for HeaderName { 277 type Error = HttpError; 278 try_from(bytes: &[u8]) -> Result<Self, Self::Error>279 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> { 280 Self::from_bytes(bytes) 281 } 282 } 283 284 /// HTTP `Header Value`, which is called [`Field Value`] in RFC9110. 285 /// 286 /// HTTP field values consist of a sequence of characters in a format defined by 287 /// the field's grammar. 288 /// 289 /// [`Field Value`]: https://httpwg.org/specs/rfc9110.html#fields.values 290 /// 291 /// # Examples 292 /// 293 /// ``` 294 /// use ylong_http::headers::HeaderValue; 295 /// 296 /// let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 297 /// value.append_bytes(b"application/xml").unwrap(); 298 /// 299 /// assert_eq!(value.to_string().unwrap(), "text/html, application/xml"); 300 /// assert!(!value.is_sensitive()); 301 /// ``` 302 #[derive(Clone, Debug, Eq, PartialEq)] 303 pub struct HeaderValue { 304 inner: Vec<Vec<u8>>, 305 // sensitive data: password etc. 306 is_sensitive: bool, 307 } 308 309 impl HeaderValue { 310 /// Attempts to convert a byte slice to a non-sensitive `HeaderValue`. 311 /// 312 /// `HeaderValue` is case-sensitive. Legal characters will remain unchanged. 313 /// 314 /// # Examples 315 /// 316 /// ``` 317 /// use ylong_http::headers::HeaderValue; 318 /// 319 /// let value = HeaderValue::from_bytes(b"text/html").unwrap(); 320 /// assert_eq!(value.to_string().unwrap(), "text/html"); 321 /// assert!(!value.is_sensitive()); 322 /// 323 /// // `HeaderValue` is case-sensitive. Legal characters will remain unchanged. 324 /// let value = HeaderValue::from_bytes(b"TEXT/HTML").unwrap(); 325 /// assert_eq!(value.to_string().unwrap(), "TEXT/HTML"); 326 /// ``` from_bytes(bytes: &[u8]) -> Result<Self, HttpError>327 pub fn from_bytes(bytes: &[u8]) -> Result<Self, HttpError> { 328 if !bytes.iter().all(|b| Self::is_valid(*b)) { 329 return Err(ErrorKind::InvalidInput.into()); 330 } 331 332 Ok(HeaderValue { 333 inner: vec![bytes.to_vec()], 334 is_sensitive: false, 335 }) 336 } 337 338 /// Consume another `HeaderValue`, and then appends it to this 339 /// `HeaderValue`. 340 /// 341 /// # Examples 342 /// 343 /// ``` 344 /// use ylong_http::headers::HeaderValue; 345 /// 346 /// let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 347 /// let other = HeaderValue::from_bytes(b"text/plain").unwrap(); 348 /// 349 /// value.append(other); 350 /// assert_eq!(value.to_string().unwrap(), "text/html, text/plain"); 351 /// ``` append(&mut self, mut other: Self)352 pub fn append(&mut self, mut other: Self) { 353 self.inner.append(&mut other.inner) 354 } 355 356 /// Appends a new bytes to `HeaderValue`. 357 /// 358 /// # Examples 359 /// 360 /// ``` 361 /// use ylong_http::headers::HeaderValue; 362 /// 363 /// let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 364 /// value.append_bytes(b"application/xml").unwrap(); 365 /// 366 /// assert_eq!(value.to_string().unwrap(), "text/html, application/xml"); 367 /// ``` append_bytes(&mut self, bytes: &[u8]) -> Result<(), HttpError>368 pub fn append_bytes(&mut self, bytes: &[u8]) -> Result<(), HttpError> { 369 if !bytes.iter().all(|b| Self::is_valid(*b)) { 370 return Err(ErrorKind::InvalidInput.into()); 371 } 372 self.inner.push(bytes.to_vec()); 373 Ok(()) 374 } 375 376 /// Outputs the content of value as a string in a certain way. 377 /// 378 /// If there are characters that cannot be displayed in value, return `Err`. 379 /// Extra comma and whitespace(", ") will be added between each element of 380 /// value. 381 /// 382 /// # Examples 383 /// 384 /// ``` 385 /// use ylong_http::headers::HeaderValue; 386 /// 387 /// let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 388 /// value.append_bytes(b"application/xml").unwrap(); 389 /// 390 /// assert_eq!(value.to_string().unwrap(), "text/html, application/xml"); 391 /// ``` to_string(&self) -> Result<String, HttpError>392 pub fn to_string(&self) -> Result<String, HttpError> { 393 let mut content = Vec::new(); 394 for (n, i) in self.inner.iter().enumerate() { 395 if n != 0 { 396 content.extend_from_slice(b", "); 397 } 398 content.extend_from_slice(i.as_slice()); 399 } 400 Ok(unsafe { String::from_utf8_unchecked(content) }) 401 } 402 403 /// Outputs the content of value as a Vec<u8> in a certain way. to_vec(&self) -> Vec<u8>404 pub(crate) fn to_vec(&self) -> Vec<u8> { 405 let mut content = Vec::new(); 406 for (n, i) in self.inner.iter().enumerate() { 407 if n != 0 { 408 content.extend_from_slice(b", "); 409 } 410 content.extend_from_slice(i.as_slice()); 411 } 412 content 413 } 414 415 /// Returns an iterator over the `HeaderValue`. 416 /// 417 /// # Examples 418 /// 419 /// ``` 420 /// use ylong_http::headers::HeaderValue; 421 /// 422 /// let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 423 /// value.append_bytes(b"application/xml").unwrap(); 424 /// 425 /// for sub_value in value.iter() { 426 /// // Operate on each sub-value. 427 /// } 428 /// ``` iter(&self) -> HeaderValueIter<'_>429 pub fn iter(&self) -> HeaderValueIter<'_> { 430 self.inner.iter() 431 } 432 433 /// Returns an iterator that allows modifying each sub-value. 434 /// 435 /// # Examples 436 /// 437 /// ``` 438 /// use ylong_http::headers::HeaderValue; 439 /// 440 /// let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 441 /// value.append_bytes(b"application/xml").unwrap(); 442 /// 443 /// for sub_value in value.iter_mut() { 444 /// // Operate on each sub-value. 445 /// } 446 /// ``` iter_mut(&mut self) -> HeaderValueIterMut<'_>447 pub fn iter_mut(&mut self) -> HeaderValueIterMut<'_> { 448 self.inner.iter_mut() 449 } 450 451 /// Sets the sensitivity of value. 452 /// 453 /// # Examples 454 /// 455 /// ``` 456 /// use ylong_http::headers::HeaderValue; 457 /// 458 /// let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 459 /// assert!(!value.is_sensitive()); 460 /// 461 /// value.set_sensitive(true); 462 /// assert!(value.is_sensitive()); 463 /// ``` set_sensitive(&mut self, is_sensitive: bool)464 pub fn set_sensitive(&mut self, is_sensitive: bool) { 465 self.is_sensitive = is_sensitive; 466 } 467 468 /// Returns `true` if the value represents sensitive data. 469 /// 470 /// # Examples 471 /// 472 /// ``` 473 /// use ylong_http::headers::HeaderValue; 474 /// 475 /// let value = HeaderValue::from_bytes(b"text/html").unwrap(); 476 /// assert!(!value.is_sensitive()); 477 /// ``` is_sensitive(&self) -> bool478 pub fn is_sensitive(&self) -> bool { 479 self.is_sensitive 480 } 481 482 /// Returns `true` if the character matches the rules of `HeaderValue`. is_valid(b: u8) -> bool483 fn is_valid(b: u8) -> bool { 484 b >= 32 && b != 127 || b == b'\t' 485 } 486 } 487 488 impl TryFrom<&str> for HeaderValue { 489 type Error = HttpError; 490 try_from(value: &str) -> Result<Self, Self::Error>491 fn try_from(value: &str) -> Result<Self, Self::Error> { 492 Self::from_bytes(value.as_bytes()) 493 } 494 } 495 496 // `HeaderValue` can use `%x80-FF` u8 in [`RFC9110`]. 497 // [`RFC9110`]: https://www.rfc-editor.org/rfc/rfc9110.html#name-field-values 498 // 499 // |======================================================================== 500 // | field-value = *field-content | 501 // | field-content = field-vchar | 502 // | [ 1*( SP / HTAB / field-vchar ) field-vchar ] | 503 // | field-vchar = VCHAR / obs-text | 504 // | obs-text = %x80-FF | 505 // |======================================================================== 506 impl TryFrom<&[u8]> for HeaderValue { 507 type Error = HttpError; 508 try_from(value: &[u8]) -> Result<Self, Self::Error>509 fn try_from(value: &[u8]) -> Result<Self, Self::Error> { 510 Self::from_bytes(value) 511 } 512 } 513 514 /// Immutable `HeaderValue` iterator. 515 /// 516 /// This struct is created by [`HeaderValue::iter`]. 517 /// 518 /// [`HeaderValue::iter`]: HeaderValue::iter 519 /// 520 /// # Examples 521 /// 522 /// ``` 523 /// use ylong_http::headers::HeaderValue; 524 /// 525 /// let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 526 /// value.append_bytes(b"application/xml").unwrap(); 527 /// 528 /// for sub_value in value.iter() { 529 /// // Operate on each sub-value. 530 /// } 531 /// ``` 532 pub type HeaderValueIter<'a> = slice::Iter<'a, Vec<u8>>; 533 534 /// Mutable `HeaderValue` iterator. 535 /// 536 /// This struct is created by [`HeaderValue::iter_mut`]. 537 /// 538 /// [`HeaderValue::iter_mut`]: HeaderValue::iter_mut 539 /// 540 /// # Examples 541 /// 542 /// ``` 543 /// use ylong_http::headers::HeaderValue; 544 /// 545 /// let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 546 /// value.append_bytes(b"application/xml").unwrap(); 547 /// 548 /// for sub_value in value.iter_mut() { 549 /// // Operate on each sub-value. 550 /// } 551 /// ``` 552 pub type HeaderValueIterMut<'a> = slice::IterMut<'a, Vec<u8>>; 553 554 /// HTTP `Headers`, which is called [`Fields`] in RFC9110. 555 /// 556 /// Fields are sent and received within the header and trailer sections of 557 /// messages. 558 /// 559 /// [`Fields`]: https://httpwg.org/specs/rfc9110.html#fields 560 /// 561 /// # Examples 562 /// 563 /// ``` 564 /// use ylong_http::headers::Headers; 565 /// 566 /// let mut headers = Headers::new(); 567 /// headers.insert("Accept", "text/html").unwrap(); 568 /// headers.insert("Content-Length", "3495").unwrap(); 569 /// headers.append("Accept", "text/plain").unwrap(); 570 /// 571 /// assert_eq!( 572 /// headers.get("accept").unwrap().to_string().unwrap(), 573 /// "text/html, text/plain" 574 /// ); 575 /// assert_eq!( 576 /// headers.get("content-length").unwrap().to_string().unwrap(), 577 /// "3495" 578 /// ); 579 /// ``` 580 #[derive(Clone, Debug, Default, Eq, PartialEq)] 581 pub struct Headers { 582 map: HashMap<HeaderName, HeaderValue>, 583 } 584 585 impl fmt::Display for Headers { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result586 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 587 for (k, v) in self.iter() { 588 writeln!( 589 f, 590 "{}: {}", 591 k.to_string(), 592 v.to_string() 593 .unwrap_or_else(|_| "<non-visible header value>".to_string()) 594 )?; 595 } 596 Ok(()) 597 } 598 } 599 600 impl Headers { 601 /// Creates a new, empty `Headers`. 602 /// 603 /// # Examples 604 /// 605 /// ``` 606 /// use ylong_http::headers::Headers; 607 /// 608 /// let headers = Headers::new(); 609 /// assert!(headers.is_empty()); 610 /// ``` new() -> Self611 pub fn new() -> Self { 612 Headers { 613 map: HashMap::new(), 614 } 615 } 616 617 /// Returns the number of header in the `Headers`. 618 /// 619 /// # Examples 620 /// 621 /// ``` 622 /// use ylong_http::headers::Headers; 623 /// 624 /// let mut headers = Headers::new(); 625 /// assert_eq!(headers.len(), 0); 626 /// 627 /// headers.insert("accept", "text/html").unwrap(); 628 /// assert_eq!(headers.len(), 1); 629 /// ``` len(&self) -> usize630 pub fn len(&self) -> usize { 631 self.map.len() 632 } 633 634 /// Returns `true` if the `Headers` contains no headers. 635 /// 636 /// # Examples 637 /// 638 /// ``` 639 /// use ylong_http::headers::Headers; 640 /// 641 /// let mut headers = Headers::new(); 642 /// assert!(headers.is_empty()); 643 /// 644 /// headers.insert("accept", "text/html").unwrap(); 645 /// assert!(!headers.is_empty()); 646 /// ``` is_empty(&self) -> bool647 pub fn is_empty(&self) -> bool { 648 self.map.is_empty() 649 } 650 651 /// Returns an immutable reference to the `HeaderValue` corresponding to 652 /// the `HeaderName`. 653 /// 654 /// This method returns `None` if the input argument could not be 655 /// successfully converted to a `HeaderName` or the `HeaderName` is not in 656 /// `Headers`. 657 /// 658 /// # Examples 659 /// 660 /// ``` 661 /// use ylong_http::headers::Headers; 662 /// 663 /// let mut headers = Headers::new(); 664 /// headers.append("accept", "text/html").unwrap(); 665 /// 666 /// let value = headers.get("accept"); 667 /// assert_eq!(value.unwrap().to_string().unwrap(), "text/html"); 668 /// ``` get<T>(&self, name: T) -> Option<&HeaderValue> where HeaderName: TryFrom<T>,669 pub fn get<T>(&self, name: T) -> Option<&HeaderValue> 670 where 671 HeaderName: TryFrom<T>, 672 { 673 HeaderName::try_from(name) 674 .ok() 675 .and_then(|name| self.map.get(&name)) 676 } 677 678 /// Returns a mutable reference to the `HeaderValue` corresponding to 679 /// the `HeaderName`. 680 /// 681 /// This method returns `None` if the input argument could not be 682 /// successfully converted to a `HeaderName` or the `HeaderName` is not in 683 /// `Headers`. 684 /// 685 /// # Examples 686 /// 687 /// ``` 688 /// use ylong_http::headers::Headers; 689 /// 690 /// let mut headers = Headers::new(); 691 /// headers.append("accept", "text/html").unwrap(); 692 /// 693 /// let value = headers.get_mut("accept"); 694 /// assert_eq!(value.unwrap().to_string().unwrap(), "text/html"); 695 /// ``` get_mut<T>(&mut self, name: T) -> Option<&mut HeaderValue> where HeaderName: TryFrom<T>,696 pub fn get_mut<T>(&mut self, name: T) -> Option<&mut HeaderValue> 697 where 698 HeaderName: TryFrom<T>, 699 { 700 HeaderName::try_from(name) 701 .ok() 702 .and_then(move |name| self.map.get_mut(&name)) 703 } 704 705 /// Inserts a `Header` into the `Headers`. 706 /// 707 /// If the input argument could not be successfully converted to a `Header`, 708 /// `Err` is returned. 709 /// 710 /// If the `Headers` did not have this `HeaderName` present, `None` is 711 /// returned. 712 /// 713 /// If the `Headers` did have this `HeaderName` present, the new 714 /// `HeaderValue` is updated, and the old `HeaderValue` is returned. 715 /// 716 /// # Examples 717 /// 718 /// ``` 719 /// use ylong_http::headers::Headers; 720 /// 721 /// let mut headers = Headers::new(); 722 /// assert!(headers.insert("\0", "illegal header").is_err()); 723 /// 724 /// assert_eq!(headers.insert("accept", "text/html"), Ok(None)); 725 /// 726 /// let old_value = headers.insert("accept", "text/plain").unwrap(); 727 /// assert_eq!(old_value.unwrap().to_string().unwrap(), "text/html"); 728 /// ``` insert<N, V>(&mut self, name: N, value: V) -> Result<Option<HeaderValue>, HttpError> where HeaderName: TryFrom<N>, <HeaderName as TryFrom<N>>::Error: Into<HttpError>, HeaderValue: TryFrom<V>, <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,729 pub fn insert<N, V>(&mut self, name: N, value: V) -> Result<Option<HeaderValue>, HttpError> 730 where 731 HeaderName: TryFrom<N>, 732 <HeaderName as TryFrom<N>>::Error: Into<HttpError>, 733 HeaderValue: TryFrom<V>, 734 <HeaderValue as TryFrom<V>>::Error: Into<HttpError>, 735 { 736 let name = HeaderName::try_from(name).map_err(Into::into)?; 737 let value = HeaderValue::try_from(value).map_err(Into::into)?; 738 Ok(self.map.insert(name, value)) 739 } 740 741 /// Appends a `Header` to the `Headers`. 742 /// 743 /// If the input argument could not be successfully converted to a `Header`, 744 /// `Err` is returned. 745 /// 746 /// If the `Headers` did not have this `HeaderName` present, this `Header` 747 /// is inserted into the `Headers`. 748 /// 749 /// If the `Headers` did have this `HeaderName` present, the new 750 /// `HeaderValue` is appended to the old `HeaderValue`. 751 /// 752 /// # Examples 753 /// 754 /// ``` 755 /// use ylong_http::headers::Headers; 756 /// 757 /// let mut headers = Headers::new(); 758 /// assert!(headers.append("\0", "illegal header").is_err()); 759 /// 760 /// headers.append("accept", "text/html").unwrap(); 761 /// headers.append("accept", "text/plain").unwrap(); 762 /// 763 /// let value = headers.get("accept"); 764 /// assert_eq!(value.unwrap().to_string().unwrap(), "text/html, text/plain"); 765 /// ``` append<N, V>(&mut self, name: N, value: V) -> Result<(), HttpError> where HeaderName: TryFrom<N>, <HeaderName as TryFrom<N>>::Error: Into<HttpError>, HeaderValue: TryFrom<V>, <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,766 pub fn append<N, V>(&mut self, name: N, value: V) -> Result<(), HttpError> 767 where 768 HeaderName: TryFrom<N>, 769 <HeaderName as TryFrom<N>>::Error: Into<HttpError>, 770 HeaderValue: TryFrom<V>, 771 <HeaderValue as TryFrom<V>>::Error: Into<HttpError>, 772 { 773 let name = HeaderName::try_from(name).map_err(Into::into)?; 774 let value = HeaderValue::try_from(value).map_err(Into::into)?; 775 776 match self.map.entry(name) { 777 Entry::Occupied(o) => { 778 o.into_mut().append(value); 779 } 780 Entry::Vacant(v) => { 781 let _ = v.insert(value); 782 } 783 }; 784 Ok(()) 785 } 786 787 /// Removes `Header` from `Headers` by `HeaderName`, returning the 788 /// `HeaderValue` at the `HeaderName` if the `HeaderName` was previously 789 /// in the `Headers`. 790 /// 791 /// If the input argument could not be successfully converted to a `Header`, 792 /// `None` is returned. 793 /// 794 /// # Examples 795 /// 796 /// ``` 797 /// use ylong_http::headers::Headers; 798 /// 799 /// let mut headers = Headers::new(); 800 /// headers.append("accept", "text/html").unwrap(); 801 /// 802 /// let value = headers.remove("accept"); 803 /// assert_eq!(value.unwrap().to_string().unwrap(), "text/html"); 804 /// ``` remove<T>(&mut self, name: T) -> Option<HeaderValue> where HeaderName: TryFrom<T>,805 pub fn remove<T>(&mut self, name: T) -> Option<HeaderValue> 806 where 807 HeaderName: TryFrom<T>, 808 { 809 HeaderName::try_from(name) 810 .ok() 811 .and_then(|name| self.map.remove(&name)) 812 } 813 814 /// Returns an iterator over the `Headers`. The iterator element type is 815 /// `(&'a HeaderName, &'a HeaderValue)`. 816 /// 817 /// # Examples 818 /// 819 /// ``` 820 /// use ylong_http::headers::Headers; 821 /// 822 /// let mut headers = Headers::new(); 823 /// headers.append("accept", "text/html").unwrap(); 824 /// 825 /// for (_name, _value) in headers.iter() { 826 /// // Operate on each `HeaderName` and `HeaderValue` pair. 827 /// } 828 /// ``` iter(&self) -> HeadersIter<'_>829 pub fn iter(&self) -> HeadersIter<'_> { 830 self.map.iter() 831 } 832 833 /// Returns an iterator over the `Headers`. The iterator element type is 834 /// `(&'a HeaderName, &'a mut HeaderValue)`. 835 /// 836 /// # Examples 837 /// 838 /// ``` 839 /// use ylong_http::headers::Headers; 840 /// 841 /// let mut headers = Headers::new(); 842 /// headers.append("accept", "text/html").unwrap(); 843 /// 844 /// for (_name, _value) in headers.iter_mut() { 845 /// // Operate on each `HeaderName` and `HeaderValue` pair. 846 /// } 847 /// ``` iter_mut(&mut self) -> HeadersIterMut<'_>848 pub fn iter_mut(&mut self) -> HeadersIterMut<'_> { 849 self.map.iter_mut() 850 } 851 } 852 853 impl IntoIterator for Headers { 854 type Item = (HeaderName, HeaderValue); 855 type IntoIter = HeadersIntoIter; 856 857 /// Creates a consuming iterator, that is, one that moves each `HeaderName` 858 /// and `HeaderValue` pair out of the `Headers` in arbitrary order. The 859 /// `Headers` cannot be used after calling this. 860 /// 861 /// # Examples 862 /// 863 /// ``` 864 /// use ylong_http::headers::Headers; 865 /// 866 /// let mut headers = Headers::new(); 867 /// headers.append("accept", "text/html").unwrap(); 868 /// 869 /// for (_name, _value) in headers.into_iter() { 870 /// // Operate on each `HeaderName` and `HeaderValue` pair. 871 /// } 872 /// ``` into_iter(self) -> Self::IntoIter873 fn into_iter(self) -> Self::IntoIter { 874 self.map.into_iter() 875 } 876 } 877 878 impl<'a> IntoIterator for &'a Headers { 879 type Item = (&'a HeaderName, &'a HeaderValue); 880 type IntoIter = HeadersIter<'a>; 881 into_iter(self) -> Self::IntoIter882 fn into_iter(self) -> Self::IntoIter { 883 self.iter() 884 } 885 } 886 887 impl<'a> IntoIterator for &'a mut Headers { 888 type Item = (&'a HeaderName, &'a mut HeaderValue); 889 type IntoIter = HeadersIterMut<'a>; 890 into_iter(self) -> Self::IntoIter891 fn into_iter(self) -> Self::IntoIter { 892 self.iter_mut() 893 } 894 } 895 896 /// Immutable `Headers` iterator. 897 /// 898 /// This struct is created by [`Headers::iter`]. 899 /// 900 /// [`Headers::iter`]: Headers::iter 901 /// 902 /// # Examples 903 /// 904 /// ``` 905 /// use ylong_http::headers::Headers; 906 /// 907 /// let mut headers = Headers::new(); 908 /// headers.append("accept", "text/html").unwrap(); 909 /// 910 /// for (_name, _value) in headers.iter() { 911 /// // Operate on each `HeaderName` and `HeaderValue` pair. 912 /// } 913 /// ``` 914 pub type HeadersIter<'a> = hash_map::Iter<'a, HeaderName, HeaderValue>; 915 916 /// Mutable `Headers` iterator. 917 /// 918 /// This struct is created by [`Headers::iter_mut`]. 919 /// 920 /// [`Headers::iter_mut`]: Headers::iter_mut 921 /// 922 /// # Examples 923 /// 924 /// ``` 925 /// use ylong_http::headers::Headers; 926 /// 927 /// let mut headers = Headers::new(); 928 /// headers.append("accept", "text/html").unwrap(); 929 /// 930 /// for (_name, _value) in headers.iter_mut() { 931 /// // Operate on each `HeaderName` and `HeaderValue` pair. 932 /// } 933 /// ``` 934 pub type HeadersIterMut<'a> = hash_map::IterMut<'a, HeaderName, HeaderValue>; 935 936 /// An owning iterator over the entries of a `Headers`. 937 /// 938 /// This struct is created by [`Headers::into_iter`]. 939 /// 940 /// [`Headers::into_iter`]: crate::headers::Headers::into_iter 941 /// 942 /// # Examples 943 /// 944 /// ``` 945 /// use ylong_http::headers::Headers; 946 /// 947 /// let mut headers = Headers::new(); 948 /// headers.append("accept", "text/html").unwrap(); 949 /// 950 /// for (_name, _value) in headers.into_iter() { 951 /// // Operate on each `HeaderName` and `HeaderValue` pair. 952 /// } 953 /// ``` 954 pub type HeadersIntoIter = hash_map::IntoIter<HeaderName, HeaderValue>; 955 956 // HEADER_CHARS is used to check whether char is correct and transfer to 957 // lowercase. 958 #[rustfmt::skip] 959 const HEADER_CHARS: [u8; 256] = [ 960 // 0 1 2 3 4 5 6 7 8 9 961 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x 962 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x 963 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x 964 0, 0, b' ', b'!', b'"', b'#', b'$', b'%', b'&', b'\'', // 3x 965 0, 0, b'*', b'+', b',', b'-', b'.', b'/', b'0', b'1', // 4x 966 b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', 0, 0, // 5x 967 0, 0, 0, 0, 0, b'a', b'b', b'c', b'd', b'e', // 6x 968 b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o', // 7x 969 b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', b'x', b'y', // 8x 970 b'z', 0, 0, 0, b'^', b'_', b'`', b'a', b'b', b'c', // 9x 971 b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', // 10x 972 b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', // 11x 973 b'x', b'y', b'z', 0, b'|', 0, b'~', 0, 0, 0, // 12x 974 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13x 975 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14x 976 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15x 977 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16x 978 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x 979 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 18x 980 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 19x 981 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20x 982 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 21x 983 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 22x 984 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 23x 985 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 24x 986 0, 0, 0, 0, 0, 0, // 25x 987 ]; 988 989 #[cfg(test)] 990 mod ut_headers { 991 use std::collections::HashMap; 992 993 use crate::headers::{Header, HeaderName, HeaderValue, Headers}; 994 995 /// UT test cases for `HeaderName::from_bytes`. 996 /// 997 /// # Brief 998 /// 1. Creates a `HeaderName` by calling `HeaderName::from_bytes`. 999 /// 2. Checks if the test results are correct. 1000 #[test] ut_header_name_from_bytes()1001 fn ut_header_name_from_bytes() { 1002 let name = String::from("accept"); 1003 assert_eq!( 1004 HeaderName::from_bytes(b"ACCEPT"), 1005 Ok(HeaderName { name: name.clone() }) 1006 ); 1007 assert_eq!(HeaderName::from_bytes(b"accept"), Ok(HeaderName { name })); 1008 } 1009 1010 /// UT test cases for `HeaderName::as_bytes`. 1011 /// 1012 /// # Brief 1013 /// 1. Creates a `HeaderName`. 1014 /// 2. Fetches content from `HeaderName` by calling `HeaderName::as_bytes`. 1015 /// 3. Checks if the test results are correct. 1016 #[test] ut_header_name_as_bytes()1017 fn ut_header_name_as_bytes() { 1018 let name = HeaderName { 1019 name: "accept".to_string(), 1020 }; 1021 assert_eq!(name.as_bytes(), b"accept"); 1022 } 1023 1024 /// UT test cases for `HeaderValue::from_bytes`. 1025 /// 1026 /// # Brief 1027 /// 1. Creates a `HeaderValue` by calling `HeaderValue::from_bytes`. 1028 /// 2. Checks if the test results are correct. 1029 #[test] ut_header_value_from_bytes()1030 fn ut_header_value_from_bytes() { 1031 let value = HeaderValue::from_bytes(b"teXt/hTml, APPLICATION/xhtml+xml, application/xml"); 1032 let result = Ok(HeaderValue { 1033 inner: vec![b"teXt/hTml, APPLICATION/xhtml+xml, application/xml".to_vec()], 1034 is_sensitive: false, 1035 }); 1036 assert_eq!(value, result); 1037 } 1038 1039 /// UT test cases for `Header::from_raw_parts, name, value, into_parts`. 1040 /// 1041 /// # Brief 1042 /// 1. Creates a `Header`. 1043 /// 2. Calls Header::from_raw_parts, name, value and into_parts 1044 /// respectively. 1045 /// 3. Checks if the test results are corrent. 1046 #[test] ut_header_methods()1047 fn ut_header_methods() { 1048 // from_raw_parts 1049 let name = HeaderName::from_bytes(b"John-Doe").unwrap(); 1050 let value = HeaderValue::from_bytes(b"Foo").unwrap(); 1051 let header = Header::from_raw_parts(name, value); 1052 assert_eq!(header.name().as_bytes(), b"john-doe"); 1053 assert_eq!(header.value().to_string().unwrap(), "Foo"); 1054 assert_ne!(header.name().as_bytes(), b"John-Doe"); 1055 assert_ne!(header.value().to_string().unwrap(), "foo"); 1056 1057 // name 1058 let name = header.name(); 1059 assert_eq!(name.as_bytes(), b"john-doe"); 1060 assert_ne!(name.as_bytes(), b"John-Doe"); 1061 assert_ne!(name.as_bytes(), b"jane-doe"); 1062 1063 // value 1064 let value = header.value(); 1065 assert_eq!(value.to_string().unwrap(), "Foo"); 1066 assert_ne!(value.to_string().unwrap(), "foo"); 1067 assert_ne!(value.to_string().unwrap(), "oof"); 1068 1069 // into_parts 1070 let (name, value) = header.into_parts(); 1071 assert_eq!(name.as_bytes(), b"john-doe"); 1072 assert_eq!(value.to_string().unwrap(), "Foo"); 1073 assert_ne!(name.as_bytes(), b"John-Doe"); 1074 assert_ne!(value.to_string().unwrap(), "foo"); 1075 } 1076 1077 /// UT test cases for `HeaderValue::iter`. 1078 /// 1079 /// # Brief 1080 /// 1. Creates a `HeaderValue`. 1081 /// 2. Loops through the values by calling `HeaderValue::iter`. 1082 /// 3. Checks if the test results are correct. 1083 #[test] ut_header_value_iter()1084 fn ut_header_value_iter() { 1085 let mut value = HeaderValue::from_bytes(b"text/html").unwrap(); 1086 value.append_bytes(b"application/xml").unwrap(); 1087 let value_to_compare = ["text/html", "application/xml"]; 1088 1089 for (index, sub_value) in value.iter().enumerate() { 1090 assert_eq!(sub_value, value_to_compare[index].as_bytes()); 1091 } 1092 1093 for (index, sub_value) in value.iter_mut().enumerate() { 1094 assert_eq!(sub_value, value_to_compare[index].as_bytes()); 1095 } 1096 } 1097 1098 /// UT test cases for `HeaderValue::is_sensitive`. 1099 /// 1100 /// # Brief 1101 /// 1. Creates a `HeaderValue`. 1102 /// 2. Calls `HeaderValue::is_sensitive` to check if the test results are 1103 /// correct. 1104 #[test] ut_header_value_is_sensitive()1105 fn ut_header_value_is_sensitive() { 1106 let mut value = HeaderValue { 1107 inner: vec![b"text/html, application/xhtml+xml".to_vec()], 1108 is_sensitive: true, 1109 }; 1110 assert!(value.is_sensitive()); 1111 value.is_sensitive = false; 1112 assert!(!value.is_sensitive()); 1113 } 1114 1115 /// UT test cases for `Headers::get_mut`. 1116 /// 1117 /// # Brief 1118 /// 1. Creates a `Headers`. 1119 /// 2. Gets the mutable `HeaderValue` by calling 1120 /// `HeaderValue::append_bytes`. 1121 /// 3. Modifies `HeaderValue`. 1122 /// 3. Checks if the test results are correct. 1123 #[test] ut_headers_get_mut()1124 fn ut_headers_get_mut() { 1125 let mut headers = Headers::new(); 1126 headers.append("accept", "text/css").unwrap(); 1127 let value = headers.get_mut("accept").unwrap(); 1128 assert!(!value.is_sensitive()); 1129 value.is_sensitive = true; 1130 assert!(value.is_sensitive()); 1131 } 1132 1133 /// UT test cases for `HeaderValue::append_bytes`. 1134 /// 1135 /// # Brief 1136 /// 1. Creates a `HeaderValue`. 1137 /// 2. Adds new value content into `HeaderValue` by calling 1138 /// `HeaderValue::append_bytes`. 1139 /// 3. Checks if the test results are correct. 1140 #[test] ut_header_value_append_bytes()1141 fn ut_header_value_append_bytes() { 1142 let mut value = HeaderValue { 1143 inner: vec![b"text/html, application/xhtml+xml".to_vec()], 1144 is_sensitive: false, 1145 }; 1146 assert!(value.append_bytes(b"teXt/plain, teXt/css").is_ok()); 1147 assert!(value.append_bytes(b"application/xml").is_ok()); 1148 1149 let res = HeaderValue { 1150 inner: vec![ 1151 b"text/html, application/xhtml+xml".to_vec(), 1152 b"teXt/plain, teXt/css".to_vec(), 1153 b"application/xml".to_vec(), 1154 ], 1155 is_sensitive: false, 1156 }; 1157 assert_eq!(value, res); 1158 } 1159 1160 /// UT test cases for `HeaderValue::to_string`. 1161 /// 1162 /// # Brief 1163 /// 1. Creates a `HeaderValue`. 1164 /// 2. Gets content of `HeaderValue` by calling `HeaderName::to_string`. 1165 /// 3. Checks if the test results are correct. 1166 #[test] ut_header_value_to_string()1167 fn ut_header_value_to_string() { 1168 let value = HeaderValue { 1169 inner: vec![ 1170 b"text/html, application/xhtml+xml".to_vec(), 1171 b"text/plain, text/css".to_vec(), 1172 b"application/xml".to_vec(), 1173 ], 1174 is_sensitive: false, 1175 }; 1176 1177 let result = 1178 "text/html, application/xhtml+xml, text/plain, text/css, application/xml".to_string(); 1179 assert_eq!(value.to_string(), Ok(result)); 1180 } 1181 1182 /// UT test cases for `HeaderValue::set_sensitive`. 1183 /// 1184 /// # Brief 1185 /// 1. Creates a `HeaderValue`. 1186 /// 2. Sets content of `HeaderValue` by calling `HeaderName::set_sensitive`. 1187 /// 3. Checks if the test results are correct. 1188 #[test] ut_header_value_set_sensitive()1189 fn ut_header_value_set_sensitive() { 1190 let mut value = HeaderValue { 1191 inner: vec![], 1192 is_sensitive: false, 1193 }; 1194 1195 value.set_sensitive(true); 1196 assert!(value.is_sensitive); 1197 } 1198 1199 /// UT test cases for `Headers::new`. 1200 /// 1201 /// # Brief 1202 /// 1. Creates `Headers` by calling `Headers::new`. 1203 /// 2. Checks if the test results are correct. 1204 #[test] ut_headers_new()1205 fn ut_headers_new() { 1206 assert_eq!( 1207 Headers::new(), 1208 Headers { 1209 map: HashMap::new() 1210 } 1211 ); 1212 } 1213 1214 /// UT test cases for `ut_change_headers_info`. 1215 /// 1216 /// # Brief 1217 /// 1. Creates Headers 1218 /// 2. Adds content type `(&str, &str)` by calling append(). 1219 /// 3. Uses new content to replace old content by calling insert(). 1220 /// 4. Uses `HeaderName` to fetch `HeaderValue` by calling get(). 1221 /// 5. Uses `HeaderNam`e to remove `HeaderValu`e by calling remove(). 1222 /// 6. Checks if the test result is correct by assert_eq!(). 1223 #[test] ut_change_headers_info()1224 fn ut_change_headers_info() { 1225 let mut new_headers = Headers::new(); 1226 if new_headers.is_empty() { 1227 let _ = new_headers.append("ACCEPT", "text/html"); 1228 } 1229 let map_len = new_headers.len(); 1230 assert_eq!(map_len, 1); 1231 1232 let mut verify_map = HashMap::new(); 1233 verify_map.insert( 1234 HeaderName { 1235 name: "accept".to_string(), 1236 }, 1237 HeaderValue { 1238 inner: [b"text/html".to_vec()].to_vec(), 1239 is_sensitive: false, 1240 }, 1241 ); 1242 let headers_map = &new_headers.map; 1243 assert_eq!(headers_map, &verify_map); 1244 1245 let mut value_vec = Vec::new(); 1246 let inner_vec = b"text/html, application/xhtml+xml, application/xml".to_vec(); 1247 value_vec.push(inner_vec); 1248 let _ = new_headers.insert( 1249 "accept", 1250 "text/html, application/xhtml+xml, application/xml", 1251 ); 1252 1253 let header_value = new_headers.get("accept").unwrap(); 1254 let verify_value = HeaderValue { 1255 inner: value_vec, 1256 is_sensitive: false, 1257 }; 1258 assert_eq!(header_value, &verify_value); 1259 1260 let remove_value = new_headers.remove("accept").unwrap(); 1261 assert_eq!( 1262 remove_value, 1263 HeaderValue { 1264 inner: [b"text/html, application/xhtml+xml, application/xml".to_vec()].to_vec(), 1265 is_sensitive: false 1266 } 1267 ); 1268 } 1269 1270 /// UT test cases for `Headers::iter`. 1271 /// 1272 /// # Brief 1273 /// 1. Creates a `Headers`. 1274 /// 2. Creates an iterator by calling `Headers::iter`. 1275 /// 3. Fetches `HeaderValue` content by calling `HeadersIter::next`. 1276 /// 4. Checks if the test results are correct. 1277 #[test] ut_headers_iter()1278 fn ut_headers_iter() { 1279 let mut headers = Headers::new(); 1280 assert!(headers.append("ACCEPT", "text/html").is_ok()); 1281 1282 let mut iter = headers.iter(); 1283 assert_eq!( 1284 iter.next(), 1285 Some(( 1286 &HeaderName { 1287 name: "accept".to_string() 1288 }, 1289 &HeaderValue { 1290 inner: [b"text/html".to_vec()].to_vec(), 1291 is_sensitive: false 1292 } 1293 )) 1294 ); 1295 assert_eq!(iter.next(), None); 1296 } 1297 } 1298