hyperx/header/common/
accept.rs

1use mime::{self, Mime};
2
3use header::{QualityItem, qitem};
4
5header! {
6    /// `Accept` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.2)
7    ///
8    /// The `Accept` header field can be used by user agents to specify
9    /// response media types that are acceptable.  Accept header fields can
10    /// be used to indicate that the request is specifically limited to a
11    /// small set of desired types, as in the case of a request for an
12    /// in-line image
13    ///
14    /// # ABNF
15    ///
16    /// ```text
17    /// Accept = #( media-range [ accept-params ] )
18    ///
19    /// media-range    = ( "*/*"
20    ///                  / ( type "/" "*" )
21    ///                  / ( type "/" subtype )
22    ///                  ) *( OWS ";" OWS parameter )
23    /// accept-params  = weight *( accept-ext )
24    /// accept-ext = OWS ";" OWS token [ "=" ( token / quoted-string ) ]
25    /// ```
26    ///
27    /// # Example values
28    /// * `audio/*; q=0.2, audio/basic`
29    /// * `text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c`
30    ///
31    /// # Examples
32    /// ```
33    /// # extern crate http;
34    /// use hyperx::header::{Accept, qitem, TypedHeaders};
35    /// use hyperx::mime;
36    ///
37    /// let mut headers = http::HeaderMap::new();
38    ///
39    /// headers.encode(
40    ///     &Accept(vec![
41    ///         qitem(mime::TEXT_HTML),
42    ///     ])
43    /// );
44    /// ```
45    ///
46    /// ```
47    /// # extern crate http;
48    /// use hyperx::header::{Accept, qitem, TypedHeaders};
49    /// use hyperx::mime;
50    ///
51    /// let mut headers = http::HeaderMap::new();
52    /// headers.encode(
53    ///     &Accept(vec![
54    ///         qitem(mime::APPLICATION_JSON),
55    ///     ])
56    /// );
57    /// ```
58    ///
59    /// ```
60    /// # extern crate http;
61    /// use hyperx::header::{Accept, QualityItem, q, qitem, TypedHeaders};
62    /// use hyperx::mime;
63    ///
64    /// let mut headers = http::HeaderMap::new();
65    ///
66    /// headers.encode(
67    ///     &Accept(vec![
68    ///         qitem(mime::TEXT_HTML),
69    ///         qitem("application/xhtml+xml".parse().unwrap()),
70    ///         QualityItem::new(
71    ///             mime::TEXT_XML,
72    ///             q(900)
73    ///         ),
74    ///         qitem("image/webp".parse().unwrap()),
75    ///         QualityItem::new(
76    ///             mime::STAR_STAR,
77    ///             q(800)
78    ///         ),
79    ///     ])
80    /// );
81    /// ```
82    (Accept, "Accept") => (QualityItem<Mime>)+
83
84    test_accept {
85        // Tests from the RFC
86         test_header!(
87            test1,
88            vec![b"audio/*; q=0.2, audio/basic"],
89            Some(HeaderField(vec![
90                QualityItem::new("audio/*".parse().unwrap(), q(200)),
91                qitem("audio/basic".parse().unwrap()),
92                ])));
93        test_header!(
94            test2,
95            vec![b"text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c"],
96            Some(HeaderField(vec![
97                QualityItem::new(TEXT_PLAIN, q(500)),
98                qitem(TEXT_HTML),
99                QualityItem::new(
100                    "text/x-dvi".parse().unwrap(),
101                    q(800)),
102                qitem("text/x-c".parse().unwrap()),
103                ])));
104        // Custom tests
105        test_header!(
106            test3,
107            vec![b"text/plain; charset=utf-8"],
108            Some(Accept(vec![
109                qitem(TEXT_PLAIN_UTF_8),
110                ])));
111        test_header!(
112            test4,
113            vec![b"text/plain; charset=utf-8; q=0.5"],
114            Some(Accept(vec![
115                QualityItem::new(TEXT_PLAIN_UTF_8,
116                    q(500)),
117            ])));
118
119        #[test]
120        fn test_fuzzing1() {
121            let raw: Raw = "chunk#;e".into();
122            let header = Accept::parse_header(&raw);
123            assert!(header.is_ok());
124        }
125    }
126}
127
128impl Accept {
129    /// A constructor to easily create `Accept: */*`.
130    pub fn star() -> Accept {
131        Accept(vec![qitem(mime::STAR_STAR)])
132    }
133
134    /// A constructor to easily create `Accept: application/json`.
135    pub fn json() -> Accept {
136        Accept(vec![qitem(mime::APPLICATION_JSON)])
137    }
138
139    /// A constructor to easily create `Accept: text/*`.
140    pub fn text() -> Accept {
141        Accept(vec![qitem(mime::TEXT_STAR)])
142    }
143
144    /// A constructor to easily create `Accept: image/*`.
145    pub fn image() -> Accept {
146        Accept(vec![qitem(mime::IMAGE_STAR)])
147    }
148}
149
150bench_header!(bench, Accept, { vec![b"text/plain; q=0.5, text/html".to_vec()] });
151
152standard_header!(Accept, ACCEPT);