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_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/router_types.hpp>
15 : #include <boost/http/method.hpp>
16 : #include <boost/url/url_view.hpp>
17 : #include <boost/mp11/algorithm.hpp>
18 : #include <boost/capy/io_task.hpp>
19 : #include <boost/assert.hpp>
20 : #include <exception>
21 : #include <memory>
22 : #include <string_view>
23 : #include <type_traits>
24 :
25 : namespace boost {
26 : namespace http {
27 :
28 : template<class>
29 : class basic_router;
30 : class flat_router;
31 :
32 : namespace detail {
33 :
34 : // implementation for all routers
35 : class BOOST_HTTP_DECL
36 : router_base
37 : {
38 : struct impl;
39 : impl* impl_;
40 :
41 : friend class http::flat_router;
42 :
43 : protected:
44 : using opt_flags = unsigned int;
45 :
46 : enum
47 : {
48 : is_invalid = 0,
49 : is_plain = 1,
50 : is_error = 2,
51 : is_router = 4,
52 : is_exception = 8
53 : };
54 :
55 : struct BOOST_HTTP_DECL
56 : handler
57 : {
58 : char const kind;
59 179 : explicit handler(char kind_) noexcept : kind(kind_) {}
60 179 : virtual ~handler() = default;
61 : virtual auto invoke(route_params_base&) const ->
62 : route_task = 0;
63 :
64 : // Returns the nested router if this handler wraps one, nullptr otherwise.
65 : // Used by flat_router::flatten() to recurse into nested routers.
66 0 : virtual router_base* get_router() noexcept { return nullptr; }
67 : };
68 :
69 : using handler_ptr = std::unique_ptr<handler>;
70 :
71 : struct handlers
72 : {
73 : std::size_t n;
74 : handler_ptr* p;
75 : };
76 :
77 : // Handler for automatic OPTIONS responses
78 : struct BOOST_HTTP_DECL
79 : options_handler
80 : {
81 4 : virtual ~options_handler() = default;
82 : virtual route_task invoke(
83 : route_params_base&,
84 : std::string_view allow) const = 0;
85 : };
86 :
87 : using options_handler_ptr = std::unique_ptr<options_handler>;
88 :
89 : protected:
90 : using match_result = route_params_base::match_result;
91 : struct matcher;
92 : struct entry;
93 : struct layer;
94 :
95 : ~router_base();
96 : router_base(opt_flags);
97 : router_base(router_base&&) noexcept;
98 : router_base& operator=(router_base&&) noexcept;
99 : layer& new_layer(std::string_view pattern);
100 : std::size_t new_layer_idx(std::string_view pattern);
101 : layer& get_layer(std::size_t idx);
102 : void add_impl(std::string_view, handlers);
103 : void add_impl(layer&, http::method, handlers);
104 : void add_impl(layer&, std::string_view, handlers);
105 : void set_nested_depth(std::size_t parent_depth);
106 : options_handler_ptr options_handler_;
107 :
108 : public:
109 : /** Maximum nesting depth for routers.
110 :
111 : This limit applies to nested routers added via use().
112 : Exceeding this limit throws std::length_error at insertion time.
113 : */
114 : static constexpr std::size_t max_path_depth = 16;
115 : };
116 :
117 : template<class H, class... Args>
118 : concept returns_route_task = std::same_as<
119 : std::invoke_result_t<H, Args...>, route_task>;
120 :
121 : } // detail
122 : } // http
123 : } // boost
124 :
125 : #endif
|