GCC Code Coverage Report


Directory: ./
File: libs/http/src/server/detail/route_match.cpp
Date: 2026-01-20 00:11:35
Exec Total Coverage
Lines: 44 48 91.7%
Functions: 3 3 100.0%
Branches: 41 49 83.7%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot 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
8 //
9
10 #include "src/server/detail/pct_decode.hpp"
11 #include "src/server/detail/route_match.hpp"
12
13 namespace boost {
14 namespace http {
15 namespace detail {
16
17 116 router_base::
18 matcher::
19 matcher(
20 std::string_view pat,
21 116 bool end_arg)
22
1/1
✓ Branch 2 taken 116 times.
116 : decoded_pat_(
23 [&pat]
24 {
25
2/2
✓ Branch 1 taken 116 times.
✓ Branch 4 taken 116 times.
116 auto s = pct_decode(pat);
26 116 if( s.size() > 1
27
4/6
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 42 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 116 times.
116 && s.back() == '/')
28 s.pop_back();
29 116 return s;
30
1/1
✓ Branch 1 taken 116 times.
232 }())
31 116 , end_(end_arg)
32 232 , slash_(pat == "/")
33 {
34
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 42 times.
116 if(! slash_)
35
1/1
✓ Branch 2 taken 74 times.
74 pv_ = grammar::parse(
36
1/1
✓ Branch 2 taken 74 times.
74 decoded_pat_, detail::path_rule).value();
37 116 }
38
39 bool
40 82 router_base::
41 matcher::
42 operator()(
43 route_params_base& p,
44 match_result& mr) const
45 {
46
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 82 times.
82 BOOST_ASSERT(! p.path.empty());
47
4/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 43 times.
121 if( slash_ && (
48
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
59 ! end_ ||
49 20 p.path == "/"))
50 {
51 // params = {};
52 39 mr.adjust_path(p, 0);
53 39 return true;
54 }
55 43 auto it = p.path.data();
56 43 auto pit = pv_.segs.begin();
57 43 auto const path_end = it + p.path.size();
58 43 auto const pend = pv_.segs.end();
59
6/6
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 21 times.
✓ Branch 3 taken 43 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 43 times.
✓ Branch 6 taken 34 times.
77 while(it != path_end && pit != pend)
60 {
61 // prefix has to match
62 43 auto s = core::string_view(it, path_end);
63
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 4 times.
43 if(! p.case_sensitive)
64 {
65
2/2
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 37 times.
39 if(pit->prefix.size() > s.size())
66 9 return false;
67
1/1
✓ Branch 3 taken 37 times.
37 s = s.substr(0, pit->prefix.size());
68 //if(! grammar::ci_is_equal(s, pit->prefix))
69
2/2
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 32 times.
37 if(! ci_is_equal(s, pit->prefix))
70 5 return false;
71 }
72 else
73 {
74
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
4 if(! s.starts_with(pit->prefix))
75 2 return false;
76 }
77 34 it += pit->prefix.size();
78 34 ++pit;
79 }
80
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 28 times.
34 if(end_)
81 {
82 // require full match
83
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 if( it != path_end ||
84
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 pit != pend)
85 return false;
86 }
87
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 else if(pit != pend)
88 {
89 return false;
90 }
91 // number of matching characters
92 34 auto const n = it - p.path.data();
93 34 mr.adjust_path(p, n);
94 34 return true;
95 }
96
97 } // detail
98 } // http
99 } // boost
100