Line data Source code
1 : //
2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/http_proto
8 : //
9 :
10 : #include <boost/http_proto/rfc/transfer_encoding_rule.hpp>
11 : #include <boost/http_proto/rfc/token_rule.hpp>
12 : #include <boost/http_proto/rfc/detail/rules.hpp>
13 : #include <boost/url/grammar/ci_string.hpp>
14 : #include <boost/url/grammar/parse.hpp>
15 :
16 : namespace boost {
17 : namespace http_proto {
18 :
19 : //------------------------------------------------
20 :
21 : namespace detail {
22 :
23 : /*
24 : tparams = *tparam
25 : tparam = OWS ";" OWS token BWS "=" BWS ( token / quoted-string )
26 : */
27 :
28 : struct tparam_rule_t
29 : {
30 : using value_type =
31 : transfer_coding::param;
32 :
33 : auto
34 49 : parse(
35 : char const*& it,
36 : char const* end) const noexcept ->
37 : system::result<value_type>
38 : {
39 49 : value_type t;
40 49 : auto it0 = it;
41 : // OWS
42 49 : it = grammar::find_if_not(
43 : it, end, ws);
44 : // ";"
45 49 : if(it == end)
46 : {
47 15 : it = it0;
48 15 : BOOST_HTTP_PROTO_RETURN_EC(
49 : grammar::error::need_more);
50 : }
51 34 : if(*it != ';')
52 : {
53 20 : it = it0;
54 20 : BOOST_HTTP_PROTO_RETURN_EC(
55 : grammar::error::mismatch);
56 : }
57 14 : ++it;
58 : // OWS
59 14 : it = grammar::find_if_not(
60 : it, end, ws);
61 : // token
62 : {
63 14 : auto rv = grammar::parse(
64 : it, end, token_rule);
65 14 : if(! rv)
66 0 : return rv.error();
67 14 : t.key = *rv;
68 : }
69 : // BWS
70 14 : it = grammar::find_if_not(
71 : it, end, ws);
72 : // "="
73 14 : if(it == end)
74 : {
75 0 : it = it0;
76 0 : BOOST_HTTP_PROTO_RETURN_EC(
77 : grammar::error::need_more);
78 : }
79 14 : if(*it != '=')
80 : {
81 0 : it = it0;
82 0 : BOOST_HTTP_PROTO_RETURN_EC(
83 : grammar::error::syntax);
84 : }
85 14 : ++it;
86 : // BWS
87 14 : it = grammar::find_if_not(
88 : it, end, ws);
89 : // quoted-token
90 : {
91 14 : auto rv = grammar::parse(
92 : it, end, quoted_token_rule);
93 14 : if(! rv)
94 0 : return rv.error();
95 14 : t.value = *rv;
96 : }
97 14 : return t;
98 : }
99 : };
100 :
101 : constexpr tparam_rule_t tparam_rule{};
102 :
103 : } // detail
104 :
105 : //------------------------------------------------
106 :
107 : auto
108 187 : transfer_coding_rule_t::
109 : parse(
110 : char const*& it,
111 : char const* end) const noexcept ->
112 : system::result<value_type>
113 : {
114 187 : value_type t;
115 : {
116 : // token
117 187 : auto rv = grammar::parse(
118 : it, end, token_rule);
119 187 : if(! rv)
120 8 : return rv.error();
121 179 : t.str = *rv;
122 :
123 : // These can't have tparams
124 179 : if(grammar::ci_is_equal(
125 : t.str, "chunked"))
126 : {
127 77 : t.id = transfer_coding::chunked;
128 77 : return t;
129 : }
130 102 : if(grammar::ci_is_equal(
131 : t.str, "compress"))
132 : {
133 34 : t.id = transfer_coding::compress;
134 34 : return t;
135 : }
136 68 : if(grammar::ci_is_equal(
137 : t.str, "deflate"))
138 : {
139 7 : t.id = transfer_coding::deflate;
140 7 : return t;
141 : }
142 61 : if(grammar::ci_is_equal(
143 : t.str, "gzip"))
144 : {
145 26 : t.id = transfer_coding::gzip;
146 26 : return t;
147 : }
148 : }
149 : // *( OWS ";" OWS token BWS "=" BWS ( token / quoted-string )
150 : {
151 : auto rv = grammar::parse(it, end,
152 35 : grammar::range_rule(
153 35 : detail::tparam_rule));
154 35 : if(! rv)
155 0 : return rv.error();
156 35 : t.params = std::move(*rv);
157 35 : }
158 35 : return t;
159 187 : }
160 :
161 : } // http_proto
162 : } // boost
|