Loading...
Searching...
No Matches
request_handler.hpp
Go to the documentation of this file.
/*
restinio
*/
#pragma once
#include <restinio/compiler_features.hpp>
#include <restinio/exception.hpp>
#include <restinio/http_headers.hpp>
#include <restinio/message_builders.hpp>
#include <restinio/chunked_input_info.hpp>
#include <restinio/impl/connection_base.hpp>
#include <array>
#include <functional>
#include <iosfwd>
namespace restinio
{
//
// extra_data_buffer_t
//
template< typename Extra_Data >
class extra_data_buffer_t
{
void * m_buffer;
public:
extra_data_buffer_t( void * buffer ) : m_buffer{ buffer } {}
RESTINIO_NODISCARD
void *
get() const noexcept { return m_buffer; }
};
//
// no_extra_data_factory_t
//
struct no_extra_data_factory_t
{
struct data_t {};
void
make_within( extra_data_buffer_t<data_t> buffer ) noexcept
{
new(buffer.get()) data_t{};
}
};
//
// simple_extra_data_factory_t
//
template< typename Extra_Data >
struct simple_extra_data_factory_t
{
using data_t = Extra_Data;
void
make_within( extra_data_buffer_t<data_t> buffer )
noexcept( noexcept(new(buffer.get()) data_t{}) )
{
new(buffer.get()) data_t{};
}
};
template< typename Extra_Data >
class generic_request_t;
namespace impl
{
template< typename Extra_Data >
connection_handle_t &
access_req_connection( generic_request_t<Extra_Data> & ) noexcept;
//
// generic_request_extra_data_holder_t
//
template< typename Extra_Data >
class generic_request_extra_data_holder_t
{
alignas(Extra_Data) std::array<char, sizeof(Extra_Data)> m_data;
public:
template< typename Factory >
generic_request_extra_data_holder_t(
Factory & factory )
{
factory.make_within( extra_data_buffer_t<Extra_Data>{ m_data.data() } );
}
~generic_request_extra_data_holder_t() noexcept
{
get_ptr()->~Extra_Data();
}
RESTINIO_NODISCARD
Extra_Data *
get_ptr() noexcept
{
// Because the content of m_data.data() is rewritten by
// placement new we have to use std::launder to avoid UB.
return RESTINIO_STD_LAUNDER(
reinterpret_cast<Extra_Data *>(m_data.data()) );
}
RESTINIO_NODISCARD
const Extra_Data *
get_ptr() const noexcept
{
// Because the content of m_data.data() is rewritten by
// placement new we have to use std::launder to avoid UB.
return RESTINIO_STD_LAUNDER(
reinterpret_cast<const Extra_Data *>(m_data.data()) );
}
};
} /* namespace impl */
//
// generic_request_t
//
template< typename Extra_Data >
class generic_request_t final
: public std::enable_shared_from_this< generic_request_t< Extra_Data > >
{
template< typename UD >
friend impl::connection_handle_t &
impl::access_req_connection( generic_request_t<UD> & ) noexcept;
public:
template< typename Extra_Data_Factory >
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 )
: generic_request_t{
request_id,
std::move( header ),
std::move( body ),
chunked_input_info_unique_ptr_t{},
std::move( connection ),
std::move( remote_endpoint ),
extra_data_factory
}
{}
template< typename Extra_Data_Factory >
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 )
: m_request_id{ request_id }
, m_header{ std::move( header ) }
, m_body{ std::move( body ) }
, m_chunked_input_info{ std::move( chunked_input_info ) }
, m_connection{ std::move( connection ) }
, m_connection_id{ m_connection->connection_id() }
, m_remote_endpoint{ std::move( remote_endpoint ) }
, m_extra_data_holder{ extra_data_factory }
{}
const http_request_header_t &
header() const noexcept
{
return m_header;
}
const std::string &
body() const noexcept
{
return m_body;
}
template < typename Output = restinio_controlled_output_t >
auto
create_response( http_status_line_t status_line = status_ok() )
{
check_connection();
return response_builder_t< Output >{
status_line,
std::move( m_connection ),
m_request_id,
m_header.should_keep_alive() };
}
auto request_id() const noexcept { return m_request_id; }
connection_id_t connection_id() const noexcept { return m_connection_id; }
const endpoint_t & remote_endpoint() const noexcept { return m_remote_endpoint; }
nullable_pointer_t< const chunked_input_info_t >
chunked_input_info() const noexcept
{
return m_chunked_input_info.get();
}
RESTINIO_NODISCARD
Extra_Data &
extra_data() noexcept
{
return *m_extra_data_holder.get_ptr();
}
RESTINIO_NODISCARD
const Extra_Data &
extra_data() const noexcept
{
return *m_extra_data_holder.get_ptr();
}
private:
void
check_connection()
{
if( !m_connection )
{
throw exception_t{ "connection already moved" };
}
}
const request_id_t m_request_id;
const http_request_header_t m_header;
const std::string m_body;
const chunked_input_info_unique_ptr_t m_chunked_input_info;
impl::connection_handle_t m_connection;
const connection_id_t m_connection_id;
const endpoint_t m_remote_endpoint;
impl::generic_request_extra_data_holder_t< Extra_Data > m_extra_data_holder;
};
template< typename Extra_Data >
std::ostream &
operator<<(
std::ostream & o,
const generic_request_t< Extra_Data > & req )
{
o << "{req_id: " << req.request_id() << ", "
"conn_id: " << req.connection_id() << ", "
"path: " << req.header().path() << ", "
"query: " << req.header().query() << "}";
return o;
}
template< typename Extra_Data >
using generic_request_handle_t =
std::shared_ptr< generic_request_t< Extra_Data > >;
using request_t = generic_request_t< no_extra_data_factory_t::data_t >;
using request_handle_t = std::shared_ptr< request_t >;
//
// default_request_handler_t
//
using default_request_handler_t =
std::function< request_handling_status_t ( request_handle_t ) >;
namespace impl
{
template< typename Extra_Data >
connection_handle_t &
access_req_connection( generic_request_t<Extra_Data> & req ) noexcept
{
return req.m_connection;
}
} /* namespace impl */
} /* 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:54
restinio::extra_data_buffer_t::get
RESTINIO_NODISCARD void * get() const noexcept
Definition: request_handler.hpp:62
restinio::extra_data_buffer_t::extra_data_buffer_t
extra_data_buffer_t(void *buffer)
Definition: request_handler.hpp:58
restinio::extra_data_buffer_t::m_buffer
void * m_buffer
Definition: request_handler.hpp:55
restinio::generic_request_t
HTTP Request data.
Definition: request_handler.hpp:209
restinio::generic_request_t::header
const http_request_header_t & header() const noexcept
Get request header.
Definition: request_handler.hpp:264
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:421
restinio::generic_request_t::body
const std::string & body() const noexcept
Get request body.
Definition: request_handler.hpp:271
restinio::generic_request_t::request_id
auto request_id() const noexcept
Get request id.
Definition: request_handler.hpp:290
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:221
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:244
restinio::generic_request_t::check_connection
void check_connection()
Definition: request_handler.hpp:402
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:296
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:435
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:349
restinio::generic_request_t::connection_id
connection_id_t connection_id() const noexcept
Get connection id.
Definition: request_handler.hpp:293
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:395
restinio::generic_request_t::m_remote_endpoint
const endpoint_t m_remote_endpoint
Remote endpoint for underlying connection.
Definition: request_handler.hpp:427
restinio::generic_request_t::create_response
auto create_response(http_status_line_t status_line=status_ok())
Definition: request_handler.hpp:278
restinio::generic_request_t::m_body
const std::string m_body
Definition: request_handler.hpp:412
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:307
restinio::generic_request_t::m_connection
impl::connection_handle_t m_connection
Definition: request_handler.hpp:423
restinio::generic_request_t::m_header
const http_request_header_t m_header
Definition: request_handler.hpp:411
restinio::generic_request_t::m_request_id
const request_id_t m_request_id
Definition: request_handler.hpp:410
restinio::generic_request_t::m_connection_id
const connection_id_t m_connection_id
Definition: request_handler.hpp:424
restinio::http_status_line_t
HTTP response header status line.
Definition: http_headers.hpp:2125
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:155
restinio::impl::generic_request_extra_data_holder_t::get_ptr
RESTINIO_NODISCARD Extra_Data * get_ptr() noexcept
Definition: request_handler.hpp:173
restinio::impl::generic_request_extra_data_holder_t::get_ptr
RESTINIO_NODISCARD const Extra_Data * get_ptr() const noexcept
Definition: request_handler.hpp:183
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:166
restinio::impl::generic_request_extra_data_holder_t::m_data
std::array< char, sizeof(Extra_Data)> m_data
Definition: request_handler.hpp:156
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:160
restinio::response_builder_t
Forbid arbitrary response_builder_t instantiations.
Definition: message_builders.hpp:243
compiler_features.hpp
Detection of compiler version and absence of various features.
RESTINIO_STD_LAUNDER
#define RESTINIO_STD_LAUNDER(x)
Definition: compiler_features.hpp:47
RESTINIO_NODISCARD
#define RESTINIO_NODISCARD
Definition: compiler_features.hpp:36
connection_base.hpp
exception.hpp
http_headers.hpp
message_builders.hpp
restinio::impl::access_req_connection
connection_handle_t & access_req_connection(generic_request_t< Extra_Data > &) noexcept
Definition: request_handler.hpp:485
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:232
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:455
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:2176
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:478
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:471
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:1612
restinio::http_request_header_t
Req header.
Definition: http_headers.hpp:1860
restinio::http_request_header_t::path
string_view_t path() const noexcept
Request URL-structure.
Definition: http_headers.hpp:1914
restinio::http_request_header_t::query
string_view_t query() const noexcept
Get the query part of the request URL.
Definition: http_headers.hpp:1925
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:82
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:77
restinio::no_extra_data_factory_t::make_within
void make_within(extra_data_buffer_t< data_t > buffer) noexcept
Definition: request_handler.hpp:85
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:119
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:123
restinio::simple_extra_data_factory_t::data_t
Extra_Data data_t
Definition: request_handler.hpp:120
const
#define const
Definition: zconf.h:230