RESTinio
Toggle main menu visibility
Loading...
Searching...
No Matches
restinio
sync_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 request-headers.
8
*
9
* @since v.0.6.13
10
*/
11
12
#
pragma
once
13
14
#
include
<
restinio
/
request_handler
.
hpp
>
15
16
#
include
<
vector
>
17
18
namespace
restinio
19
{
20
21
namespace
sync_chain
22
{
23
24
//
25
// growable_size_chain_t
26
//
27
/*!
28
* @brief A holder of variable-size chain of synchronous handlers.
29
*
30
* @note
31
* Once a list of handler is filled and an instance of growable_size_chain_t
32
* is created that instance can't be changed: a new handler can't be added, and
33
* an old handler can be removed. The creation of growable_size_chain_t
34
* instance is performed by the help of growable_size_chain_t::builder_t
35
* class.
36
*
37
* Usage example for the case when there is no extra-data in a request object.
38
* @code
39
* struct my_traits : public restinio::default_traits_t {
40
* using request_handler_t = restinio::sync_chain::growable_size_chain_t;
41
* };
42
*
43
* // The first handler in the chain.
44
* restinio::request_handling_status_t headers_checker(
45
* const restinio::request_handle_t & req )
46
* {
47
* ... // Checks values of HTTP-fields and rejects invalid requests.
48
* }
49
*
50
* // The second handler in the chain.
51
* restinio::request_handling_status_t authentificator(
52
* const restinio::request_handle_t & req )
53
* {
54
* ... // Checks user's credentials and rejects requests from
55
* // non-authentificated users.
56
* }
57
*
58
* // The last handler in the chain.
59
* restinio::request_handling_status_t actual_handler(
60
* const restinio::request_handle_t & req )
61
* {
62
* ... // Actual processing.
63
* }
64
*
65
* // Building of a chain.
66
* restinio::sync_chain::growable_size_chain_t<>::builder_t builder;
67
* if(config.force_headers_checking())
68
* builder.add(headers_checker);
69
* if(config.force_user_authentification())
70
* builder.add(authentificator);
71
* builder.add(actual_handler);
72
*
73
* restinio::run(
74
* on_thread_pool<my_traits>(16)
75
* .address(...)
76
* .port(...)
77
* .request_handler(builder.release())
78
* );
79
* @endcode
80
*
81
* Usage example for the case when some extra-data is incorporated into
82
* a request object.
83
* @code
84
* struct my_extra_data_factory {
85
* // A data formed by checker of HTTP-fields.
86
* struct request_specific_fields_t {...};
87
*
88
* // A data formed by user-authentificator.
89
* struct user_info_t {...};
90
*
91
* // A data to be incorporated into a request object.
92
* using data_t = std::tuple<
93
* std::optional<request_specific_fields_t>,
94
* std::optional<user_info_t>>;
95
*
96
* void make_within(restinio::extra_data_buffer_t<data_t> buf) {
97
* new(buf.get()) data_t{};
98
* }
99
* };
100
*
101
* struct my_traits : public restinio::default_traits_t {
102
* using extra_data_factory_t = my_extra_data_factory;
103
* using request_handler_t = restinio::sync_chain::growable_size_chain_t<
104
* extra_data_factory>;
105
* };
106
*
107
* using my_request_handle_t =
108
* restinio::generic_request_handle_t<my_extra_data_factory::data_t>;
109
*
110
* // The first handler in the chain.
111
* restinio::request_handling_status_t headers_checker(
112
* const my_request_handle_t & req )
113
* {
114
* ... // Checks values of HTTP-fields and rejects invalid requests.
115
* }
116
*
117
* // The second handler in the chain.
118
* restinio::request_handling_status_t authentificator(
119
* const my_request_handle_t & req )
120
* {
121
* ... // Checks user's credentials and rejects requests from
122
* // non-authentificated users.
123
* }
124
*
125
* // The last handler in the chain.
126
* restinio::request_handling_status_t actual_handler(
127
* const my_request_handle_t & req )
128
* {
129
* auto & field_values = std::get<
130
* std::optional<my_extra_data_factory::request_specific_fields_t>>(req->extra_data());
131
* auto & user_info = std::get<
132
* std::optional<my_extra_data_factory::user_info_t>>(req->extra_data());
133
* ... // Actual processing.
134
* }
135
*
136
* // Building of a chain.
137
* restinio::sync_chain::growable_size_chain_t::builder_t builder;
138
* if(config.force_headers_checking())
139
* builder.add(headers_checker);
140
* if(config.force_user_authentification())
141
* builder.add(authentificator);
142
* builder.add(actual_handler);
143
*
144
* restinio::run(
145
* on_thread_pool<my_traits>(16)
146
* .address(...)
147
* .port(...)
148
* .request_handler(builder.release())
149
* );
150
* @endcode
151
*
152
* @tparam Extra_Data_Factory The type of extra-data-factory specified in
153
* the server's traits.
154
*
155
* @since v.0.6.13
156
*/
157
template
<
typename
Extra_Data_Factory =
no_extra_data_factory_t
>
158
class
growable_size_chain_t
159
{
160
// Helper class to allow the creation of growable_size_chain_t only
161
// for the friends of growable_size_chain_t.
162
struct
creation_token_t
{};
163
164
public
:
165
friend
class
builder_t;
166
167
/*!
168
* @brief A builder of an instance of growable_size_chain.
169
*
170
* Creates an empty instance of growable_size_chain_t in the constructor.
171
* That instance can be obtained by release() method.
172
*
173
* @note
174
* New handlers can be added to the chain by add() method until
175
* release() is called.
176
*
177
* @attention
178
* An instance of builder works like an unique_ptr: it will hold
179
* a nullptr after a call of release() method.
180
*
181
* @since v.0.6.13
182
*/
183
class
builder_t
184
{
185
public
:
186
builder_t
()
187
:
m_chain
{
new
growable_size_chain_t
(
creation_token_t
{} ) }
188
{}
189
190
/*!
191
* @brief Stop adding of new handlers and acquire the chain instance.
192
*
193
* @note
194
* The builder object should not be used after the calling of
195
* that method.
196
*/
197
[[nodiscard]]
198
std
::
unique_ptr
<
growable_size_chain_t
>
199
release
()
noexcept
200
{
201
return
{ std::move(m_chain) };
202
}
203
204
/*!
205
* @brief Add a new handler to the chain.
206
*/
207
template
<
typename
Handler >
208
void
209
add
( Handler && handler )
210
{
211
if
( !m_chain )
212
throw
exception_t
{
"an attempt to add a handler to "
213
"a growable-size-chain builder that already "
214
"released"
215
}
;
216
m_chain->m_handlers.push_back(
217
growable_size_chain_t::handler_holder_t{
218
std::forward<Handler>(handler)
219
} );
220
}
221
222
private
:
223
std
::
unique_ptr
<
growable_size_chain_t
>
m_chain
;
224
};
225
226
private
:
227
using
actual_request_handle_t
=
228
generic_request_handle_t
<
typename
Extra_Data_Factory
::
data_t
>;
229
230
using
handler_holder_t
= std::function<
231
request_handling_status_t
(
const
actual_request_handle_t &)
232
>;
233
234
std
::
vector
<
handler_holder_t
>
m_handlers
;
235
236
/*!
237
* @brief The main constructor.
238
*
239
* It has that form because the default constructor is public and
240
* marked as deleted.
241
*/
242
growable_size_chain_t
(
creation_token_t
) {}
243
244
public
:
245
/*!
246
* @note
247
* The default constructor is disable because an instance of
248
* that class should be created and filled by using builder_t.
249
*/
250
growable_size_chain_t
() =
delete
;
251
252
[[nodiscard]]
253
request_handling_status_t
254
operator
()(
const
actual_request_handle_t & req )
const
255
{
256
for
(
auto
& h : m_handlers )
257
{
258
const
request_handling_status_t result = h( req );
259
260
switch
( result )
261
{
262
case
request_handling_status_t::accepted:
263
case
request_handling_status_t::rejected:
264
// There is no need to try next handler.
265
return
result;
266
267
case
request_handling_status_t::not_handled:
268
// Nothing to do. The next handler should be tried.
269
break
;
270
}
271
}
272
273
return
request_not_handled
(
)
;
274
}
275
};
276
277
}
/* namespace sync_chain */
278
279
}
/* namespace restinio */
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::sync_chain::growable_size_chain_t::builder_t
A builder of an instance of growable_size_chain.
Definition
growable_size.hpp:184
restinio::sync_chain::growable_size_chain_t::builder_t::m_chain
std::unique_ptr< growable_size_chain_t > m_chain
Definition
growable_size.hpp:223
restinio::sync_chain::growable_size_chain_t::builder_t::add
void add(Handler &&handler)
Add a new handler to the chain.
Definition
growable_size.hpp:209
restinio::sync_chain::growable_size_chain_t::builder_t::release
std::unique_ptr< growable_size_chain_t > release() noexcept
Stop adding of new handlers and acquire the chain instance.
Definition
growable_size.hpp:199
restinio::sync_chain::growable_size_chain_t::builder_t::builder_t
builder_t()
Definition
growable_size.hpp:186
restinio::sync_chain::growable_size_chain_t
A holder of variable-size chain of synchronous handlers.
Definition
growable_size.hpp:159
restinio::sync_chain::growable_size_chain_t::handler_holder_t
std::function< request_handling_status_t(const actual_request_handle_t &) > handler_holder_t
Definition
growable_size.hpp:230
restinio::sync_chain::growable_size_chain_t::growable_size_chain_t
growable_size_chain_t()=delete
restinio::sync_chain::growable_size_chain_t::operator()
request_handling_status_t operator()(const actual_request_handle_t &req) const
Definition
growable_size.hpp:254
restinio::sync_chain::growable_size_chain_t::growable_size_chain_t
growable_size_chain_t(creation_token_t)
The main constructor.
Definition
growable_size.hpp:242
restinio::sync_chain::growable_size_chain_t::m_handlers
std::vector< handler_holder_t > m_handlers
Definition
growable_size.hpp:234
restinio::sync_chain
Definition
fixed_size.hpp:22
restinio
Definition
sendfile_operation_default.ipp:12
restinio::request_not_handled
constexpr request_handling_status_t request_not_handled() noexcept
Definition
common_types.hpp:63
restinio::request_handling_status_t
request_handling_status_t
Request handling status.
Definition
common_types.hpp:26
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
restinio::sync_chain::growable_size_chain_t::creation_token_t
Definition
growable_size.hpp:162
Generated by
1.17.0