Line data Source code
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 : #ifndef BOOST_HTTP_SRC_SERVER_DETAIL_ROUTER_BASE_HPP
11 : #define BOOST_HTTP_SRC_SERVER_DETAIL_ROUTER_BASE_HPP
12 :
13 : #include <boost/http/server/detail/router_base.hpp>
14 : #include "src/server/detail/route_match.hpp"
15 :
16 : namespace boost {
17 : namespace http {
18 : namespace detail {
19 :
20 : // An entry describes a single route handler.
21 : // This can be an end route or a middleware.
22 : // Members ordered largest-to-smallest for optimal packing.
23 : struct router_base::entry
24 : {
25 : // ~32 bytes (SSO string)
26 : std::string verb_str;
27 :
28 : // 8 bytes each
29 : handler_ptr h;
30 : std::size_t matcher_idx = 0; // flat_router: index into matchers vector
31 :
32 : // 4 bytes
33 : http::method verb = http::method::unknown;
34 :
35 : // 1 byte (+ 3 bytes padding)
36 : bool all;
37 :
38 : // all
39 104 : explicit entry(
40 : handler_ptr h_) noexcept
41 104 : : h(std::move(h_))
42 104 : , all(true)
43 : {
44 104 : }
45 :
46 : // verb match
47 23 : entry(
48 : http::method verb_,
49 : handler_ptr h_) noexcept
50 23 : : h(std::move(h_))
51 23 : , verb(verb_)
52 23 : , all(false)
53 : {
54 23 : BOOST_ASSERT(verb !=
55 : http::method::unknown);
56 23 : }
57 :
58 : // verb match
59 2 : entry(
60 : std::string_view verb_str_,
61 : handler_ptr h_) noexcept
62 2 : : h(std::move(h_))
63 2 : , verb(http::string_to_method(verb_str_))
64 4 : , all(false)
65 : {
66 2 : if(verb != http::method::unknown)
67 0 : return;
68 2 : verb_str = verb_str_;
69 : }
70 :
71 29 : bool match_method(
72 : route_params_base& rp) const noexcept
73 : {
74 29 : detail::route_params_access RP{rp};
75 29 : if(all)
76 7 : return true;
77 22 : if(verb != http::method::unknown)
78 20 : return RP->verb_ == verb;
79 2 : if(RP->verb_ != http::method::unknown)
80 0 : return false;
81 2 : return RP->verb_str_ == verb_str;
82 : }
83 : };
84 :
85 : // A layer is a set of entries that match a route
86 : struct router_base::layer
87 : {
88 : matcher match;
89 : std::vector<entry> entries;
90 :
91 : // middleware layer
92 89 : layer(
93 : std::string_view pat,
94 : handlers hn)
95 89 : : match(pat, false)
96 : {
97 89 : entries.reserve(hn.n);
98 187 : for(std::size_t i = 0; i < hn.n; ++i)
99 98 : entries.emplace_back(std::move(hn.p[i]));
100 89 : }
101 :
102 : // route layer
103 27 : explicit layer(
104 : std::string_view pat)
105 27 : : match(pat, true)
106 : {
107 27 : }
108 : };
109 :
110 : struct router_base::impl
111 : {
112 : std::vector<layer> layers;
113 : opt_flags opt;
114 : std::size_t depth_ = 0;
115 :
116 102 : explicit impl(
117 : opt_flags opt_) noexcept
118 102 : : opt(opt_)
119 : {
120 102 : }
121 : };
122 :
123 : } // detail
124 : } // http
125 : } // boost
126 :
127 : #endif
|