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