GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/rfc/detail/impl/rules.ipp
Date: 2023-03-01 04:29:23
Exec Total Coverage
Lines: 137 150 91.3%
Functions: 6 6 100.0%
Branches: 74 92 80.4%

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_IMPL_RULES_IPP
11 #define BOOST_HTTP_PROTO_RFC_DETAIL_IMPL_RULES_IPP
12
13 #include <boost/http_proto/rfc/detail/rules.hpp>
14 #include <boost/url/grammar/digit_chars.hpp>
15
16 namespace boost {
17 namespace http_proto {
18 namespace detail {
19
20 auto
21 43158 crlf_rule_t::
22 parse(
23 char const*& it,
24 char const* end) const noexcept ->
25 system::result<value_type>
26 {
27
2/2
✓ Branch 0 taken 3861 times.
✓ Branch 1 taken 39297 times.
43158 if(it == end)
28 3861 return grammar::error::need_more;
29
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39297 times.
39297 if(*it != '\r')
30 return grammar::error::mismatch;
31 39297 ++it;
32
2/2
✓ Branch 0 taken 1553 times.
✓ Branch 1 taken 37744 times.
39297 if(it == end)
33 1553 return grammar::error::need_more;
34
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37744 times.
37744 if(*it != '\n')
35 return grammar::error::mismatch;
36 37744 ++it;
37 37744 return {};
38 }
39
40 //------------------------------------------------
41
42 auto
43 23617 version_rule_t::
44 parse(
45 char const*& it,
46 char const* end) const noexcept ->
47 system::result<value_type>
48 {
49 23617 value_type v = 0;
50
2/2
✓ Branch 0 taken 671 times.
✓ Branch 1 taken 22946 times.
23617 if(it == end)
51 {
52 // expected "HTTP/"
53 671 BOOST_HTTP_PROTO_RETURN_EC(
54 grammar::error::need_more);
55 }
56
2/2
✓ Branch 0 taken 20343 times.
✓ Branch 1 taken 2603 times.
22946 if(end - it >= 5)
57 {
58
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20343 times.
20343 if(std::memcmp(
59 it, "HTTP/", 5) != 0)
60 {
61 BOOST_HTTP_PROTO_RETURN_EC(
62 grammar::error::mismatch);
63 }
64 20343 it += 5;
65 }
66
2/2
✓ Branch 0 taken 617 times.
✓ Branch 1 taken 22329 times.
22946 if(it == end)
67 {
68 // expected DIGIT
69 617 BOOST_HTTP_PROTO_RETURN_EC(
70 grammar::error::need_more);
71 }
72
2/2
✓ Branch 1 taken 2603 times.
✓ Branch 2 taken 19726 times.
22329 if(! grammar::digit_chars(*it))
73 {
74 // expected DIGIT
75 2603 BOOST_HTTP_PROTO_RETURN_EC(
76 grammar::error::need_more);
77 }
78 19726 v = 10 * (*it++ - '0');
79
2/2
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 19001 times.
19726 if(it == end)
80 {
81 // expected "."
82 725 BOOST_HTTP_PROTO_RETURN_EC(
83 grammar::error::need_more);
84 }
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19001 times.
19001 if(*it != '.')
86 {
87 // expected "."
88 BOOST_HTTP_PROTO_RETURN_EC(
89 grammar::error::need_more);
90 }
91 19001 ++it;
92
2/2
✓ Branch 0 taken 617 times.
✓ Branch 1 taken 18384 times.
19001 if(it == end)
93 {
94 // expected DIGIT
95 617 BOOST_HTTP_PROTO_RETURN_EC(
96 grammar::error::need_more);
97 }
98
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18384 times.
18384 if(! grammar::digit_chars(*it))
99 {
100 // expected DIGIT
101 BOOST_HTTP_PROTO_RETURN_EC(
102 grammar::error::need_more);
103 }
104 18384 v += *it++ - '0';
105 18384 return v;
106 }
107
108 //------------------------------------------------
109
110 auto
111 11100 status_code_rule_t::
112 parse(
113 char const*& it,
114 char const* end) const noexcept ->
115 system::result<value_type>
116 {
117 auto const dig =
118 31152 [](char c) -> int
119 {
120 31152 unsigned char uc(c - '0');
121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31152 times.
31152 if(uc > 9)
122 return -1;
123 31152 return uc;
124 };
125
126
2/2
✓ Branch 0 taken 358 times.
✓ Branch 1 taken 10742 times.
11100 if(it == end)
127 {
128 // end
129 358 BOOST_HTTP_PROTO_RETURN_EC(
130 grammar::error::need_more);
131 }
132 10742 auto it0 = it;
133 10742 int v = dig(*it);
134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10742 times.
10742 if(v == -1)
135 {
136 // expected DIGIT
137 BOOST_HTTP_PROTO_RETURN_EC(
138 grammar::error::mismatch);
139 }
140 10742 value_type t;
141 10742 t.v = 100 * v;
142 10742 ++it;
143
2/2
✓ Branch 0 taken 358 times.
✓ Branch 1 taken 10384 times.
10742 if(it == end)
144 {
145 // end
146 358 BOOST_HTTP_PROTO_RETURN_EC(
147 grammar::error::need_more);
148 }
149 10384 v = dig(*it);
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10384 times.
10384 if(v == -1)
151 {
152 // expected DIGIT
153 BOOST_HTTP_PROTO_RETURN_EC(
154 grammar::error::mismatch);
155 }
156 10384 t.v = t.v + (10 * v);
157 10384 ++it;
158
2/2
✓ Branch 0 taken 358 times.
✓ Branch 1 taken 10026 times.
10384 if(it == end)
159 {
160 // end
161 358 BOOST_HTTP_PROTO_RETURN_EC(
162 grammar::error::need_more);
163 }
164 10026 v = dig(*it);
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10026 times.
10026 if(v == -1)
166 {
167 // expected DIGIT
168 BOOST_HTTP_PROTO_RETURN_EC(
169 grammar::error::need_more);
170 }
171 10026 t.v = t.v + v;
172 10026 ++it;
173
174 10026 t.s = core::string_view(it0, it - it0);
175 10026 t.st = int_to_status(t.v);
176 10026 return t;
177 }
178
179 //------------------------------------------------
180
181 auto
182 52722 field_rule_t::
183 parse(
184 char const*& it,
185 char const* end) const noexcept ->
186 system::result<value_type>
187 {
188
2/2
✓ Branch 0 taken 698 times.
✓ Branch 1 taken 52024 times.
52722 if(it == end)
189 {
190 698 BOOST_HTTP_PROTO_RETURN_EC(
191 grammar::error::need_more);
192 }
193 // check for leading CRLF
194
2/2
✓ Branch 0 taken 15262 times.
✓ Branch 1 taken 36762 times.
52024 if(it[0] == '\r')
195 {
196 15262 ++it;
197
2/2
✓ Branch 0 taken 657 times.
✓ Branch 1 taken 14605 times.
15262 if(it == end)
198 {
199 657 BOOST_HTTP_PROTO_RETURN_EC(
200 grammar::error::need_more);
201 }
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14605 times.
14605 if(*it != '\n')
203 {
204 BOOST_HTTP_PROTO_RETURN_EC(
205 grammar::error::mismatch);
206 }
207 // end of fields
208 14605 ++it;
209 14605 BOOST_HTTP_PROTO_RETURN_EC(
210 grammar::error::end_of_range);
211 }
212
213 36762 value_type v;
214
215 // field name
216 {
217 auto rv = grammar::parse(
218 36762 it, end, grammar::tuple_rule(
219 token_rule,
220 36762 grammar::squelch(
221 36762 grammar::delim_rule(':'))));
222
2/2
✓ Branch 1 taken 7820 times.
✓ Branch 2 taken 28942 times.
36762 if(! rv)
223 7820 return rv.error();
224 28942 v.name = rv.value();
225 }
226
227 // consume all obs-fold until
228 // field char or end of field
229 for(;;)
230 {
231 29236 skip_ows(it, end);
232
2/2
✓ Branch 0 taken 1802 times.
✓ Branch 1 taken 27434 times.
29236 if(it == end)
233 {
234 1802 BOOST_HTTP_PROTO_RETURN_EC(
235 grammar::error::need_more);
236 }
237
2/2
✓ Branch 0 taken 26880 times.
✓ Branch 1 taken 554 times.
27434 if(*it != '\r')
238 {
239 // start of value
240 26880 break;
241 }
242 554 ++it;
243
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 494 times.
554 if(it == end)
244 {
245 60 BOOST_HTTP_PROTO_RETURN_EC(
246 grammar::error::need_more);
247 }
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 494 times.
494 if(*it != '\n')
249 {
250 BOOST_HTTP_PROTO_RETURN_EC(
251 grammar::error::mismatch);
252 }
253 494 ++it;
254
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 438 times.
494 if(it == end)
255 {
256 56 BOOST_HTTP_PROTO_RETURN_EC(
257 grammar::error::need_more);
258 }
259
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 294 times.
438 if(*it == '\r')
260 {
261 // empty value
262 144 return v;
263 }
264
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 294 times.
294 if( *it != ' ' &&
265 *it != '\t')
266 {
267 // start of value
268 break;
269 }
270 // eat obs-fold
271 294 ++it;
272 294 v.has_obs_fold = true;
273 294 }
274
275 26880 char const* s0 = it; // start of value
276 for(;;)
277 {
278 auto rv = grammar::parse(
279 26922 it, end, grammar::tuple_rule(
280 26922 grammar::token_rule(
281 26922 ws_vchars),
282 26922 crlf_rule));
283
2/2
✓ Branch 1 taken 3714 times.
✓ Branch 2 taken 23208 times.
26922 if(! rv)
284 3714 return rv.error();
285
2/2
✓ Branch 0 taken 858 times.
✓ Branch 1 taken 22350 times.
23208 if(it == end)
286 {
287 858 BOOST_HTTP_PROTO_RETURN_EC(
288 grammar::error::need_more);
289 }
290
2/2
✓ Branch 0 taken 22308 times.
✓ Branch 1 taken 42 times.
22350 if( *it != ' ' &&
291
1/2
✓ Branch 0 taken 22308 times.
✗ Branch 1 not taken.
22308 *it != '\t')
292 {
293 // end of field
294 22308 break;
295 }
296 // *it will match field_value_rule
297 42 v.has_obs_fold = true;
298 42 }
299
300 22308 v.value = core::string_view(s0, (it - s0) - 2);
301
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 22308 times.
22308 BOOST_ASSERT(! v.value.empty());
302 //BOOST_ASSERT(! ws(t.v.value.front()));
303
304 // remove trailing SP,HTAB,CR,LF
305 22308 auto p = &v.value.back();
306 for(;;)
307 {
308
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 22308 times.
22513 switch(*p)
309 {
310 205 case ' ': case '\t':
311 case '\r': case '\n':
312 205 --p;
313 205 continue;
314 22308 default:
315 22308 ++p;
316 22308 goto done;
317 }
318 }
319 22308 done:
320 22308 v.value = core::string_view(
321 v.value.data(),
322 22308 p - v.value.data());
323 22308 return v;
324 }
325
326 //------------------------------------------------
327
328 void
329 946 remove_obs_fold(
330 char* it,
331 char const* const end) noexcept
332 {
333
2/2
✓ Branch 0 taken 941 times.
✓ Branch 1 taken 5 times.
946 while(it != end)
334 {
335
2/2
✓ Branch 0 taken 593 times.
✓ Branch 1 taken 348 times.
941 if(*it != '\r')
336 {
337 593 ++it;
338 593 continue;
339 }
340
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 203 times.
348 if(end - it < 3)
341 145 break;
342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 203 times.
203 BOOST_ASSERT(it[1] == '\n');
343
5/6
✓ Branch 0 taken 203 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 200 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 200 times.
✓ Branch 5 taken 3 times.
406 if( it[1] == '\n' &&
344 203 ws(it[2]))
345 {
346 200 it[0] = ' ';
347 200 it[1] = ' ';
348 200 it += 3;
349 }
350 else
351 {
352 3 ++it;
353 }
354 }
355 150 }
356
357 } // detail
358 } // http_proto
359 } // boost
360
361 #endif
362