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);