GCC Code Coverage Report


Directory: libs/http_proto/
File: src/rfc/detail/rules.hpp
Date: 2025-09-21 18:08:15
Exec Total Coverage
Lines: 3 3 100.0%
Functions: 1 1 100.0%
Branches: 4 6 66.7%

Line Branch Exec Source
1 //
2 // Copyright (c) 2024 Christian Mazakas
3 // Copyright (c) 2025 Mohammad Nejati
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/http_proto
9 //
10
11 #ifndef BOOST_HTTP_PROTO_SRC_RFC_DETAIL_RULES_HPP
12 #define BOOST_HTTP_PROTO_SRC_RFC_DETAIL_RULES_HPP
13
14 #include <boost/http_proto/detail/config.hpp>
15 #include <boost/http_proto/rfc/detail/ws.hpp>
16 #include <boost/http_proto/rfc/token_rule.hpp>
17 #include <boost/http_proto/status.hpp>
18 #include <boost/core/detail/string_view.hpp>
19 #include <boost/system/result.hpp>
20 #include <boost/url/grammar/delim_rule.hpp>
21 #include <boost/url/grammar/error.hpp>
22 #include <boost/url/grammar/lut_chars.hpp>
23 #include <boost/url/grammar/token_rule.hpp>
24 #include <boost/url/grammar/tuple_rule.hpp>
25
26 namespace boost {
27 namespace http_proto {
28 namespace detail {
29
30 //------------------------------------------------
31
32 /* Used with list_rule
33
34 @par BNF
35 @code
36 ows-comma = OWS "," OWS
37 @endcode
38 */
39 struct ows_comma_ows_rule_t
40 {
41 using value_type = void;
42
43 auto
44 parse(
45 char const*& it,
46 char const* end) const noexcept ->
47 system::result<void>
48 {
49 // OWS
50 it = grammar::find_if_not(
51 it, end, ws);
52 if(it == end)
53 return grammar::error::mismatch;
54 // ","
55 if(*it != ',')
56 return grammar::error::mismatch;
57 ++it;
58 // OWS
59 it = grammar::find_if_not(
60 it, end, ws);
61 return {};
62 }
63 };
64
65 constexpr ows_comma_ows_rule_t ows_comma_ows_rule{};
66
67 //------------------------------------------------
68
69 // used for request-target
70 //
71 // target-char = <any OCTET except CTLs, and excluding LWS>
72 //
73 struct target_chars_t
74 {
75 constexpr
76 bool
77 operator()(char c) const noexcept
78 {
79 return
80 (static_cast<unsigned char>(c) >= 0x21) &&
81 (static_cast<unsigned char>(c) <= 0x7e);
82 }
83 };
84
85 constexpr target_chars_t target_chars{};
86
87 //------------------------------------------------
88
89 // WS-VCHAR = SP / HTAB / VCHAR
90 struct ws_vchars_t
91 {
92 constexpr
93 bool
94 2766 operator()(char ch) const noexcept
95 {
96 return (
97
4/6
✓ Branch 0 taken 1904 times.
✓ Branch 1 taken 862 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1904 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 862 times.
2766 ch >= 0x20 && ch <= 0x7e) ||
98 2766 ch == 0x09;
99 }
100 };
101
102 constexpr ws_vchars_t ws_vchars{};
103
104 //------------------------------------------------
105
106 // OWS = *( SP / HTAB )
107 inline
108 void
109 skip_ows(
110 char const*& it,
111 char const* end) noexcept
112 {
113 while(it != end)
114 {
115 if(! ws(*it))
116 break;
117 ++it;
118 }
119 }
120
121 struct ows_rule_t
122 {
123 using value_type = void;
124
125 system::result<value_type>
126 parse(
127 char const*& it,
128 char const* end) noexcept
129 {
130 skip_ows(it, end);
131 return system::error_code();
132 }
133 };
134
135 constexpr ows_rule_t ows_rule{};
136
137 //------------------------------------------------
138
139 // CRLF = CR LF
140 struct crlf_rule_t
141 {
142 using value_type = void;
143
144 system::result<value_type>
145 parse(
146 char const*& it,
147 char const* end) const noexcept;
148 };
149
150 constexpr crlf_rule_t crlf_rule{};
151
152 //------------------------------------------------
153
154 // HTTP-version = "HTTP/" DIGIT "." DIGIT
155 struct version_rule_t
156 {
157 using value_type = unsigned char;
158
159 system::result<value_type>
160 parse(
161 char const*& it,
162 char const* end) const noexcept;
163 };
164
165 constexpr version_rule_t version_rule{};
166
167 //------------------------------------------------
168
169 // request-line = method SP request-target SP HTTP-version CRLF
170 constexpr auto
171 request_line_rule =
172 grammar::tuple_rule(
173 token_rule,
174 grammar::squelch(
175 grammar::delim_rule(' ') ),
176 grammar::token_rule(
177 grammar::lut_chars(target_chars) ),
178 grammar::squelch(
179 grammar::delim_rule(' ') ),
180 version_rule,
181 crlf_rule);
182
183 //------------------------------------------------
184
185 // status-code = 3DIGIT
186 struct status_code_rule_t
187 {
188 struct value_type
189 {
190 int v;
191 status st;
192 core::string_view s;
193 };
194
195 system::result<value_type>
196 parse(
197 char const*& it,
198 char const* end) const noexcept;
199 };
200
201 constexpr status_code_rule_t status_code_rule{};
202
203 //------------------------------------------------
204
205 // status-code = *( HTAB / SP / VCHAR / obs-text )
206 struct reason_phrase_rule_t
207 {
208 using value_type = core::string_view;
209
210 system::result<value_type>
211 parse(
212 char const*& it,
213 char const* end) const noexcept;
214 };
215
216 constexpr reason_phrase_rule_t reason_phrase_rule{};
217
218 //------------------------------------------------
219
220 // status-line = HTTP-version SP status-code SP reason-phrase CRLF
221 constexpr auto
222 status_line_rule =
223 grammar::tuple_rule(
224 version_rule,
225 grammar::squelch(
226 grammar::delim_rule(' ') ),
227 status_code_rule,
228 grammar::squelch(
229 grammar::delim_rule(' ') ),
230 reason_phrase_rule,
231 crlf_rule);
232
233 //------------------------------------------------
234
235 struct field_rule_t
236 {
237 struct value_type
238 {
239 core::string_view name;
240 core::string_view value;
241 bool has_obs_fold = false;
242 };
243
244 system::result<value_type>
245 parse(
246 char const*& it,
247 char const* end) const noexcept;
248 };
249
250 constexpr field_rule_t field_rule{};
251
252 /** Replace obs-fold with spaces
253 */
254 void
255 remove_obs_fold(
256 char *start,
257 char const* end) noexcept;
258
259 // header-field = field-name ":" OWS field-value OWS
260 struct field_name_rule_t
261 {
262 using value_type = core::string_view;
263
264 system::result<value_type>
265 parse(
266 char const*& it,
267 char const* end) const noexcept;
268 };
269
270 constexpr field_name_rule_t field_name_rule{};
271
272 struct field_value_rule_t
273 {
274 struct value_type
275 {
276 core::string_view value;
277 // detected occurrence of `\r\n `, `\r\n\t`
278 bool has_obs_fold = false;
279 // detected `\r\nX`, attempt at field termination
280 bool has_crlf = false;
281 };
282
283 system::result<value_type>
284 parse(
285 char const*& it,
286 char const* end) const noexcept;
287 };
288
289 constexpr field_value_rule_t field_value_rule{};
290
291 } // detail
292 } // http_proto
293 } // boost
294
295 #endif
296