libs/http/include/boost/http/server/detail/router_base.hpp

100.0% Lines (7/7) 100.0% Functions (7/7) -% Branches (0/0)
libs/http/include/boost/http/server/detail/router_base.hpp
Line 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_SERVER_DETAIL_ROUTER_BASE_HPP
11 #define BOOST_HTTP_SERVER_DETAIL_ROUTER_BASE_HPP
12
13 #include <boost/http/detail/config.hpp>
14 #include <boost/http/server/route_handler.hpp>
15 #include <boost/http/method.hpp>
16 #include <boost/url/url_view.hpp>
17 #include <boost/mp11/algorithm.hpp>
18 #include <boost/assert.hpp>
19 #include <exception>
20 #include <memory>
21 #include <string_view>
22 #include <type_traits>
23
24 namespace boost {
25 namespace http {
26 namespace detail {
27
28 template<class> class router;
29
30 /** Non-template base class for all routers.
31
32 Holds a shared reference to an internal routing table
33 that is built incrementally as routes are added. The routing
34 table uses contiguous flat arrays for cache-friendly dispatch.
35
36 Copies share the same underlying routing data. Modifying
37 a router after it has been copied is not permitted and
38 results in undefined behavior.
39
40 @par Thread Safety
41
42 `dispatch` may be called concurrently on routers that share
43 the same data. Modification through `router` is not
44 thread-safe and must not be performed concurrently with any
45 other operation.
46
47 @see router
48 */
49 class BOOST_HTTP_DECL
50 router_base
51 {
52 struct impl;
53 std::shared_ptr<impl> impl_;
54
55 template<class, class> friend class http::router;
56
57 protected:
58 using opt_flags = unsigned int;
59
60 enum
61 {
62 is_invalid = 0,
63 is_plain = 1,
64 is_error = 2,
65 is_exception = 8
66 };
67
68 struct BOOST_HTTP_DECL
69 handler
70 {
71 char const kind;
72 227 explicit handler(char kind_) noexcept : kind(kind_) {}
73 227 virtual ~handler() = default;
74 virtual auto invoke(route_params&) const ->
75 route_task = 0;
76 };
77
78 using handler_ptr = std::unique_ptr<handler>;
79
80 struct handlers
81 {
82 std::size_t n;
83 handler_ptr* p;
84 };
85
86 struct BOOST_HTTP_DECL
87 options_handler
88 {
89 224 virtual ~options_handler() = default;
90 virtual route_task invoke(
91 route_params&,
92 std::string_view allow) const = 0;
93 };
94
95 using options_handler_ptr = std::unique_ptr<options_handler>;
96
97 protected:
98 using match_result = route_params::match_result;
99 struct matcher;
100 struct entry;
101
102 // Construct with options
103 explicit router_base(opt_flags);
104
105 // Registration helpers
106 void add_middleware(std::string_view pattern, handlers hn);
107 void inline_router(std::string_view pattern, router_base&& sub);
108 std::size_t new_route(std::string_view pattern);
109 void add_to_route(std::size_t idx, http::method verb, handlers hn);
110 void add_to_route(std::size_t idx, std::string_view verb, handlers hn);
111 void finalize_pending();
112 void set_options_handler_impl(options_handler_ptr p);
113
114 public:
115 /** Default constructor.
116
117 Creates a router in an empty state. The only valid
118 operations on a default-constructed router are
119 assignment, destruction, and copying.
120 */
121 router_base() = default;
122
123 75 router_base(router_base const&) = default;
124 72 router_base(router_base&&) noexcept = default;
125 2 router_base& operator=(router_base const&) = default;
126 router_base& operator=(router_base&&) noexcept = default;
127 369 ~router_base() = default;
128
129 /** Dispatch a request using a known HTTP method.
130
131 @param verb The HTTP method to match. Must not be
132 @ref http::method::unknown.
133
134 @param url The full request target used for route matching.
135
136 @param p The params to pass to handlers.
137
138 @return A task yielding the @ref route_result describing
139 how routing completed.
140
141 @throws std::invalid_argument If @p verb is
142 @ref http::method::unknown.
143 */
144 route_task
145 dispatch(
146 http::method verb,
147 urls::url_view const& url,
148 route_params& p) const;
149
150 /** Dispatch a request using a method string.
151
152 @param verb The HTTP method string to match. Must not be empty.
153
154 @param url The full request target used for route matching.
155
156 @param p The params to pass to handlers.
157
158 @return A task yielding the @ref route_result describing
159 how routing completed.
160
161 @throws std::invalid_argument If @p verb is empty.
162 */
163 route_task
164 dispatch(
165 std::string_view verb,
166 urls::url_view const& url,
167 route_params& p) const;
168
169 /** Maximum nesting depth for routers.
170
171 This limit applies to nested routers added via use().
172 Exceeding this limit throws std::length_error at
173 insertion time.
174 */
175 static constexpr std::size_t max_path_depth = 16;
176 };
177
178 } // detail
179 } // http
180 } // boost
181
182 #endif
183