1 use {Header, HeaderValue}; 2 3 /// `Content-Length` header, defined in 4 /// [RFC7230](http://tools.ietf.org/html/rfc7230#section-3.3.2) 5 /// 6 /// When a message does not have a `Transfer-Encoding` header field, a 7 /// Content-Length header field can provide the anticipated size, as a 8 /// decimal number of octets, for a potential payload body. For messages 9 /// that do include a payload body, the Content-Length field-value 10 /// provides the framing information necessary for determining where the 11 /// body (and message) ends. For messages that do not include a payload 12 /// body, the Content-Length indicates the size of the selected 13 /// representation. 14 /// 15 /// Note that setting this header will *remove* any previously set 16 /// `Transfer-Encoding` header, in accordance with 17 /// [RFC7230](http://tools.ietf.org/html/rfc7230#section-3.3.2): 18 /// 19 /// > A sender MUST NOT send a Content-Length header field in any message 20 /// > that contains a Transfer-Encoding header field. 21 /// 22 /// ## ABNF 23 /// 24 /// ```text 25 /// Content-Length = 1*DIGIT 26 /// ``` 27 /// 28 /// ## Example values 29 /// 30 /// * `3495` 31 /// 32 /// # Example 33 /// 34 /// ``` 35 /// # extern crate headers; 36 /// use headers::ContentLength; 37 /// 38 /// let len = ContentLength(1_000); 39 /// ``` 40 #[derive(Clone, Copy, Debug, PartialEq)] 41 pub struct ContentLength(pub u64); 42 43 impl Header for ContentLength { name() -> &'static ::http::header::HeaderName44 fn name() -> &'static ::http::header::HeaderName { 45 &::http::header::CONTENT_LENGTH 46 } 47 decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, ::Error>48 fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, ::Error> { 49 // If multiple Content-Length headers were sent, everything can still 50 // be alright if they all contain the same value, and all parse 51 // correctly. If not, then it's an error. 52 let mut len = None; 53 for value in values { 54 let parsed = value 55 .to_str() 56 .map_err(|_| ::Error::invalid())? 57 .parse::<u64>() 58 .map_err(|_| ::Error::invalid())?; 59 60 if let Some(prev) = len { 61 if prev != parsed { 62 return Err(::Error::invalid()); 63 } 64 } else { 65 len = Some(parsed); 66 } 67 } 68 69 len 70 .map(ContentLength) 71 .ok_or_else(::Error::invalid) 72 } 73 encode<E: Extend<::HeaderValue>>(&self, values: &mut E)74 fn encode<E: Extend<::HeaderValue>>(&self, values: &mut E) { 75 values.extend(::std::iter::once(self.0.into())); 76 } 77 } 78 79 /* 80 __hyper__tm!(ContentLength, tests { 81 // Testcase from RFC 82 test_header!(test1, vec![b"3495"], Some(HeaderField(3495))); 83 84 test_header!(test_invalid, vec![b"34v95"], None); 85 86 // Can't use the test_header macro because "5, 5" gets cleaned to "5". 87 #[test] 88 fn test_duplicates() { 89 let parsed = HeaderField::parse_header(&vec![b"5".to_vec(), 90 b"5".to_vec()].into()).unwrap(); 91 assert_eq!(parsed, HeaderField(5)); 92 assert_eq!(format!("{}", parsed), "5"); 93 } 94 95 test_header!(test_duplicates_vary, vec![b"5", b"6", b"5"], None); 96 }); 97 */ 98 99