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 : #ifndef BOOST_HTTP_PROTO_RFC_DETAIL_RULES_HPP
11 : #define BOOST_HTTP_PROTO_RFC_DETAIL_RULES_HPP
12 :
13 : #include <boost/http_proto/status.hpp>
14 : #include <boost/http_proto/rfc/token_rule.hpp>
15 : #include <boost/http_proto/detail/config.hpp>
16 : #include <boost/url/grammar/delim_rule.hpp>
17 : #include <boost/url/grammar/error.hpp>
18 : #include <boost/url/grammar/lut_chars.hpp>
19 : #include <boost/url/grammar/token_rule.hpp>
20 : #include <boost/url/grammar/tuple_rule.hpp>
21 : #include <boost/core/detail/string_view.hpp>
22 :
23 : namespace boost {
24 : namespace http_proto {
25 : namespace detail {
26 :
27 : //------------------------------------------------
28 :
29 : // WS = SP / HTAB
30 : struct ws_t
31 : {
32 : constexpr
33 : bool
34 27795 : operator()(char c) const noexcept
35 : {
36 27795 : return c == ' ' || c == '\t';
37 : }
38 : };
39 :
40 : constexpr ws_t ws{};
41 :
42 : //------------------------------------------------
43 :
44 : /* Used with list_rule
45 :
46 : @par BNF
47 : @code
48 : ows-comma = OWS "," OWS
49 : @endcode
50 : */
51 : struct ows_comma_ows_rule_t
52 : {
53 : using value_type = void;
54 :
55 : auto
56 : parse(
57 : char const*& it,
58 : char const* end) const noexcept ->
59 : system::result<void>
60 : {
61 : // OWS
62 : it = grammar::find_if_not(
63 : it, end, ws);
64 : if(it == end)
65 : return grammar::error::mismatch;
66 : // ","
67 : if(*it != ',')
68 : return grammar::error::mismatch;
69 : ++it;
70 : // OWS
71 : it = grammar::find_if_not(
72 : it, end, ws);
73 : return {};
74 : }
75 : };
76 :
77 : constexpr ows_comma_ows_rule_t ows_comma_ows_rule{};
78 :
79 : //------------------------------------------------
80 :
81 : // used for request-target
82 : //
83 : // target-char = <any OCTET except CTLs, and excluding LWS>
84 : //
85 : struct target_chars_t
86 : {
87 : constexpr
88 : bool
89 : operator()(char c) const noexcept
90 : {
91 : return
92 : (static_cast<unsigned char>(c) >= 0x21) &&
93 : (static_cast<unsigned char>(c) <= 0x7e);
94 : }
95 : };
96 :
97 : constexpr target_chars_t target_chars{};
98 :
99 : //------------------------------------------------
100 :
101 : // WS-VCHAR = SP / HTAB / VCHAR
102 : struct ws_vchars_t
103 : {
104 : constexpr
105 : bool
106 1461 : operator()(char ch) const noexcept
107 : {
108 : return (
109 1461 : ch >= 0x20 && ch <= 0x7e) ||
110 1461 : ch == 0x09;
111 : }
112 : };
113 :
114 : constexpr ws_vchars_t ws_vchars{};
115 :
116 : //------------------------------------------------
117 :
118 : // OWS = *( SP / HTAB )
119 : inline
120 : void
121 : skip_ows(
122 : char const*& it,
123 : char const* end) noexcept
124 : {
125 : while(it != end)
126 : {
127 : if(! ws(*it))
128 : break;
129 : ++it;
130 : }
131 : }
132 :
133 : struct ows_rule_t
134 : {
135 : using value_type = void;
136 :
137 : system::result<value_type>
138 : parse(
139 : char const*& it,
140 : char const* end) noexcept
141 : {
142 : skip_ows(it, end);
143 : return system::error_code();
144 : }
145 : };
146 :
147 : constexpr ows_rule_t ows_rule{};
148 :
149 : //------------------------------------------------
150 :
151 : // CRLF = CR LF
152 : struct crlf_rule_t
153 : {
154 : using value_type = void;
155 :
156 : system::result<value_type>
157 : parse(
158 : char const*& it,
159 : char const* end) const noexcept;
160 : };
161 :
162 : constexpr crlf_rule_t crlf_rule{};
163 :
164 : //------------------------------------------------
165 :
166 : // HTTP-version = "HTTP/" DIGIT "." DIGIT
167 : struct version_rule_t
168 : {
169 : using value_type = unsigned char;
170 :
171 : system::result<value_type>
172 : parse(
173 : char const*& it,
174 : char const* end) const noexcept;
175 : };
176 :
177 : constexpr version_rule_t version_rule{};
178 :
179 : //------------------------------------------------
180 :
181 : // request-line = method SP request-target SP HTTP-version CRLF
182 : constexpr auto
183 : request_line_rule =
184 : grammar::tuple_rule(
185 : token_rule,
186 : grammar::squelch(
187 : grammar::delim_rule(' ') ),
188 : grammar::token_rule(
189 : grammar::lut_chars(target_chars) ),
190 : grammar::squelch(
191 : grammar::delim_rule(' ') ),
192 : version_rule,
193 : crlf_rule);
194 :
195 : //------------------------------------------------
196 :
197 : // status-code = 3DIGIT
198 : struct status_code_rule_t
199 : {
200 : struct value_type
201 : {
202 : int v;
203 : status st;
204 : core::string_view s;
205 : };
206 :
207 : system::result<value_type>
208 : parse(
209 : char const*& it,
210 : char const* end) const noexcept;
211 : };
212 :
213 : constexpr status_code_rule_t status_code_rule{};
214 :
215 : //------------------------------------------------
216 :
217 : // status-line = HTTP-version SP status-code SP reason-phrase CRLF
218 : constexpr auto
219 : status_line_rule =
220 : grammar::tuple_rule(
221 : version_rule,
222 : grammar::squelch(
223 : grammar::delim_rule(' ') ),
224 : status_code_rule,
225 : grammar::squelch(
226 : grammar::delim_rule(' ') ),
227 : grammar::token_rule(ws_vchars),
228 : crlf_rule);
229 :
230 : //------------------------------------------------
231 :
232 : struct field_rule_t
233 : {
234 : struct value_type
235 : {
236 : core::string_view name;
237 : core::string_view value;
238 : bool has_obs_fold = false;
239 : };
240 :
241 : system::result<value_type>
242 : parse(
243 : char const*& it,
244 : char const* end) const noexcept;
245 : };
246 :
247 : constexpr field_rule_t field_rule{};
248 :
249 : /** Replace obs-fold with spaces
250 : */
251 : BOOST_HTTP_PROTO_DECL
252 : void
253 : remove_obs_fold(
254 : char *start,
255 : char const* end) noexcept;
256 :
257 : } // detail
258 : } // http_proto
259 : } // boost
260 :
261 : #endif
|