13 #include <restinio/asio_include.hpp> 17 #include <restinio/impl/include_fmtlib.hpp> 19 #include <restinio/core.hpp> 20 #include <restinio/impl/executor_wrapper.hpp> 21 #include <restinio/impl/write_group_output_ctx.hpp> 22 #include <restinio/websocket/message.hpp> 23 #include <restinio/websocket/impl/ws_parser.hpp> 24 #include <restinio/websocket/impl/ws_protocol_validator.hpp> 26 #include <restinio/utils/impl/safe_uint_truncate.hpp> 28 #include <restinio/compiler_features.hpp> 63 m_awaiting_write_groups.emplace( std::move( wg ) );
69 std::optional< write_group_t > result;
71 if( !m_awaiting_write_groups.empty() )
73 result = std::move( m_awaiting_write_groups.front() );
74 m_awaiting_write_groups.pop();
121 typename WS_Message_Handler >
129 using message_handler_t = WS_Message_Handler;
131 using timer_manager_t =
typename Traits::timer_manager_t;
133 using timer_guard_t =
typename timer_manager_t::timer_guard_t;
134 using logger_t =
typename Traits::logger_t;
135 using strand_t =
typename Traits::strand_t;
136 using stream_socket_t =
typename Traits::stream_socket_t;
144 connection_id_t conn_id,
147 restinio::impl::connection_settings_handle_t< Traits > settings,
148 stream_socket_t socket,
149 lifetime_monitor_t lifetime_monitor,
151 message_handler_t msg_handler )
166 "[connection:{}] move socket to [ws_connection:{}]" ),
174 "[ws_connection:{}] start connection with {}" ),
202 "[ws_connection:{}] destructor called" ),
227 "[ws_connection:{}] shutdown" ),
240 "[ws_connection:{}] shutdown operation error: {}" ),
266 "[ws_connection:{}] kill" ),
281 "[ws_connection:{}] kill operation error: {}" ),
319 "[ws_connection:{}] unable to init read: {}" ),
331 bool is_close_frame )
override 354 "[ws_connection:{}] cannot write to websocket: " 355 "write operations disabled" ),
367 "[ws_connection:{}] unable to write data: {}" ),
389 "[ws_connection:{}] close socket" ),
397 "ws_connection.close_impl.socket.shutdown",
407 "ws_connection.close_impl.socket.close",
473 template<
typename MSG_BUILDER >
476 status_code_t status,
477 MSG_BUILDER msg_builder )
noexcept 485 m_logger,
"ws_connection.call_close_handler_if_necessary",
501 "[ws_connection:{}] start reading header" ),
527 "[ws_connection:{}] continue reading message" ),
550 "[ws_connection:{}] after read header " 551 "callback error: {}" ),
578 const asio_ns::error_code & ec,
586 "[ws_connection:{}] received {} bytes" ),
626 "[ws_connection:{}] start handling {} ({:#x})" ),
640 "[ws_connection:{}] invalid header" ),
725 std::size_t length_remaining,
727 bool do_validate_payload_and_call_msg_handler =
true )
757 "[ws_connection:{}] after read payload " 758 "callback error: {}" ),
770 std::size_t length_remaining,
771 const asio_ns::error_code & ec,
773 bool do_validate_payload_and_call_msg_handler =
true )
780 "[ws_connection:{}] received {} bytes" ),
852 "[ws_connection:{}] execute handler error: {}" ),
865 std::size_t next_length_remaining )
910 "[ws_connection:{}] invalid paload" ),
972 "[ws_connection:{}] got close frame from " 973 "peer, status: {}" ),
1011 "[ws_connection:{}] expected close frame came" ),
1052 "[ws_connection:{}] user sends close frame" ),
1075 "[ws_connection:{}] try to write while " 1076 "socket is closed" ),
1115 "[ws_connection:{}] start next write group, " 1153 throw exception_t{
"sendfile write operation not implemented" };
1163 "[ws_connection:{}] handle_current_write_ctx failed: {}" ),
1179 "[ws_connection:{}] sending data with " 1206 "[ws_connection:{}] outgoing data was " 1222 "[ws_connection:{}] after write " 1223 "callback error: {}" ),
1239 "[ws_connection:{}] finishing current write group" ),
1266 "[ws_connection:{}] unable to write: {}" ),
1280 "[ws_connection:{}] notificator error: {}" ),
1332 "[connection: {}] unexpected " 1333 "error during timeout handling: {}" ),
1356 "[wd_connection:{}] write operation timed out" ),
1368 "[wd_connection:{}] waiting for close-frame " 1369 "from peer timed out" ),
1455 template <
typename Action >
read_state_t m_read_state
A state of a websocket input.
void consume_header_from_buffer(const char *data, std::size_t length)
Parse header from internal buffer.
Context for handling websocket connections.
std::chrono::steady_clock::time_point m_close_frame_from_peer_timeout_after
ws_weak_handle_t m_websocket_weak_handle
A waek handler for owning ws_t to use it when call message handler.
connection_input_t m_input
Input routine.
void close_impl() noexcept
Standard close routine.
void after_read_payload(char *payload_data, std::size_t length_remaining, const asio_ns::error_code &ec, std::size_t length, bool do_validate_payload_and_call_msg_handler=true)
Handle read operation result, when reading payload.
write_state_t
Websocket output states.
void guard_close_frame_from_peer_operation()
void run_if_first(Action &&action) noexcept(noexcept(action()))
virtual void kill() override
Kill websocket.
void handle_trivial_write_operation(const trivial_write_operation_t &op)
timer_guard_t m_timer_guard
void consume_header_from_socket()
Initiate read operation on socket to receive bytes for header.
void handle_invalid_payload(validation_state_t validation_result)
Handle payload errors.
write_groups_queue_t m_awaiting_write_groups
A queue of buffers.
std::optional< write_group_t > pop_ready_buffers()
ws_connection_t & operator=(const ws_connection_t &)=delete
constexpr size_t websocket_header_max_size()
Max possible size of websocket frame header (a part before payload).
void write_data_impl(write_group_t wg, bool is_close_frame)
Implementation of writing data performed on the asio_ns::io_context.
ws_connection_t(ws_connection_t &&)=delete
void send_close_frame_to_peer(std::string payload)
Send close frame to peer.
restinio::impl::write_group_output_ctx_t m_write_output_ctx
Write to socket operation context.
message_handler_t m_msg_handler
Websocket message handler provided by user.
Do not read anything (before activation).
ws_outgoing_data_t m_outgoing_data
Output buffers queue.
A queue for outgoing buffers.
void handle_current_write_ctx()
ws_connection_t(const ws_connection_t &)=delete
void handle_read_error(const char *desc, const asio_ns::error_code &ec)
Handle read error (reading header or payload)
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, std::optional< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in std::optional<Value_Type> if parameter exis...
read_state_t
Websocket input states.
void append(write_group_t wg)
Add buffers to queue.
one_shot_action_t m_close_frame_to_user
bool validate_payload_part(char *payload_data, std::size_t length, std::size_t next_length_remaining)
Validates a part of received payload.
void disable()
Disable ation: action will not be executed even on a first shot.
No more outgoing data can be added (e.g. close-frame was sent).
lifetime_monitor_t m_lifetime_monitor
Monitor of the connection lifetime.
one_shot_action_t m_close_impl
void init_read(ws_handle_t wsh) override
Start reading ws-messages.
static ws_connection_t & cast_to_self(tcp_connection_ctx_base_t &base)
Timers.
Reads only close frame: skip all frames until close-frame.
void trigger_error_and_close(status_code_t status, MSG_BUILDER msg_builder) noexcept
Trigger an error.
~ws_connection_t() override
ws_protocol_validator_t m_protocol_validator
Helper for validating protocol.
void call_close_handler_if_necessary(status_code_t status)
virtual void check_timeout(tcp_connection_ctx_handle_t &self) override
void start_waiting_close_frame_only()
Start waiting for close-frame.
void start_read_header()
Start the process of reading ws messages from socket.
restinio::impl::connection_settings_handle_t< Traits > m_settings
Common paramaters of a connection.
logger_t & m_logger
Logger for operation.
void finish_handling_current_write_ctx()
Do post write actions for current write group.
void handle_parsed_header(const message_details_t &md)
Handle parsed header.
void start_read_payload(char *payload_data, std::size_t length_remaining, bool do_validate_payload_and_call_msg_handler=true)
Start reading message payload.
tcp_connection_ctx_weak_handle_t m_prepared_weak_ctx
void call_handler_on_current_message()
void init_write()
Initiate write operation.
void init_write_if_necessary()
Checks if there is something to write, and if so starts write operation.
ws_connection_t & operator=(ws_connection_t &&)=delete
void init_next_timeout_checking()
schedule next timeout checking.
virtual void shutdown() override
Shutdown websocket.
stream_socket_t m_socket
Connection.
void send_close_frame_to_peer(status_code_t code, std::string desc=std::string{})
Send close frame to peer.
void after_read_header(const asio_ns::error_code &ec, std::size_t length)
Handle read operation result, when reading header.
write_state_t m_write_state
A state of a websocket output.
virtual void write_data(write_group_t wg, bool is_close_frame) override
Write pieces of outgoing data.
void after_write(const asio_ns::error_code &ec)
Handle write response finished.
Able to append outgoing data.
void check_timeout_impl()
void guard_write_operation()
Start guard write operation if necessary.
void graceful_close()
Close WebSocket connection in a graceful manner.
void call_message_handler(message_handle_t close_frame)
Call user message handler with current message.
one_shot_action_t m_close_frame_to_peer
std::chrono::steady_clock::time_point m_write_operation_timeout_after
void handle_parsed_and_valid_header(const message_details_t &md)
Handle parsed and valid header.
Reads any type of frame and serve it to user.
A helper class for running exclusive action. Only a first action will run.