RESTinio
Toggle main menu visibility
Loading...
Searching...
No Matches
restinio
sync_chain
fixed_size.hpp
Go to the documentation of this file.
1
/*
2
* RESTinio
3
*/
4
5
/*!
6
* @file
7
* @brief Stuff related to fixed-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
<
array
>
17
18
namespace
restinio
19
{
20
21
namespace
sync_chain
22
{
23
24
//
25
// fixed_size_chain_t
26
//
27
/*!
28
* @brief A holder of fixed-size chain of synchronous handlers.
29
*
30
* @note
31
* An instance of that type is intended to be filled with actual handlers
32
* at the creation time. After that new handlers can't be added to the chain,
33
* and old handlers can't be removed from the chain.
34
*
35
* Usage example for the case when there is no extra-data in a request object.
36
* @code
37
* struct my_traits : public restinio::default_traits_t {
38
* using request_handler_t = restinio::sync_chain::fixed_size_chain_t<3>;
39
* };
40
*
41
* // The first handler in the chain.
42
* restinio::request_handling_status_t headers_checker(
43
* const restinio::request_handle_t & req )
44
* {
45
* ... // Checks values of HTTP-fields and rejects invalid requests.
46
* }
47
*
48
* // The second handler in the chain.
49
* restinio::request_handling_status_t authentificator(
50
* const restinio::request_handle_t & req )
51
* {
52
* ... // Checks user's credentials and rejects requests from
53
* // non-authentificated users.
54
* }
55
*
56
* // The last handler in the chain.
57
* restinio::request_handling_status_t actual_handler(
58
* const restinio::request_handle_t & req )
59
* {
60
* ... // Actual processing.
61
* }
62
*
63
* restinio::run(
64
* on_thread_pool<my_traits>(16)
65
* .address(...)
66
* .port(...)
67
* .request_handler(
68
* // Just enumerate all handlers.
69
* headers_checker,
70
* authentificator,
71
* actual_handler )
72
* );
73
* @endcode
74
*
75
* An instance of `fixed_size_chain_t` can also be created manually and
76
* passed to server's settings by `unique_ptr`:
77
* @code
78
* auto chain = std::make_unique<restinio::sync_chain::fixed_size_chain_t<3>>(
79
* headers_checker, authentificator, actual_handler);
80
* ...
81
* restinio::run(
82
* on_thread_pool<my_traits>(16)
83
* .address(...)
84
* .port(...)
85
* .request_handler(std::move(chain))
86
* );
87
* @endcode
88
*
89
* Usage example for the case when some extra-data is incorporated into
90
* a request object.
91
* @code
92
* struct my_extra_data_factory {
93
* // A data formed by checker of HTTP-fields.
94
* struct request_specific_fields_t {...};
95
*
96
* // A data formed by user-authentificator.
97
* struct user_info_t {...};
98
*
99
* // A data to be incorporated into a request object.
100
* using data_t = std::tuple<request_specific_fields_t, user_info_t>;
101
*
102
* void make_within(restinio::extra_data_buffer_t<data_t> buf) {
103
* new(buf.get()) data_t{};
104
* }
105
* };
106
*
107
* struct my_traits : public restinio::default_traits_t {
108
* using extra_data_factory_t = my_extra_data_factory;
109
* using request_handler_t = restinio::sync_chain::fixed_size_chain_t<
110
* 3,
111
* extra_data_factory>;
112
* };
113
*
114
* using my_request_handle_t =
115
* restinio::generic_request_handle_t<my_extra_data_factory::data_t>;
116
*
117
* // The first handler in the chain.
118
* restinio::request_handling_status_t headers_checker(
119
* const my_request_handle_t & req )
120
* {
121
* ... // Checks values of HTTP-fields and rejects invalid requests.
122
* }
123
*
124
* // The second handler in the chain.
125
* restinio::request_handling_status_t authentificator(
126
* const my_request_handle_t & req )
127
* {
128
* ... // Checks user's credentials and rejects requests from
129
* // non-authentificated users.
130
* }
131
*
132
* // The last handler in the chain.
133
* restinio::request_handling_status_t actual_handler(
134
* const my_request_handle_t & req )
135
* {
136
* auto & field_values = std::get<my_extra_data_factory::request_specific_fields_t>(req->extra_data());
137
* auto & user_info = std::get<my_extra_data_factory::user_info_t>(req->extra_data());
138
* ... // Actual processing.
139
* }
140
*
141
* restinio::run(
142
* on_thread_pool<my_traits>(16)
143
* .address(...)
144
* .port(...)
145
* .request_handler(
146
* // Just enumerate all handlers.
147
* headers_checker,
148
* authentificator,
149
* actual_handler )
150
* );
151
* @endcode
152
*
153
* @tparam Size The exact number of handlers in the chain.
154
*
155
* @tparam Extra_Data_Factory The type of extra-data-factory specified in
156
* the server's traits.
157
*
158
* @since v.0.6.13
159
*/
160
template
<
161
std::size_t Size,
162
typename
Extra_Data_Factory =
no_extra_data_factory_t
>
163
class
fixed_size_chain_t
164
{
165
using
actual_request_handle_t
=
166
generic_request_handle_t
<
typename
Extra_Data_Factory
::
data_t
>;
167
168
using
handler_holder_t
= std::function<
169
request_handling_status_t
(
const
actual_request_handle_t &)
170
>;
171
172
std::array<
handler_holder_t
, Size >
m_handlers
;
173
174
template
<
175
typename
Head,
176
typename
... Tail >
177
void
178
store_to
( std::size_t index, Head && head, Tail && ...tail )
179
{
180
m_handlers
[ index ] =
181
[handler = std::move(head)]
182
(
const
actual_request_handle_t & req ) ->
request_handling_status_t
183
{
184
return
handler( req );
185
};
186
187
if
constexpr
( 0u !=
sizeof
...(tail) )
188
store_to( index + 1u, std::forward<Tail>(tail)... );
189
}
190
191
public
:
192
/*!
193
* @attention
194
* The default constructor is disabled. It's because a chain should
195
* be initialized by handlers at the creation time. Because of that
196
* fixed_size_chain_t isn't a DefaultConstructible type.
197
*/
198
fixed_size_chain_t
() =
delete
;
199
200
/*!
201
* @brief Initializing constructor.
202
*
203
* @note
204
* The number of parameters should match the value of @a Size
205
* template parameter.
206
*/
207
template
<
typename
... Handlers >
208
fixed_size_chain_t
( Handlers && ...handlers )
209
{
210
static_assert
( Size ==
sizeof
...(handlers),
211
"Wrong number of parameters for the constructor of "
212
"fixed_size_chain_t<Size>. Exact `Size` parameters expected"
);
213
214
store_to( 0u, std::forward<Handlers>(handlers)... );
215
}
216
217
[[nodiscard]]
218
request_handling_status_t
219
operator
()(
const
actual_request_handle_t & req )
const
220
{
221
for
(
auto
& h :
m_handlers
)
222
{
223
const
request_handling_status_t
result = h( req );
224
225
switch
( result )
226
{
227
case
request_handling_status_t
::
accepted
:
228
case
request_handling_status_t
::
rejected
:
229
// There is no need to try next handler.
230
return
result;
231
232
case
request_handling_status_t
::
not_handled
:
233
// Nothing to do. The next handler should be tried.
234
break
;
235
}
236
}
237
238
return
request_not_handled
(
)
;
239
}
240
};
241
242
}
/* namespace sync_chain */
243
244
}
/* namespace restinio */
restinio::sync_chain::fixed_size_chain_t
A holder of fixed-size chain of synchronous handlers.
Definition
fixed_size.hpp:164
restinio::sync_chain::fixed_size_chain_t::m_handlers
std::array< handler_holder_t, Size > m_handlers
Definition
fixed_size.hpp:172
restinio::sync_chain::fixed_size_chain_t::store_to
void store_to(std::size_t index, Head &&head, Tail &&...tail)
Definition
fixed_size.hpp:178
restinio::sync_chain::fixed_size_chain_t::fixed_size_chain_t
fixed_size_chain_t()=delete
restinio::sync_chain::fixed_size_chain_t::fixed_size_chain_t
fixed_size_chain_t(Handlers &&...handlers)
Initializing constructor.
Definition
fixed_size.hpp:208
restinio::sync_chain::fixed_size_chain_t::operator()
request_handling_status_t operator()(const actual_request_handle_t &req) const
Definition
fixed_size.hpp:219
restinio::sync_chain::fixed_size_chain_t::handler_holder_t
std::function< request_handling_status_t(const actual_request_handle_t &) > handler_holder_t
Definition
fixed_size.hpp:168
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::request_handling_status_t::accepted
@ accepted
Request accepted for handling.
Definition
common_types.hpp:28
restinio::request_handling_status_t::not_handled
@ not_handled
The request wasn't handled. If there is another handler to be tried it should be tried....
Definition
common_types.hpp:38
restinio::request_handling_status_t::rejected
@ rejected
Request wasn't accepted for handling.
Definition
common_types.hpp:31
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