GCC Code Coverage Report


Directory: libs/beast2/
File: include/boost/beast2/server/route_handler.hpp
Date: 2025-11-13 15:50:44
Exec Total Coverage
Lines: 3 23 13.0%
Functions: 1 8 12.5%
Branches: 0 0 -%

Line Branch Exec Source
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/beast2
8 //
9
10 #ifndef BOOST_BEAST2_SERVER_ROUTE_HANDLER_HPP
11 #define BOOST_BEAST2_SERVER_ROUTE_HANDLER_HPP
12
13 #include <boost/beast2/detail/config.hpp>
14 #include <boost/beast2/detail/except.hpp>
15 #include <boost/http_proto/request_parser.hpp> // VFALCO forward declare?
16 #include <boost/http_proto/response.hpp> // VFALCO forward declare?
17 #include <boost/http_proto/serializer.hpp> // VFALCO forward declare?
18 #include <boost/url/url_view.hpp>
19 #include <boost/url/segments_encoded_view.hpp>
20 #include <boost/core/detail/string_view.hpp>
21 #include <boost/system/error_code.hpp>
22 #include <boost/assert.hpp>
23
24 namespace boost {
25 namespace beast2 {
26
27 /** The type of value returned by route handlers
28 */
29 using route_result = system::error_code;
30
31 /** Route handler return values
32
33 These values determine how the caller proceeds after invoking
34 a route handler. Each enumerator describes a distinct control
35 action; whether the request was handled, should continue to the
36 next route, transfers ownership of the session, or signals that
37 the connection should be closed.
38 */
39 enum class route
40 {
41 /** The request was handled
42
43 This indicates that the route handler processed
44 the request and set up the response serializer.
45 The calling function will write the response
46 before reading the next request or closing
47 the connection.
48 */
49 send,
50
51 /** The route handler did not handle the request
52
53 Indicates that the route handler declined to process
54 the request. The caller will continue attempting to
55 match subsequent route handlers until one returns
56 `send` or no routes remain.
57 */
58 next,
59
60 /** The route handler requests that the connection be closed
61
62 Indicates that no further requests will be processed.
63 The caller should close the connection once the current
64 response, if any, has been sent.
65 */
66 close,
67
68 /** The route handler is detaching from the session
69
70 Indicates that ownership of the session or stream is
71 being transferred to the handler. The caller will not
72 perform further I/O or manage the connection after
73 this return value.
74 */
75 detach,
76
77 /** The route handler processed the request and sent the response
78
79 Indicates that the handler has completed the response. The caller
80 will read the next HTTP request if the connection is persistent,
81 or close the connection otherwise.
82 */
83 done
84 };
85
86 } // beast2
87 namespace system {
88 template<>
89 struct is_error_code_enum<
90 ::boost::beast2::route>
91 {
92 static bool const value = true;
93 };
94 } // system
95 namespace beast2 {
96
97 namespace detail {
98 struct BOOST_SYMBOL_VISIBLE route_cat_type
99 : system::error_category
100 {
101 BOOST_BEAST2_DECL const char* name(
102 ) const noexcept override;
103 BOOST_BEAST2_DECL std::string message(
104 int) const override;
105 BOOST_BEAST2_DECL char const* message(
106 int, char*, std::size_t
107 ) const noexcept override;
108 bool failed( int ) const noexcept override
109 { return false; }
110 2 BOOST_SYSTEM_CONSTEXPR route_cat_type()
111 2 : error_category(0x51c90d393754ecdf )
112 {
113 2 }
114 };
115 BOOST_BEAST2_DECL extern route_cat_type route_cat;
116 } // detail
117
118 inline
119 BOOST_SYSTEM_CONSTEXPR
120 system::error_code
121 make_error_code(route ev) noexcept
122 {
123 return system::error_code{static_cast<
124 std::underlying_type<route>::type>(ev),
125 detail::route_cat};
126 }
127
128 //------------------------------------------------
129
130 class resumer;
131
132 /** Function to detach a route handler from its session
133
134 This holds an reference to an implementation
135 which detaches the handler from its session.
136 */
137 class detacher
138 {
139 public:
140 /** Base class of the implementation
141 */
142 struct owner
143 {
144 virtual resumer do_detach() = 0;
145 virtual void do_resume(route_result const&) = 0;
146 };
147
148 detacher() = default;
149 detacher(detacher const&) = default;
150 detacher& operator=(detacher const&) = default;
151
152 explicit
153 detacher(
154 owner& who) noexcept
155 : p_(&who)
156 {
157 }
158
159 /** Detach and invoke the given function
160
161 The function will be invoked with this equivalent signature:
162 @code
163 void( resumer );
164 @endcode
165
166 @return A @ref route_result equal to @ref route::detach
167 */
168 template<class F>
169 route_result
170 operator()(F&& f);
171
172 private:
173 friend resumer;
174 owner* p_ = nullptr;
175 };
176
177 //------------------------------------------------
178
179 /** Function to resume a route handler's session
180
181 This holds a reference to an implementation
182 which resumes the handler's session. The resume
183 function is returned by calling @ref detach.
184 */
185 class resumer
186 {
187 public:
188 /** Constructor
189
190 Default constructed resume functions will
191 be empty. Invoking an empty resume function
192 yields undefined behavior.
193 */
194 resumer() = default;
195
196 /** Constructor
197
198 Copies of resume functions behave the same
199 as the original
200 */
201 resumer(resumer const&) = default;
202
203 /** Assignment
204
205 Copies of resume functions behave the same
206 as the original
207 */
208 resumer& operator=(resumer const&) = default;
209
210 /** Constructor
211 */
212 explicit
213 resumer(
214 detacher::owner& who) noexcept
215 : p_(&who)
216 {
217 }
218
219 /** Resume the session
220
221 A session is resumed as if the detached
222 handler returned the error code in `ec`.
223
224 @param ec The error code to resume with.
225 */
226 void operator()(
227 system::error_code const& ec = {}) const
228 {
229 p_->do_resume(ec);
230 }
231
232 private:
233 detacher::owner* p_ = nullptr;
234 };
235
236 template<class F>
237 auto
238 detacher::
239 operator()(F&& f) ->
240 route_result
241 {
242 if(! p_)
243 detail::throw_logic_error();
244 std::forward<F>(f)(p_->do_detach());
245 return route::detach;
246 }
247
248 //------------------------------------------------
249
250 struct acceptor_config
251 {
252 bool is_ssl;
253 bool is_admin;
254 };
255
256 /** Request object for HTTP route handlers
257 */
258 struct Request
259 {
260 /** The mount path of the current router
261
262 This is the portion of the request path
263 which was matched to select the handler.
264 The remaining portion is available in
265 @ref path.
266 */
267 core::string_view base_path;
268
269 /** The current pathname, relative to the base path
270 */
271 core::string_view path;
272
273 /** The complete request target
274
275 This is the parsed directly from the start
276 line contained in the HTTP request and is
277 never modified.
278 */
279 urls::url_view url;
280
281 acceptor_config port;
282 http_proto::request_base const& m;
283 http_proto::request_parser& pr;
284
285 Request(
286 acceptor_config port_,
287 http_proto::request_base const& m_,
288 http_proto::request_parser& pr_)
289 : port(port_)
290 , m(m_)
291 , pr(pr_)
292 {
293 }
294 };
295
296 /** Response object for HTTP route handlers
297 */
298 struct Response
299 {
300 /** Set the status code of the response.
301 @par Example
302 @code
303 res.status(http_proto::status::not_found);
304 @endcode
305 @param code The status code to set.
306 @return A reference to this response.
307 */
308 BOOST_BEAST2_DECL
309 Response&
310 status(http_proto::status code);
311
312 BOOST_BEAST2_DECL
313 Response&
314 set_body(std::string s);
315
316 http_proto::response& m;
317 http_proto::serializer& sr;
318
319 detacher detach;
320
321 /*
322 bool send(core::string_view);
323 bool error(system::error_code);
324 bool status(http_proto::status);
325 */
326
327 Response(
328 http_proto::response& m_,
329 http_proto::serializer& sr_) noexcept
330 : m(m_)
331 , sr(sr_)
332 {
333 }
334
335 };
336
337 } // beast2
338 } // boost
339
340 #endif
341