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