static_web_server/headers_ext/
accept_encoding.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Original code by Parker Timmerman
3// Original code sourced from https://github.com/hyperium/headers/pull/70
4
5use headers::{Error, Header};
6use hyper::header::{HeaderName, HeaderValue, ACCEPT_ENCODING};
7
8use super::{ContentCoding, QualityValue};
9
10/// `Accept-Encoding` header, defined in
11/// [RFC7231](https://tools.ietf.org/html/rfc7231#section-5.3.4)
12///
13/// The `Accept-Encoding` header field can be used by user agents to
14/// indicate what response content-codings are acceptable in the response.
15/// An "identity" token is used as a synonym for "no encoding" in
16/// order to communicate when no encoding is preferred.
17///
18/// # ABNF
19///
20/// ```text
21/// Accept-Encoding  = #( codings [ weight ] )
22/// codings          = content-coding / "identity" / "*"
23/// ```
24///
25/// # Example Values
26///
27/// * `gzip`
28/// * `br;q=1.0, gzip;q=0.8`
29///
30#[derive(Clone, Debug)]
31pub(crate) struct AcceptEncoding(QualityValue);
32
33impl Header for AcceptEncoding {
34    fn name() -> &'static HeaderName {
35        &ACCEPT_ENCODING
36    }
37
38    fn decode<'i, I>(values: &mut I) -> Result<Self, Error>
39    where
40        I: Iterator<Item = &'i HeaderValue>,
41    {
42        QualityValue::try_from_values(values).map(Self)
43    }
44
45    fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
46        values.extend(std::iter::once((&self.0).into()))
47    }
48}
49
50impl AcceptEncoding {
51    /// Returns a quality sorted iterator of the `ContentCoding`
52    pub(crate) fn sorted_encodings(&self) -> impl Iterator<Item = ContentCoding> + '_ {
53        self.0.iter().map(ContentCoding::from)
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn from_static() {
63        let val = HeaderValue::from_static("deflate, zstd;q=0.7, gzip;q=1.0, br;q=0.9");
64        let accept_enc = AcceptEncoding(val.into());
65
66        let mut encodings = accept_enc.sorted_encodings();
67        assert_eq!(encodings.next(), Some(ContentCoding::DEFLATE));
68        assert_eq!(encodings.next(), Some(ContentCoding::GZIP));
69        assert_eq!(encodings.next(), Some(ContentCoding::BROTLI));
70        assert_eq!(encodings.next(), Some(ContentCoding::ZSTD));
71        assert_eq!(encodings.next(), None);
72    }
73}