src/server/detail/any_router.hpp

94.1% Lines (32/34) 100.0% List of functions (7/7)
any_router.hpp
f(x) Functions (7)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 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
8 //
9
10 #ifndef BOOST_HTTP_SRC_SERVER_DETAIL_ANY_ROUTER_HPP
11 #define BOOST_HTTP_SRC_SERVER_DETAIL_ANY_ROUTER_HPP
12
13 #include <boost/http/server/detail/router_base.hpp>
14 #include <boost/http/detail/except.hpp>
15 #include "src/server/detail/route_match.hpp"
16 #include <mutex>
17
18 namespace boost {
19 namespace http {
20 namespace detail {
21
22 struct router_base::entry
23 {
24 // ~32 bytes (SSO string)
25 std::string verb_str;
26
27 // 8 bytes each
28 handler_ptr h;
29 std::size_t matcher_idx = 0;
30
31 // 4 bytes
32 http::method verb = http::method::unknown;
33
34 // 1 byte (+ 3 bytes padding)
35 bool all;
36
37 // all methods
38 82x explicit entry(
39 handler_ptr h_) noexcept
40 82x : h(std::move(h_))
41 82x , all(true)
42 {
43 82x }
44
45 // known verb match
46 58x entry(
47 http::method verb_,
48 handler_ptr h_) noexcept
49 58x : h(std::move(h_))
50 58x , verb(verb_)
51 58x , all(false)
52 {
53 58x BOOST_ASSERT(verb !=
54 http::method::unknown);
55 58x }
56
57 // string verb match
58 2x entry(
59 std::string_view verb_str_,
60 handler_ptr h_) noexcept
61 2x : h(std::move(h_))
62 2x , verb(http::string_to_method(verb_str_))
63 4x , all(false)
64 {
65 2x if(verb != http::method::unknown)
66 return;
67 2x verb_str = verb_str_;
68 }
69
70 69x bool match_method(
71 route_params& rp) const noexcept
72 {
73 69x route_params_access RP{rp};
74 69x if(all)
75 9x return true;
76 60x if(verb != http::method::unknown)
77 58x return RP->verb_ == verb;
78 2x if(RP->verb_ != http::method::unknown)
79 return false;
80 2x return RP->verb_str_ == verb_str;
81 }
82 };
83
84 struct router_base::impl
85 {
86 std::vector<entry> entries;
87 std::vector<matcher> matchers;
88
89 std::size_t pending_route_ = SIZE_MAX;
90 mutable std::once_flag finalized_;
91
92 options_handler_ptr options_handler_;
93 std::uint64_t global_methods_ = 0;
94 std::vector<std::string> global_custom_verbs_;
95 std::string global_allow_header_;
96
97 opt_flags opt_;
98 std::size_t depth_ = 0;
99
100 168x explicit impl(
101 opt_flags opt) noexcept
102 168x : opt_(opt)
103 {
104 168x }
105
106 void finalize_pending();
107
108 // Thread-safe lazy finalization for dispatch
109 113x void ensure_finalized() const
110 {
111 113x std::call_once(finalized_, [this]() {
112 99x const_cast<impl*>(this)->finalize_pending();
113 99x });
114 113x }
115
116 void update_allow_for_entry(
117 matcher& m,
118 entry const& e);
119
120 void rebuild_global_allow_header();
121
122 route_task
123 dispatch_loop(
124 route_params& p,
125 bool is_options) const;
126
127 static std::string
128 build_allow_header(
129 std::uint64_t methods,
130 std::vector<std::string> const& custom);
131
132 static opt_flags
133 compute_effective_opts(
134 opt_flags parent,
135 opt_flags child);
136
137 static void
138 restore_path(
139 route_params& p,
140 std::size_t base_len);
141 };
142
143 } // detail
144 } // http
145 } // boost
146
147 #endif
148