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