RESTinio
Loading...
Searching...
No Matches
request_handler.hpp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
9#pragma once
10
12
18
19#include <array>
20#include <functional>
21#include <iosfwd>
22#include <new>
23
24namespace restinio
25{
26
27//
28// extra_data_buffer_t
29//
53template< typename Extra_Data >
55{
56 void * m_buffer;
57
58public:
59 extra_data_buffer_t( void * buffer ) : m_buffer{ buffer } {}
60
61 [[nodiscard]]
62 void *
63 get() const noexcept { return m_buffer; }
64};
65
66//
67// no_extra_data_factory_t
68//
78{
83 struct data_t {};
84
85 void
87 {
88 new(buffer.get()) data_t{};
89 }
90};
91
92//
93// simple_extra_data_factory_t
94//
118template< typename Extra_Data >
120{
122
123 void
125 noexcept( noexcept(new(buffer.get()) data_t{}) )
126 {
127 new(buffer.get()) data_t{};
128 }
129};
130
131template< typename Extra_Data >
132class generic_request_t;
133
134namespace impl
135{
136
137template< typename Extra_Data >
140
141//
142// generic_request_extra_data_holder_t
143//
154template< typename Extra_Data >
156{
157 alignas(Extra_Data) std::array<char, sizeof(Extra_Data)> m_data;
158
159public:
160 template< typename Factory >
166
168 {
169 get_ptr()->~Extra_Data();
170 }
171
172 [[nodiscard]]
173 Extra_Data *
175 {
176 // Because the content of m_data.data() is rewritten by
177 // placement new we have to use std::launder to avoid UB.
178 return std::launder(
179 reinterpret_cast<Extra_Data *>(m_data.data()) );
180 }
181
182 [[nodiscard]]
183 const Extra_Data *
185 {
186 // Because the content of m_data.data() is rewritten by
187 // placement new we have to use std::launder to avoid UB.
188 return std::launder(
189 reinterpret_cast<const Extra_Data *>(m_data.data()) );
190 }
191};
192
193} /* namespace impl */
194
195//
196// generic_request_t
197//
198
200
207template< typename Extra_Data >
209 : public std::enable_shared_from_this< generic_request_t< Extra_Data > >
210{
211 template< typename UD >
214
215 public:
217
221 template< typename Extra_Data_Factory >
225 std::string body,
226 impl::connection_handle_t connection,
228 Extra_Data_Factory & extra_data_factory )
231 std::move( header ),
232 std::move( body ),
234 std::move( connection ),
235 std::move( remote_endpoint ),
236 extra_data_factory
237 }
238 {}
239
241
244 template< typename Extra_Data_Factory >
248 std::string body,
250 impl::connection_handle_t connection,
252 Extra_Data_Factory & extra_data_factory )
254 , m_header{ std::move( header ) }
255 , m_body{ std::move( body ) }
257 , m_connection{ std::move( connection ) }
260 , m_extra_data_holder{ extra_data_factory }
261 {}
262
266 {
267 return m_header;
268 }
269
271 const std::string &
273 {
274 return m_body;
275 }
276
277 template < typename Output = restinio_controlled_output_t >
278 auto
280 {
282
284 status_line,
285 std::move( m_connection ),
288 }
289
292
295
298
300
309 {
310 return m_chunked_input_info.get();
311 }
312
348 [[nodiscard]]
349 Extra_Data &
351 {
352 return *m_extra_data_holder.get_ptr();
353 }
354
394 [[nodiscard]]
395 const Extra_Data &
397 {
398 return *m_extra_data_holder.get_ptr();
399 }
400
401 private:
402 void
404 {
405 if( !m_connection )
406 {
407 throw exception_t{ "connection already moved" };
408 }
409 }
410
413 const std::string m_body;
414
416
423
426
429
437};
438
439template< typename Extra_Data >
440std::ostream &
442 std::ostream & o,
444{
445 o << "{req_id: " << req.request_id() << ", "
446 "conn_id: " << req.connection_id() << ", "
447 "path: " << req.header().path() << ", "
448 "query: " << req.header().query() << "}";
449
450 return o;
451}
452
454template< typename Extra_Data >
456 std::shared_ptr< generic_request_t< Extra_Data > >;
457
459
465
467
472using request_handle_t = std::shared_ptr< request_t >;
473
474//
475// default_request_handler_t
476//
477
479 std::function< request_handling_status_t ( request_handle_t ) >;
480
481namespace impl
482{
483
484template< typename Extra_Data >
487{
488 return req.m_connection;
489}
490
491} /* namespace impl */
492
493
494} /* namespace restinio */
Information about chunked encoded body.
Exception class for all exceptions thrown by RESTinio.
Definition exception.hpp:26
Helper for holding a pointer to a buffer where a new object of type Extra_Data should be constructed.
void * get() const noexcept
const http_request_header_t & header() const noexcept
Get request header.
const chunked_input_info_unique_ptr_t m_chunked_input_info
Optional description for chunked-encoding.
const std::string & body() const noexcept
Get request body.
auto request_id() const noexcept
Get request id.
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.
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.
const endpoint_t & remote_endpoint() const noexcept
Get the remote endpoint of the underlying connection.
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.
const Extra_Data & extra_data() const noexcept
Get readonly access to extra-data object incorporated into a request object.
connection_id_t connection_id() const noexcept
Get connection id.
const endpoint_t m_remote_endpoint
Remote endpoint for underlying connection.
auto create_response(http_status_line_t status_line=status_ok())
nullable_pointer_t< const chunked_input_info_t > chunked_input_info() const noexcept
Get optional info about chunked input.
impl::connection_handle_t m_connection
const http_request_header_t m_header
Extra_Data & extra_data() noexcept
Get writeable access to extra-data object incorporated into a request object.
const connection_id_t m_connection_id
HTTP response header status line.
Helper class for holding a buffer for extra-data object to be incorporated into a request object.
std::array< char, sizeof(Extra_Data)> m_data
Forbid arbitrary response_builder_t instantiations.
Detection of compiler version and absence of various features.
connection_handle_t & access_req_connection(generic_request_t< Extra_Data > &) noexcept
std::shared_ptr< connection_base_t > connection_handle_t
Alias for http connection handle.
std::function< request_handling_status_t(request_handle_t) > default_request_handler_t
asio_ns::ip::tcp::endpoint endpoint_t
An alias for endpoint type from Asio.
unsigned int request_id_t
Request id in scope of single connection.
std::shared_ptr< generic_request_t< Extra_Data > > generic_request_handle_t
An alias for shared-pointer to incoming request.
std::shared_ptr< request_t > request_handle_t
An alias for handle for incoming request without additional extra-data.
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
std::ostream & operator<<(std::ostream &o, response_parts_attr_t attr)
T * nullable_pointer_t
Type for pointer that can be nullptr.
http_status_line_t status_ok()
request_handling_status_t
Request handling status.
std::unique_ptr< chunked_input_info_t > chunked_input_info_unique_ptr_t
Alias of unique_ptr for chunked_input_info.
std::uint64_t connection_id_t
Type for ID of connection.
bool should_keep_alive() const noexcept
A type of extra-data to be incorporated into a request object by the default.
The default extra-data-factory to be used in server's traits if a user doesn't specify own one.
void make_within(extra_data_buffer_t< data_t > buffer) noexcept
A helper template class for cases when extra-data-factory is just a simple stateless object.
void make_within(extra_data_buffer_t< data_t > buffer) noexcept(noexcept(new(buffer.get()) data_t{}))