RESTinio
Toggle main menu visibility
Loading...
Searching...
No Matches
restinio
async_chain
growable_size.hpp
Go to the documentation of this file.
1
/*
2
* RESTinio
3
*/
4
5
/*!
6
* @file
7
* @brief Stuff related to growable-size chain of async request-headers.
8
*
9
* @since v.0.7.0
10
*/
11
12
#
pragma
once
13
14
#
include
<
restinio
/
async_chain
/
common
.
hpp
>
15
16
#
include
<
vector
>
17
18
namespace
restinio
::
async_chain
19
{
20
21
//
22
// growable_size_chain_t
23
//
24
/*!
25
* @brief A holder of variable-size chain of asynchronous handlers.
26
*
27
* @note
28
* Once a list of schedulers is filled and an instance of growable_size_chain_t
29
* is created that instance can't be changed: a new scheduler can't be added, and
30
* an old scheduler can be removed. The creation of growable_size_chain_t
31
* instance is performed by the help of growable_size_chain_t::builder_t
32
* class.
33
*
34
* Usage example for the case when there is no extra-data in a request object
35
* (please note that this is simplified example without actual asynchronous code,
36
* all schedulers work as synchronous handlers):
37
* @code
38
* struct my_traits : public restinio::default_traits_t {
39
* using request_handler_t = restinio::async_chain::growable_size_chain_t;
40
* };
41
*
42
* // The first handler in the chain.
43
* restinio::async_chain::schedule_result_t headers_checker(
44
* restinio::async_chain::unique_async_handling_controller_t<> controller )
45
* {
46
* ... // Checks values of HTTP-fields and rejects invalid requests.
47
*
48
* // Activation of the next handler.
49
* next( std::move(controller) );
50
*
51
* return restinio::async_chain::ok();
52
* }
53
*
54
* // The second handler in the chain.
55
* restinio::async_chain::schedule_result_t authentificator(
56
* restinio::async_chain::unique_async_handling_controller_t<> controller )
57
* {
58
* ... // Checks user's credentials and rejects requests from
59
* // non-authentificated users.
60
*
61
* // Activation of the next handler.
62
* next( std::move(controller) );
63
*
64
* return restinio::async_chain::ok();
65
* }
66
*
67
* // The last handler in the chain.
68
* restinio::async_chain::schedule_result_t actual_handler(
69
* restinio::async_chain::unique_async_handling_controller_t<> controller )
70
* {
71
* ... // Actual processing.
72
*
73
* return restinio::async_chain::ok();
74
* }
75
*
76
* // Building of a chain.
77
* restinio::async_chain::growable_size_chain_t<>::builder_t builder;
78
* if(config.force_headers_checking())
79
* builder.add(headers_checker);
80
* if(config.force_user_authentification())
81
* builder.add(authentificator);
82
* builder.add(actual_handler);
83
*
84
* restinio::run(
85
* on_thread_pool<my_traits>(16)
86
* .address(...)
87
* .port(...)
88
* .request_handler(builder.release())
89
* );
90
* @endcode
91
*
92
* Usage example for the case when some extra-data is incorporated into
93
* a request object:
94
* (please note that this is simplified example without actual asynchronous code,
95
* all schedulers work as synchronous handlers):
96
* @code
97
* struct my_extra_data_factory {
98
* // A data formed by checker of HTTP-fields.
99
* struct request_specific_fields_t {...};
100
*
101
* // A data formed by user-authentificator.
102
* struct user_info_t {...};
103
*
104
* // A data to be incorporated into a request object.
105
* using data_t = std::tuple<
106
* std::optional<request_specific_fields_t>,
107
* std::optional<user_info_t>>;
108
*
109
* void make_within(restinio::extra_data_buffer_t<data_t> buf) {
110
* new(buf.get()) data_t{};
111
* }
112
* };
113
*
114
* struct my_traits : public restinio::default_traits_t {
115
* using extra_data_factory_t = my_extra_data_factory;
116
* using request_handler_t = restinio::async_chain::growable_size_chain_t<
117
* extra_data_factory>;
118
* };
119
*
120
* using my_unique_controller_t =
121
* restinio::async_chain::unique_async_handling_controller_t<my_extra_data_factory>;
122
* using my_request_handle_t = my_unique_controller_t::actual_request_handle_t;
123
*
124
* // The first handler in the chain.
125
* restinio::async_chain::schedule_result_t headers_checker(
126
* my_unique_controller_t controller )
127
* {
128
* const my_request_handle_t req = acceptor->request_handle();
129
* ... // Checks values of HTTP-fields and rejects invalid requests.
130
* ...
131
* next( std::move(controller) );
132
* return restinio::async_chain::ok();
133
* }
134
*
135
* // The second handler in the chain.
136
* restinio::async_chain::schedule_result_t authentificator(
137
* my_unique_controller_t controller )
138
* {
139
* const my_request_handle_t req = acceptor->request_handle();
140
* ... // Checks user's credentials and rejects requests from
141
* // non-authentificated users.
142
* ...
143
* next( std::move(controller) );
144
* return restinio::async_chain::ok();
145
* }
146
*
147
* // The last handler in the chain.
148
* restinio::async_chain::schedule_result_t actual_handler(
149
* my_unique_controller_t controller )
150
* {
151
* const my_request_handle_t req = acceptor->request_handle();
152
* auto & field_values = std::get<my_extra_data_factory::request_specific_fields_t>(req->extra_data());
153
* auto & user_info = std::get<my_extra_data_factory::user_info_t>(req->extra_data());
154
* ... // Actual processing.
155
* return restinio::async_chain::ok();
156
* }
157
*
158
* // Building of a chain.
159
* restinio::sync_chain::growable_size_chain_t::builder_t builder;
160
* if(config.force_headers_checking())
161
* builder.add(headers_checker);
162
* if(config.force_user_authentification())
163
* builder.add(authentificator);
164
* builder.add(actual_handler);
165
*
166
* restinio::run(
167
* on_thread_pool<my_traits>(16)
168
* .address(...)
169
* .port(...)
170
* .request_handler(builder.release())
171
* );
172
* @endcode
173
*
174
* @tparam Extra_Data_Factory The type of extra-data-factory specified in
175
* the server's traits.
176
*
177
* @since v.0.7.0
178
*/
179
template
<
typename
Extra_Data_Factory =
no_extra_data_factory_t
>
180
class
growable_size_chain_t
181
{
182
// Helper class to allow the creation of growable_size_chain_t only
183
// for the friends of growable_size_chain_t.
184
struct
creation_token_t
{};
185
186
//! Short alias for a handling controller.
187
using
unique_controller_t
=
unique_async_handling_controller_t
<
Extra_Data_Factory
>;
188
189
//! Short alias for a scheduler.
190
using
scheduler_holder_t
=
generic_async_request_scheduler_t
<
Extra_Data_Factory
>;
191
192
//! Short alias for a vector of schedulers.
193
using
schedulers_vector_t
=
std
::
vector
<
scheduler_holder_t
>;
194
195
//! Short alias to a smart pointer to the source request.
196
using
actual_request_handle_t
=
197
typename
async_handling_controller_t
< Extra_Data_Factory >::
actual_request_handle_t
;
198
199
//! Short alias for the result of controller's on_next method.
200
using
actual_on_next_result_t
=
201
typename
async_handling_controller_t
< Extra_Data_Factory >::
actual_on_next_result_t
;
202
203
/*!
204
* @brief Actual implementation of the controller interface.
205
*
206
* @note
207
* Object of this type holds a copy of the source vector of schedulers.
208
*/
209
class
actual_controller_t
final
210
:
public
async_handling_controller_t
< Extra_Data_Factory >
211
{
212
//! The source request.
213
const
actual_request_handle_t
m_request
;
214
//! Request schedulers.
215
schedulers_vector_t
m_schedulers
;
216
//! Index of the current scheduler to be used.
217
/*!
218
* @note
219
* May be equal to or greater than m_schedulers.size() in the case
220
* when all schedulers are already processed.
221
*/
222
std::size_t
m_current
{};
223
224
public
:
225
//! Initializing constructor.
226
explicit
actual_controller_t
(
227
actual_request_handle_t
request,
228
const
schedulers_vector_t & schedulers )
229
:
m_request
{ request }
230
,
m_schedulers
{
schedulers
}
231
{}
232
233
[[nodiscard]]
234
const
actual_request_handle_t
&
235
request_handle
()
const
noexcept
override
{
return
m_request
; }
236
237
private
:
238
[[nodiscard]]
239
actual_on_next_result_t
240
on_next
()
override
241
{
242
const
auto
index_to_use =
m_current
;
243
++
m_current
;
244
245
if
( index_to_use >= m_schedulers.size() )
246
{
247
return
{
no_more_schedulers_t
{} };
248
}
249
else
250
{
251
return
{ m_schedulers[ index_to_use ] };
252
}
253
}
254
};
255
256
public
:
257
friend
class
builder_t;
258
259
/*!
260
* @brief A builder of an instance of growable_size_chain.
261
*
262
* Creates an empty instance of growable_size_chain_t in the constructor.
263
* That instance can be obtained by release() method.
264
*
265
* @note
266
* New schedulers can be added to the chain by add() method until
267
* release() is called.
268
*
269
* @attention
270
* An instance of builder works like an unique_ptr: it will hold
271
* a nullptr after a call of release() method.
272
*
273
* @since v.0.7.0
274
*/
275
class
builder_t
276
{
277
public
:
278
builder_t
()
279
:
m_chain
{
new
growable_size_chain_t
(
creation_token_t
{} ) }
280
{}
281
282
/*!
283
* @brief Stop adding of new schedulers and acquire the chain instance.
284
*
285
* @note
286
* The builder object should not be used after the calling of
287
* that method.
288
*/
289
[[nodiscard]]
290
std
::
unique_ptr
<
growable_size_chain_t
>
291
release
()
noexcept
292
{
293
return
{ std::move(m_chain) };
294
}
295
296
/*!
297
* @brief Add a new scheduler to the chain.
298
*/
299
template
<
typename
Scheduler >
300
void
301
add
( Scheduler && scheduler )
302
{
303
if
( !m_chain )
304
throw
exception_t
{
"an attempt to add a scheduler to "
305
"a growable-size-chain builder that already "
306
"released"
307
}
;
308
m_chain->m_schedulers.push_back(
309
growable_size_chain_t::scheduler_holder_t{
310
std::forward<Scheduler>(scheduler)
311
} );
312
}
313
314
private
:
315
std
::
unique_ptr
<
growable_size_chain_t
>
m_chain
;
316
};
317
318
private
:
319
//! The vector of schedulers.
320
schedulers_vector_t
m_schedulers
;
321
322
/*!
323
* @brief The main constructor.
324
*
325
* It has that form because the default constructor is public and
326
* marked as deleted.
327
*/
328
growable_size_chain_t
(
creation_token_t
) {}
329
330
public
:
331
/*!
332
* @note
333
* The default constructor is disable because an instance of
334
* that class should be created and filled by using builder_t.
335
*/
336
growable_size_chain_t
() =
delete
;
337
338
/*!
339
* Initiates execution of the first scheduler in the chain.
340
*
341
* @note
342
* Always returns request_handling_status_t::accepted.
343
*/
344
[[nodiscard]]
345
request_handling_status_t
346
operator
()(
const
actual_request_handle_t
& req )
const
347
{
348
unique_controller_t controller =
349
std::make_unique< actual_controller_t >(
350
req,
351
m_schedulers );
352
next( std::move(controller) );
353
354
return
request_accepted
(
)
;
355
}
356
};
357
358
}
/* namespace restinio::async_chain */
restinio::async_chain::async_handling_controller_t
Interface of a controller of an async chan.
Definition
common.hpp:146
restinio::async_chain::growable_size_chain_t::actual_controller_t::on_next
actual_on_next_result_t on_next() override
Command to try find a next scheduler to be invoked.
Definition
growable_size.hpp:240
restinio::async_chain::growable_size_chain_t::actual_controller_t::m_current
std::size_t m_current
Index of the current scheduler to be used.
Definition
growable_size.hpp:222
restinio::async_chain::growable_size_chain_t::actual_controller_t::request_handle
const actual_request_handle_t & request_handle() const noexcept override
Get reference to the source request.
Definition
growable_size.hpp:235
restinio::async_chain::growable_size_chain_t::actual_controller_t::actual_controller_t
actual_controller_t(actual_request_handle_t request, const schedulers_vector_t &schedulers)
Initializing constructor.
Definition
growable_size.hpp:226
restinio::async_chain::growable_size_chain_t::actual_controller_t::m_schedulers
schedulers_vector_t m_schedulers
Request schedulers.
Definition
growable_size.hpp:215
restinio::async_chain::growable_size_chain_t::actual_controller_t::m_request
const actual_request_handle_t m_request
The source request.
Definition
growable_size.hpp:213
restinio::async_chain::growable_size_chain_t::builder_t
A builder of an instance of growable_size_chain.
Definition
growable_size.hpp:276
restinio::async_chain::growable_size_chain_t::builder_t::release
std::unique_ptr< growable_size_chain_t > release() noexcept
Stop adding of new schedulers and acquire the chain instance.
Definition
growable_size.hpp:291
restinio::async_chain::growable_size_chain_t::builder_t::builder_t
builder_t()
Definition
growable_size.hpp:278
restinio::async_chain::growable_size_chain_t::builder_t::m_chain
std::unique_ptr< growable_size_chain_t > m_chain
Definition
growable_size.hpp:315
restinio::async_chain::growable_size_chain_t::builder_t::add
void add(Scheduler &&scheduler)
Add a new scheduler to the chain.
Definition
growable_size.hpp:301
restinio::async_chain::growable_size_chain_t
A holder of variable-size chain of asynchronous handlers.
Definition
growable_size.hpp:181
restinio::async_chain::growable_size_chain_t::actual_request_handle_t
typename async_handling_controller_t< Extra_Data_Factory >::actual_request_handle_t actual_request_handle_t
Short alias to a smart pointer to the source request.
Definition
growable_size.hpp:196
restinio::async_chain::growable_size_chain_t::actual_on_next_result_t
typename async_handling_controller_t< Extra_Data_Factory >::actual_on_next_result_t actual_on_next_result_t
Short alias for the result of controller's on_next method.
Definition
growable_size.hpp:200
restinio::async_chain::growable_size_chain_t::m_schedulers
schedulers_vector_t m_schedulers
The vector of schedulers.
Definition
growable_size.hpp:320
restinio::async_chain::growable_size_chain_t::operator()
request_handling_status_t operator()(const actual_request_handle_t &req) const
Definition
growable_size.hpp:346
restinio::async_chain::growable_size_chain_t::growable_size_chain_t
growable_size_chain_t()=delete
restinio::async_chain::growable_size_chain_t::growable_size_chain_t
growable_size_chain_t(creation_token_t)
The main constructor.
Definition
growable_size.hpp:328
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition
exception.hpp:26
restinio::exception_t::exception_t
exception_t(const char *err)
Definition
exception.hpp:29
restinio::async_chain
Definition
common.hpp:12
restinio
Definition
sendfile_operation_default.ipp:12
restinio::request_accepted
constexpr request_handling_status_t request_accepted() noexcept
Definition
common_types.hpp:46
restinio::request_handling_status_t
request_handling_status_t
Request handling status.
Definition
common_types.hpp:26
restinio::async_chain::growable_size_chain_t::creation_token_t
Definition
growable_size.hpp:184
restinio::async_chain::no_more_schedulers_t
Special type to be used as an indicator that there are no more schedulers in an async chain.
Definition
common.hpp:106
restinio::no_extra_data_factory_t
The default extra-data-factory to be used in server's traits if a user doesn't specify own one.
Definition
request_handler.hpp:78
Generated by
1.17.0