GCC Code Coverage Report


Directory: libs/http_proto/
File: boost/http_proto/rfc/detail/rules.hpp
Date: 2024-04-15 15:38:04
Exec Total Coverage
Lines: 5 5 100.0%
Functions: 2 2 100.0%
Branches: 8 10 80.0%

Line Branch Exec Source
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 28741 operator()(char c) const noexcept
35 {
36
4/4
✓ Branch 0 taken 22091 times.
✓ Branch 1 taken 6650 times.
✓ Branch 2 taken 533 times.
✓ Branch 3 taken 21558 times.
28741 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 1489 operator()(char ch) const noexcept
107 {
108 return (
109
4/6
✓ Branch 0 taken 1028 times.
✓ Branch 1 taken 461 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1028 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 461 times.
1489 ch >= 0x20 && ch <= 0x7e) ||
110 1489 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
262