RESTinio

request_handler.hpp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
9#pragma once
10
11#include <restinio/exception.hpp>
12#include <restinio/http_headers.hpp>
13#include <restinio/message_builders.hpp>
14#include <restinio/chunked_input_info.hpp>
15#include <restinio/impl/connection_base.hpp>
16
17#include <array>
18#include <functional>
19#include <iosfwd>
20
21 namespace restinio
22{
23
24//
25// extra_data_buffer_t
26//
50 template< typename Extra_Data >
51 class extra_data_buffer_t
52{
53 void * m_buffer;
54
55 public:
56 extra_data_buffer_t( void * buffer ) : m_buffer{ buffer } {}
57
58 RESTINIO_NODISCARD
59 void *
60 get() const noexcept { return m_buffer; }
61};
62
63//
64// no_extra_data_factory_t
65//
74 struct no_extra_data_factory_t
75{
80 struct data_t {};
81
82 void
83 make_within( extra_data_buffer_t<data_t> buffer ) noexcept
84 {
85 new(buffer.get()) data_t{};
86 }
87};
88
89//
90// simple_extra_data_factory_t
91//
115 template< typename Extra_Data >
116 struct simple_extra_data_factory_t
117{
118 using data_t = Extra_Data;
119
120 void
121 make_within( extra_data_buffer_t<data_t> buffer )
122 noexcept( noexcept(new(buffer.get()) data_t{}) )
123 {
124 new(buffer.get()) data_t{};
125 }
126};
127
128 template< typename Extra_Data >
129 class generic_request_t;
130
131 namespace impl
132{
133
134 template< typename Extra_Data >
135 connection_handle_t &
136 access_req_connection( generic_request_t<Extra_Data> & ) noexcept;
137
138//
139// generic_request_extra_data_holder_t
140//
151 template< typename Extra_Data >
152 class generic_request_extra_data_holder_t
153{
154 alignas(Extra_Data) std::array<char, sizeof(Extra_Data)> m_data;
155
156 public:
157 template< typename Factory >
158 generic_request_extra_data_holder_t(
159 Factory & factory )
160 {
161 factory.make_within( extra_data_buffer_t<Extra_Data>{ m_data.data() } );
162 }
163
164 ~generic_request_extra_data_holder_t() noexcept
165 {
166 get_ptr()->~Extra_Data();
167 }
168
169 RESTINIO_NODISCARD
170 Extra_Data *
171 get_ptr() noexcept
172 {
173 return reinterpret_cast<Extra_Data *>(m_data.data());
174 }
175
176 RESTINIO_NODISCARD
177 const Extra_Data *
178 get_ptr() const noexcept
179 {
180 return reinterpret_cast<const Extra_Data *>(m_data.data());
181 }
182};
183
184} /* namespace impl */
185
186//
187// generic_request_t
188//
189
191
198 template< typename Extra_Data >
199 class generic_request_t final
200 : public std::enable_shared_from_this< generic_request_t< Extra_Data > >
201{
202 template< typename UD >
203 friend impl::connection_handle_t &
204 impl::access_req_connection( generic_request_t<UD> & ) noexcept;
205
206 public:
208
212 template< typename Extra_Data_Factory >
213 generic_request_t(
214 request_id_t request_id,
215 http_request_header_t header,
216 std::string body,
217 impl::connection_handle_t connection,
218 endpoint_t remote_endpoint,
219 Extra_Data_Factory & extra_data_factory )
220 : generic_request_t{
221 request_id,
222 std::move( header ),
223 std::move( body ),
224 chunked_input_info_unique_ptr_t{},
225 std::move( connection ),
226 std::move( remote_endpoint ),
227 extra_data_factory
228 }
229 {}
230
232
235 template< typename Extra_Data_Factory >
236 generic_request_t(
237 request_id_t request_id,
238 http_request_header_t header,
239 std::string body,
240 chunked_input_info_unique_ptr_t chunked_input_info,
241 impl::connection_handle_t connection,
242 endpoint_t remote_endpoint,
243 Extra_Data_Factory & extra_data_factory )
244 : m_request_id{ request_id }
245 , m_header{ std::move( header ) }
246 , m_body{ std::move( body ) }
247 , m_chunked_input_info{ std::move( chunked_input_info ) }
248 , m_connection{ std::move( connection ) }
249 , m_connection_id{ m_connection->connection_id() }
250 , m_remote_endpoint{ std::move( remote_endpoint ) }
251 , m_extra_data_holder{ extra_data_factory }
252 {}
253
255 const http_request_header_t &
256 header() const noexcept
257 {
258 return m_header;
259 }
260
262 const std::string &
263 body() const noexcept
264 {
265 return m_body;
266 }
267
268 template < typename Output = restinio_controlled_output_t >
269 auto
270 create_response( http_status_line_t status_line = status_ok() )
271 {
272 check_connection();
273
274 return response_builder_t< Output >{
275 status_line,
276 std::move( m_connection ),
277 m_request_id,
278 m_header.should_keep_alive() };
279 }
280
282 auto request_id() const noexcept { return m_request_id; }
283
285 connection_id_t connection_id() const noexcept { return m_connection_id; }
286
288 const endpoint_t & remote_endpoint() const noexcept { return m_remote_endpoint; }
289
291
298 nullable_pointer_t< const chunked_input_info_t >
299 chunked_input_info() const noexcept
300 {
301 return m_chunked_input_info.get();
302 }
303
339 RESTINIO_NODISCARD
340 Extra_Data &
341 extra_data() noexcept
342 {
343 return *m_extra_data_holder.get_ptr();
344 }
345
385 RESTINIO_NODISCARD
386 const Extra_Data &
387 extra_data() const noexcept
388 {
389 return *m_extra_data_holder.get_ptr();
390 }
391
392 private:
393 void
394 check_connection()
395 {
396 if( !m_connection )
397 {
398 throw exception_t{ "connection already moved" };
399 }
400 }
401
402 const request_id_t m_request_id;
403 const http_request_header_t m_header;
404 const std::string m_body;
405
407
413 const chunked_input_info_unique_ptr_t m_chunked_input_info;
414
415 impl::connection_handle_t m_connection;
416 const connection_id_t m_connection_id;
417
419 const endpoint_t m_remote_endpoint;
420
427 impl::generic_request_extra_data_holder_t< Extra_Data > m_extra_data_holder;
428};
429
430 template< typename Extra_Data >
431std::ostream &
432 operator<<(
433 std::ostream & o,
434 const generic_request_t< Extra_Data > & req )
435{
436 o << "{req_id: " << req.request_id() << ", "
437 "conn_id: " << req.connection_id() << ", "
438 "path: " << req.header().path() << ", "
439 "query: " << req.header().query() << "}";
440
441 return o;
442}
443
445 template< typename Extra_Data >
446 using generic_request_handle_t =
447 std::shared_ptr< generic_request_t< Extra_Data > >;
448
450
455 using request_t = generic_request_t< no_extra_data_factory_t::data_t >;
456
458
463 using request_handle_t = std::shared_ptr< request_t >;
464
465//
466// default_request_handler_t
467//
468
469 using default_request_handler_t =
470 std::function< request_handling_status_t ( request_handle_t ) >;
471
472 namespace impl
473{
474
475 template< typename Extra_Data >
476 connection_handle_t &
477 access_req_connection( generic_request_t<Extra_Data> & req ) noexcept
478{
479 return req.m_connection;
480}
481
482} /* namespace impl */
483
484
485} /* namespace restinio */
chunked_input_info.hpp
Information about chunked encoded body.
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
restinio::extra_data_buffer_t
Helper for holding a pointer to a buffer where a new object of type Extra_Data should be constructed.
Definition: request_handler.hpp:52
restinio::extra_data_buffer_t::get
RESTINIO_NODISCARD void * get() const noexcept
Definition: request_handler.hpp:60
restinio::extra_data_buffer_t::extra_data_buffer_t
extra_data_buffer_t(void *buffer)
Definition: request_handler.hpp:56
restinio::extra_data_buffer_t::m_buffer
void * m_buffer
Definition: request_handler.hpp:53
restinio::generic_request_t
HTTP Request data.
Definition: request_handler.hpp:201
restinio::generic_request_t::header
const http_request_header_t & header() const noexcept
Get request header.
Definition: request_handler.hpp:256
restinio::generic_request_t::m_chunked_input_info
const chunked_input_info_unique_ptr_t m_chunked_input_info
Optional description for chunked-encoding.
Definition: request_handler.hpp:413
restinio::generic_request_t::body
const std::string & body() const noexcept
Get request body.
Definition: request_handler.hpp:263
restinio::generic_request_t::request_id
auto request_id() const noexcept
Get request id.
Definition: request_handler.hpp:282
restinio::generic_request_t::generic_request_t
generic_request_t(request_id_t request_id, http_request_header_t header, std::string body, impl::connection_handle_t connection, endpoint_t remote_endpoint, Extra_Data_Factory &extra_data_factory)
Old-format initializing constructor.
Definition: request_handler.hpp:213
restinio::generic_request_t::generic_request_t
generic_request_t(request_id_t request_id, http_request_header_t header, std::string body, chunked_input_info_unique_ptr_t chunked_input_info, impl::connection_handle_t connection, endpoint_t remote_endpoint, Extra_Data_Factory &extra_data_factory)
New-format initializing constructor.
Definition: request_handler.hpp:236
restinio::generic_request_t::check_connection
void check_connection()
Definition: request_handler.hpp:394
restinio::generic_request_t::remote_endpoint
const endpoint_t & remote_endpoint() const noexcept
Get the remote endpoint of the underlying connection.
Definition: request_handler.hpp:288
restinio::generic_request_t::m_extra_data_holder
impl::generic_request_extra_data_holder_t< Extra_Data > m_extra_data_holder
An instance of extra-data that is incorporated into a request object.
Definition: request_handler.hpp:427
restinio::generic_request_t::extra_data
RESTINIO_NODISCARD Extra_Data & extra_data() noexcept
Get writeable access to extra-data object incorporated into a request object.
Definition: request_handler.hpp:341
restinio::generic_request_t::connection_id
connection_id_t connection_id() const noexcept
Get connection id.
Definition: request_handler.hpp:285
restinio::generic_request_t::extra_data
RESTINIO_NODISCARD const Extra_Data & extra_data() const noexcept
Get readonly access to extra-data object incorporated into a request object.
Definition: request_handler.hpp:387
restinio::generic_request_t::m_remote_endpoint
const endpoint_t m_remote_endpoint
Remote endpoint for underlying connection.
Definition: request_handler.hpp:419
restinio::generic_request_t::create_response
auto create_response(http_status_line_t status_line=status_ok())
Definition: request_handler.hpp:270
restinio::generic_request_t::m_body
const std::string m_body
Definition: request_handler.hpp:404
restinio::generic_request_t::chunked_input_info
nullable_pointer_t< const chunked_input_info_t > chunked_input_info() const noexcept
Get optional info about chunked input.
Definition: request_handler.hpp:299
restinio::generic_request_t::m_connection
impl::connection_handle_t m_connection
Definition: request_handler.hpp:415
restinio::generic_request_t::m_header
const http_request_header_t m_header
Definition: request_handler.hpp:403
restinio::generic_request_t::m_request_id
const request_id_t m_request_id
Definition: request_handler.hpp:402
restinio::generic_request_t::m_connection_id
const connection_id_t m_connection_id
Definition: request_handler.hpp:416
restinio::http_status_line_t
HTTP response header status line.
Definition: http_headers.hpp:2124
restinio::impl::generic_request_extra_data_holder_t
Helper class for holding a buffer for extra-data object to be incorporated into a request object.
Definition: request_handler.hpp:153
restinio::impl::generic_request_extra_data_holder_t::get_ptr
RESTINIO_NODISCARD Extra_Data * get_ptr() noexcept
Definition: request_handler.hpp:171
restinio::impl::generic_request_extra_data_holder_t::get_ptr
RESTINIO_NODISCARD const Extra_Data * get_ptr() const noexcept
Definition: request_handler.hpp:178
restinio::impl::generic_request_extra_data_holder_t::~generic_request_extra_data_holder_t
~generic_request_extra_data_holder_t() noexcept
Definition: request_handler.hpp:164
restinio::impl::generic_request_extra_data_holder_t::m_data
std::array< char, sizeof(Extra_Data)> m_data
Definition: request_handler.hpp:154
restinio::impl::generic_request_extra_data_holder_t::generic_request_extra_data_holder_t
generic_request_extra_data_holder_t(Factory &factory)
Definition: request_handler.hpp:158
restinio::response_builder_t
Forbid arbitrary response_builder_t instantiations.
Definition: message_builders.hpp:243
RESTINIO_NODISCARD
#define RESTINIO_NODISCARD
Definition: compiler_features.hpp:33
connection_base.hpp
exception.hpp
http_headers.hpp
message_builders.hpp
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:465
restinio::impl::access_req_connection
connection_handle_t & access_req_connection(generic_request_t< Extra_Data > &) noexcept
Definition: request_handler.hpp:477
restinio::impl::connection_handle_t
std::shared_ptr< connection_base_t > connection_handle_t
Alias for http connection handle.
Definition: connection_base.hpp:47
restinio
Definition: asio_include.hpp:21
restinio::nullable_pointer_t
T * nullable_pointer_t
Type for pointer that can be nullptr.
Definition: common_types.hpp:154
restinio::chunked_input_info_unique_ptr_t
std::unique_ptr< chunked_input_info_t > chunked_input_info_unique_ptr_t
Alias of unique_ptr for chunked_input_info.
Definition: chunked_input_info.hpp:230
restinio::generic_request_handle_t
std::shared_ptr< generic_request_t< Extra_Data > > generic_request_handle_t
An alias for shared-pointer to incoming request.
Definition: request_handler.hpp:447
restinio::operator<<
std::ostream & operator<<(std::ostream &o, response_parts_attr_t attr)
Definition: common_types.hpp:82
restinio::request_id_t
unsigned int request_id_t
Request id in scope of single connection.
Definition: common_types.hpp:70
restinio::status_ok
http_status_line_t status_ok()
Definition: http_headers.hpp:2175
restinio::request_handling_status_t
request_handling_status_t
Request handling status.
Definition: common_types.hpp:26
restinio::default_request_handler_t
std::function< request_handling_status_t(request_handle_t) > default_request_handler_t
Definition: request_handler.hpp:470
restinio::endpoint_t
asio_ns::ip::tcp::endpoint endpoint_t
An alias for endpoint type from Asio.
Definition: common_types.hpp:177
restinio::request_handle_t
std::shared_ptr< request_t > request_handle_t
An alias for handle for incoming request without additional extra-data.
Definition: request_handler.hpp:463
restinio::connection_id_t
std::uint64_t connection_id_t
Type for ID of connection.
Definition: common_types.hpp:174
std
STL namespace.
restinio::http_header_common_t::should_keep_alive
bool should_keep_alive() const noexcept
Definition: http_headers.hpp:1611
restinio::http_request_header_t
Req header.
Definition: http_headers.hpp:1859
restinio::http_request_header_t::path
string_view_t path() const noexcept
Request URL-structure.
Definition: http_headers.hpp:1913
restinio::http_request_header_t::query
string_view_t query() const noexcept
Get the query part of the request URL.
Definition: http_headers.hpp:1924
restinio::no_extra_data_factory_t::data_t
A type of extra-data to be incorporated into a request object by the default.
Definition: request_handler.hpp:80
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:75
restinio::no_extra_data_factory_t::make_within
void make_within(extra_data_buffer_t< data_t > buffer) noexcept
Definition: request_handler.hpp:83
restinio::simple_extra_data_factory_t
A helper template class for cases when extra-data-factory is just a simple stateless object.
Definition: request_handler.hpp:117
restinio::simple_extra_data_factory_t::make_within
void make_within(extra_data_buffer_t< data_t > buffer) noexcept(noexcept(new(buffer.get()) data_t{}))
Definition: request_handler.hpp:121
restinio::simple_extra_data_factory_t::data_t
Extra_Data data_t
Definition: request_handler.hpp:118
const
#define const
Definition: zconf.h:230