Go to the documentation of this file.
13 #include <http_parser.h>
131 result = std::make_unique< chunked_input_info_t >(
150 template<
typename Http_Methods >
151 inline http_parser_settings
154 http_parser_settings parser_settings;
155 http_parser_settings_init( &parser_settings );
157 parser_settings.on_url =
158 []( http_parser * parser,
const char * at,
size_t length ) ->
int {
162 parser_settings.on_header_field =
163 []( http_parser * parser,
const char * at,
size_t length ) ->
int {
167 parser_settings.on_header_value =
168 []( http_parser * parser,
const char * at,
size_t length ) ->
int {
172 parser_settings.on_headers_complete =
173 []( http_parser * parser ) ->
int {
177 parser_settings.on_body =
178 []( http_parser * parser,
const char * at,
size_t length ) ->
int {
182 parser_settings.on_chunk_header =
183 []( http_parser * parser ) ->
int {
187 parser_settings.on_chunk_complete =
188 []( http_parser * parser ) ->
int {
192 parser_settings.on_message_complete =
193 []( http_parser * parser ) ->
int {
194 return restinio_message_complete_cb< Http_Methods >( parser );
197 return parser_settings;
212 pending_upgrade_handling,
228 std::size_t buffer_size,
231 ,
m_buf{ buffer_size }
255 http_parser_init( &
m_parser, HTTP_REQUEST);
263 template <
typename Connection,
typename Start_Read_CB,
typename Failed_CB >
266 asio_ns::ip::tcp::socket & ,
268 Start_Read_CB start_read_cb,
278 asio_ns::ip::tcp::socket & ) noexcept
302 template <
typename Traits >
348 "[connection:{}] start connection with {}",
365 "[connection:{}] destructor called",
378 m_settings->call_state_listener( [
this]() noexcept {
396 [ & ](
const asio_ns::error_code & ec ){
399 "[connection:{}] prepare connection error: {}",
412 "[connection:{}] start waiting for request",
479 "[connection:{}] continue reading request",
487 asio_ns::bind_executor(
489 [
this, ctx = shared_from_this()]
491 (
const asio_ns::error_code & ec,
492 std::size_t length ) noexcept {
501 "[connection:{}] skip read operation: already running",
509 after_read(
const asio_ns::error_code & ec, std::size_t length ) noexcept
520 "[connection:{}] received {} bytes",
529 catch(
const std::exception & x )
533 "[connection:{}] unexpected exception during the "
534 "handling of incoming data: {}",
549 "[connection:{}] read socket error: {}; "
564 "[connection:{}] EOF and no request, "
596 if( HPE_OK != parser.http_errno &&
597 HPE_PAUSED != parser.http_errno )
600 auto err = HTTP_PARSER_ERRNO( &parser );
605 "[connection:{}] parser error {}: {}",
607 http_errno_name( err ),
608 http_errno_description( err ) );
640 connection_upgrade_stage_t::pending_upgrade_handling;
651 "[connection:{}] request received (#{}): {} {}",
655 static_cast<http_method
>( parser.method ) ),
656 parser_ctx.m_header.request_target() );
667 std::make_shared< request_t >(
671 parser_ctx.make_chunked_input_info_if_necessary(),
672 shared_from_concrete< connection_base_t >(),
695 const std::string default_value{};
698 "[connection:{}] upgrade request received: {} {}; "
702 static_cast<http_method
>( parser.method ) ),
703 parser_ctx.m_header.request_target(),
704 parser_ctx.m_header.get_field_or(
721 "[connection:{}] upgrade request happened to be a pipelined one, "
722 "and will be handled after previous requests are handled",
731 catch(
const std::exception & ex )
735 "[connection:{}] error while handling request: {}",
760 "[connection:{}] handle upgrade request (#{}): {} {}",
764 static_cast<http_method
>( parser.method ) ),
765 parser_ctx.m_header.request_target() );
778 std::make_shared< request_t >(
782 parser_ctx.make_chunked_input_info_if_necessary(),
783 shared_from_concrete< connection_base_t >(),
806 "[connection:{}] upgrade request handler rejects "
807 "request, but socket was moved out from connection",
841 response_output_flags,
843 ctx = shared_from_this() ]
851 response_output_flags,
854 catch(
const std::exception & ex )
858 "[connection:{}] unable to handle response: {}",
876 auto invoke_after_write_cb_with_error = [&]{
881 asio_convertible_error_t::write_was_not_executed ) );
883 catch(
const std::exception & ex )
887 "[connection:{}] notificator error: {}",
917 "[connection:{}] append response (#{}), "
918 "flags: {}, write group size: {}",
921 response_output_flags,
927 response_output_flags,
936 "[connection:{}] receive response parts for "
937 "request (#{}), but response with connection-close "
938 "attribute happened before",
942 invoke_after_write_cb_with_error();
949 "[connection:{}] try to write response, "
950 "while socket is closed",
953 invoke_after_write_cb_with_error();
978 const bool response_coordinator_full_before =
983 if( next_write_group )
987 "[connection:{}] start next write group for response (#{}), "
990 next_write_group->second,
991 next_write_group->first.items_count() );
995 const bool response_coordinator_full_after =
1000 response_coordinator_full_before &&
1001 !response_coordinator_full_after;
1003 if( 0 < next_write_group->first.status_line_size() )
1007 writable_item_type_t::trivial_write_operation ==
1008 next_write_group->first.items().front().write_type() );
1014 asio_ns::buffer_cast< const char * >(
1015 next_write_group->first.items().front().buf() ),
1016 next_write_group->first.status_line_size() };
1020 "[connection:{}] start response (#{}): {}",
1022 next_write_group->second,
1064 if( holds_alternative< trivial_write_operation_t >( wo ) )
1068 else if( holds_alternative< file_write_operation_t >( wo ) )
1074 assert( holds_alternative< none_write_operation_t >( wo ) );
1078 catch(
const std::exception & ex )
1082 "[connection:{}] handle_current_write_ctx failed: {}",
1100 "[connection:{}] sending resp data with "
1101 "connection-close attribute "
1110 asio_ns::error_code ignored_ec;
1117 "[connection:{}] sending resp data, "
1126 asio_ns::async_write(
1129 asio_ns::bind_executor(
1131 [
this, ctx = shared_from_this()]
1133 (
const asio_ns::error_code & ec, std::size_t written ) noexcept
1140 "[connection:{}] outgoing data was sent: {} bytes",
1160 "[connection:{}] sending resp file data with "
1161 "connection-close attribute, "
1168 asio_ns::error_code ignored_ec;
1175 "[connection:{}] sending resp file data, total size: {}",
1188 asio_ns::bind_executor(
1190 [
this, ctx = shared_from_this(),
1194 (
const asio_ns::error_code & ec,
file_size_t written )
mutable noexcept
1211 "[connection:{}] file data was sent: {} bytes",
1221 "[connection:{}] send file data error: {} ({}) bytes",
1239 "[connection:{}] finishing current write group",
1250 "[connection:{}] should keep alive",
1310 "[connection:{}] last sent response was marked "
1351 "[connection:{}] unable to write: {}",
1362 catch(
const std::exception & ex )
1367 "[connection:{}] notificator error: {}",
1385 "[connection:{}] close",
1393 "connection.socket.shutdown",
1395 asio_ns::error_code ignored_ec;
1397 asio_ns::ip::tcp::socket::shutdown_both,
1402 "connection.socket.close",
1410 "[connection:{}] close: close socket",
1420 "[connection:{}] close: timer canceled",
1429 "[connection:{}] close: reset responses data",
1434 m_settings->call_state_listener_suppressing_exceptions(
1449 template<
typename Message_Builder >
1508 conn_object.check_timeout_impl();
1510 catch(
const std::exception & x )
1512 conn_object.trigger_error_and_close( [&] {
1513 return fmt::format(
"[connection: {}] unexpected "
1514 "error during timeout handling: {}",
1515 conn_object.connection_id(),
1568 std::chrono::steady_clock::time_point timeout_after,
1577 std::chrono::steady_clock::duration timeout,
1581 std::chrono::steady_clock::now() + timeout,
1590 "[connection:{}] {} timed out",
1611 m_settings->m_read_next_http_message_timelimit,
1659 timelimit =
m_settings->m_write_http_response_timelimit;
1689 template <
typename Traits >
1700 std::unique_ptr< socket_options_setter_t > socket_options_setter )
1720 (*m_socket_options_setter)( options );
1723 return std::make_shared< connection_type_t >(
@ not_final_parts
Intermediate parts (more parts of response to follow).
connection_id_t connection_id() const noexcept
Get connection id.
asio_ns::error_code make_asio_compaible_error(asio_convertible_error_t err) noexcept
Make restinio error_code compatible with asio_ns::error_code.
void handle_file_write_operation(file_write_operation_t &op)
Run sendfile write operation.
std::size_t length() const noexcept
How many unconsumed bytes are there in buffer.
Helper class for reading bytes and feeding them to parser.
http_request_header_t m_header
Request data.
#define RESTINIO_NODISCARD
Traits::strand_t & get_executor() noexcept
An executor for callbacks on async operations.
void init_write()
Initiate write operation.
void handle_xxx_timeout(const char *operation_name)
void append_response(request_id_t req_id, response_output_flags_t response_output_flags, write_group_t wg)
Add outgoing data for specified request.
logger_t & m_logger
Logger for operation.
typename Traits::request_handler_t request_handler_t
void prepare_connection_and_start_read(asio_ns::ip::tcp::socket &, Connection &, Start_Read_CB start_read_cb, Failed_CB)
const endpoint_t m_remote_endpoint
Remote endpoint for this connection.
void schedule_operation_timeout_callback(std::chrono::steady_clock::time_point timeout_after, timout_cb_t timout_cb)
Helper function to work with timer guard.
upgrade_internals_t(upgrade_internals_t &&)=default
std::size_t m_total_field_count
Total number of parsed HTTP-fields.
connection_t(connection_t &&)=delete
typename Traits::logger_t logger_t
connection_t(connection_id_t conn_id, stream_socket_t &&socket, connection_settings_handle_t< Traits > settings, endpoint_t remote_endpoint, lifetime_monitor_t lifetime_monitor)
bool transmitting() const noexcept
Check if data is trunsmitting now.
tcp_connection_ctx_weak_handle_t m_prepared_weak_ctx
A prepared weak handle for passing it to timer guard.
auto create_new_connection(stream_socket_t socket, endpoint_t remote_endpoint, lifetime_monitor_t lifetime_monitor)
asio_ns::ip::tcp::endpoint endpoint_t
An alias for endpoint type from Asio.
Helper class for writting response data.
solid_write_operation_variant_t extract_next_write_operation()
et an object with next write operation to perform.
std::uint64_t file_size_t
Helper type for controlling the lifetime of the connection.
std::string m_current_field_name
Parser context temp values and flags.
void init_write_if_necessary()
void wait_for_http_message()
Start reading next htttp-message.
tls_socket_t * make_tls_socket_pointer_for_state_listener(asio_ns::ip::tcp::socket &) noexcept
void fail_write_group(const asio_ns::error_code &ec)
Handle current group write process failed.
int restinio_chunk_header_cb(http_parser *parser)
virtual void check_timeout(tcp_connection_ctx_handle_t &self) override
Schedules real timedout operations check on the executer of a connection.
void init_next_timeout_checking()
Schedule next timeout checking.
bool m_message_complete
Flag: is http message parsed completely.
void cancel_timeout_checking() noexcept
Stop timout guarding.
constexpr underlying_uint_t zero
The minimal allowed value for a qvalue.
Wrapper for an executor (strand) used by connections.
auto items_count() const noexcept
Get the count of stored items.
void handle_upgrade_request()
Calls handler for upgrade request.
void check_timeout_impl()
Check timed out operation.
void start_next_write_group(optional_t< write_group_t > next_wg) noexcept
Start handlong next write group.
upgrade_internals_t move_upgrade_internals()
Move socket out of connection.
@ connection_close
This response says to close connection.
nonstd::string_view string_view_t
connection_factory_t(connection_settings_handle_t< Traits > connection_settings, std::unique_ptr< socket_options_setter_t > socket_options_setter)
bool empty() const noexcept
void consumed_bytes(std::size_t length) noexcept
Mark how many bytes were obtained.
scope_exit_details::at_exit_t< L > at_scope_exit(L &&l)
Helper function for creation action to be performed at scope exit.
std::uint64_t connection_id_t
Type for ID of connection.
void guard_request_handling_operation()
Start guard request handling operation if necessary.
RESTINIO_NODISCARD chunked_input_info_unique_ptr_t make_chunked_input_info_if_necessary()
Creates an instance of chunked_input_info if there is an info about chunks in the body.
int restinio_chunk_complete_cb(http_parser *)
Coordinator for process of sending responses with respect to http pipeline technique and chunk transf...
ws_handle_t upgrade(request_t &req, activation_t activation_flag, http_header_fields_t upgrade_response_header_fields, WS_Message_Handler ws_message_handler)
Upgrade http-connection of a current request to a websocket connection.
int restinio_url_cb(http_parser *parser, const char *at, size_t length)
void schedule_operation_timeout_callback(std::chrono::steady_clock::duration timeout, timout_cb_t timout_cb)
A type of holder of limits related to an incoming HTTP message.
Type of object that tells that new connection has been accepted.
#define RESTINIO_ENSURE_NOEXCEPT_CALL(expr)
A wrapper around static_assert for checking that an expression is noexcept and execution of that expr...
int restinio_headers_complete_cb(http_parser *parser)
void finish_handling_current_write_ctx()
Do post write actions for current write group.
lifetime_monitor_t m_lifetime_monitor
Stuff related to limits of active parallel connections.
void obtained_bytes(std::size_t length) noexcept
Mark how many bytes were obtained.
typename Traits::logger_t logger_t
void log_error_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
request_id_t register_new_request()
Create a new request and reserve context for its response.
chunked_input_info_block_t m_chunked_info_block
connection_upgrade_stage_t
Enum for a flag specifying that connection is going to upgrade or not.
void consume_data(const char *data, std::size_t length)
Parse some data.
std::unique_ptr< socket_options_setter_t > m_socket_options_setter
void invoke_after_write_notificator_if_exists(const asio_ns::error_code &ec)
Get after write notificator.
void handle_nothing_to_write()
void on_request_message_complete()
Handle a given request message.
static connection_t & cast_to_self(tcp_connection_ctx_base_t &base)
Timer to controll operations.
std::shared_ptr< connection_settings_t< Traits > > connection_settings_handle_t
void reset()
Prepare context to handle new request.
Socket adapter for asio::ssl::stream< asio::ip::tcp::socket >.
bool m_leading_headers_completed
typename Traits::stream_socket_t stream_socket_t
An adapter for setting acceptor options before running server.
auto make_asio_buffer() noexcept
Make asio buffer for reading bytes from socket.
void handle_sendfile_timeout()
auto size() const noexcept
Get the size of sendfile operation.
void log_trace_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
void handle_request_handling_timeout()
void write_response_parts_impl(request_id_t request_id, response_output_flags_t response_output_flags, write_group_t wg)
Write parts for specified request.
stream_socket_t m_socket
Connection.
connection_settings_handle_t< Traits > m_settings
timer_guard_t m_timer_guard
Timer guard.
void suppress_exceptions(Logger &&logger, const char *block_description, Lambda &&lambda) noexcept
Helper function for execution a block of code with suppression of any exceptions raised inside that b...
A special wrapper around fmtlib include files.
connection_input_t m_input
Input routine.
void trigger_error_and_close(Message_Builder msg_builder) noexcept
Trigger an error.
typename Traits::timer_manager_t timer_manager_t
int restinio_body_cb(http_parser *parser, const char *at, size_t length)
int restinio_header_field_cb(http_parser *parser, const char *at, size_t length)
http_parser_ctx_t(incoming_http_msg_limits_t limits)
The main constructor.
std::size_t m_last_value_total_size
auto timelimit() const noexcept
Get the timelimit on this sendfile operation.
An object with info about connection to be passed to state listener.
Group of writable items transported to the context of underlying connection as one solid piece.
connection_t & operator=(const connection_t &)=delete
void(connection_t::*)(void) timout_cb_t
Callback type for timedout operations.
bool error_is_eof(const asio_ns::error_code &ec) noexcept
void start_sendfile_operation(default_asio_executor executor, Socket &socket, After_Write_CB after_sendfile_cb)
Start a sendfile operation.
Response output flags for buffers commited to response-coordinator.
void finish_write_group()
Finish writing group normally.
typename Traits::stream_socket_t stream_socket_t
const std::vector< asio_ns::const_buffer > & get_trivial_bufs() const noexcept
Get buffer "iovec" for performing gather write.
response_coordinator_t m_response_coordinator
Response coordinator.
A simple implementation of at_scope_exit concept.
void handle_read_timeout()
typename connection_count_limit_types< Traits >::lifetime_monitor_t lifetime_monitor_t
auto size() const noexcept
The size of data within this operation.
connection_settings_handle_t< Traits > m_connection_settings
void guard_read_operation()
Statr guard read operation if necessary.
Type of object that tells that the connection has been closed.
optional_t< std::pair< write_group_t, request_id_t > > pop_ready_buffers()
Extract a portion of data available for write.
connection_settings_handle_t< Traits > m_settings
Common paramaters of a connection.
void handle_trivial_write_operation(const trivial_write_operation_t &op)
Run trivial buffers write operation.
bool m_init_read_after_this_write
void handle_write_response_timeout()
std::shared_ptr< tcp_connection_ctx_base_t > tcp_connection_ctx_handle_t
Alias for http connection handle.
executor_wrapper_t< typename Traits::strand_t > executor_wrapper_base_t
unsigned int request_id_t
Request id in scope of single connection.
void after_read(const asio_ns::error_code &ec, std::size_t length) noexcept
Handle read operation result.
Parsing result context for using in parser callbacks.
Internals that are necessary for upgrade.
std::weak_ptr< tcp_connection_ctx_base_t > tcp_connection_ctx_weak_handle_t
Alias for http connection weak handle.
void close() noexcept
Close connection functions.
@ none
No connection request in progress.
bool is_able_to_get_more_messages() const noexcept
Check if it is possible to accept more requests.
const char * bytes() const noexcept
Get pointer to unconsumed bytes.
lifetime_monitor_t m_lifetime_monitor
Monitor of the connection lifetime.
void consume_message()
Start (continue) a chain of read-parse-read-... operations.
bool error_is_operation_aborted(const asio_ns::error_code &ec) noexcept
std::chrono::steady_clock::time_point m_current_timeout_after
Timeout point of a current guarded operation.
int restinio_header_value_cb(http_parser *parser, const char *at, size_t length)
Helpers for safe truncation of unsigned integers.
void reset() noexcept
Remove all contexts.
std::unique_ptr< chunked_input_info_t > chunked_input_info_unique_ptr_t
Alias of unique_ptr for chunked_input_info.
constexpr request_handling_status_t request_rejected() noexcept
void handle_current_write_ctx() noexcept
Start/continue/continue handling output data of current write group.
const incoming_http_msg_limits_t m_limits
Limits for the incoming message.
typename timer_manager_t::timer_guard_t timer_guard_t
upgrade_internals_t(connection_settings_handle_t< Traits > settings, stream_socket_t socket, lifetime_monitor_t lifetime_monitor)
bool closed() const noexcept
connection_id_t m_connection_id_counter
bool is_full() const noexcept
connection_t(const connection_t &)=delete
auto create_not_implemented_resp()
write_group_output_ctx_t m_write_output_ctx
Write to socket operation context.
void after_write(const asio_ns::error_code &ec) noexcept
Handle write response finished.
typename Traits::strand_t strand_t
request_handler_t & m_request_handler
Request handler.
void guard_sendfile_operation(std::chrono::steady_clock::duration timelimit)
Context for handling http connections.
timout_cb_t m_current_timeout_cb
Callback to all if timeout happened.
typename connection_count_limit_types< Traits >::lifetime_monitor_t lifetime_monitor_t
virtual void write_response_parts(request_id_t request_id, response_output_flags_t response_output_flags, write_group_t wg) override
Write parts for specified request.
Write operaton using sendfile.
http_parser_settings create_parser_settings() noexcept
Include parser callbacks.
void guard_write_operation()
Start guard write operation if necessary.