13 #include <restinio/asio_include.hpp> 15 #include <http_parser.h> 17 #include <fmt/format.h> 19 #include <restinio/all.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> 61 m_awaiting_write_groups.emplace( std::move( wg ) );
67 optional_t< write_group_t > result;
69 if( !m_awaiting_write_groups.empty() )
71 result = std::move( m_awaiting_write_groups.front() );
72 m_awaiting_write_groups.pop();
119 typename WS_Message_Handler >
127 using message_handler_t = WS_Message_Handler;
129 using timer_manager_t =
typename Traits::timer_manager_t;
131 using timer_guard_t =
typename timer_manager_t::timer_guard_t;
132 using logger_t =
typename Traits::logger_t;
133 using strand_t =
typename Traits::strand_t;
134 using stream_socket_t =
typename Traits::stream_socket_t;
140 connection_id_t conn_id,
143 restinio::impl::connection_settings_handle_t< Traits > settings,
144 stream_socket_t socket,
146 message_handler_t msg_handler )
159 "[connection:{}] move socket to [ws_connection:{}]",
166 "[ws_connection:{}] start connection with {}",
192 "[ws_connection:{}] destructor called",
211 "[ws_connection:{}] shutdown",
222 "[ws_connection:{}] shutdown operation error: {}",
241 "[ws_connection:{}] kill",
254 "[ws_connection:{}] kill operation error: {}",
288 "[ws_connection:{}] unable to init read: {}",
300 bool is_close_frame )
override 319 "[ws_connection:{}] cannot write to websocket: " 320 "write operations disabled",
331 "[ws_connection:{}] unable to write data: {}",
347 "[ws_connection:{}] close socket",
415 template<
typename MSG_BUILDER >
418 status_code_t status,
419 MSG_BUILDER msg_builder )
433 "[ws_connection:{}] start reading header",
458 "[ws_connection:{}] continue reading message",
479 "[ws_connection:{}] after read header callback error: {}",
496 "[ws_connection:{}] {}: {}",
506 const asio_ns::error_code & ec,
513 "[ws_connection:{}] received {} bytes",
552 "[ws_connection:{}] start handling {} ({:#x})",
565 "[ws_connection:{}] invalid header",
650 std::size_t length_remaining,
652 bool do_validate_payload_and_call_msg_handler =
true )
681 "[ws_connection:{}] after read payload callback error: {}",
693 std::size_t length_remaining,
694 const asio_ns::error_code & ec,
696 bool do_validate_payload_and_call_msg_handler =
true )
702 "[ws_connection:{}] received {} bytes",
773 "[ws_connection:{}] execute handler error: {}",
786 std::size_t next_length_remaining )
830 "[ws_connection:{}] invalid paload",
891 "[ws_connection:{}] got close frame from peer, status: {}",
928 "[ws_connection:{}] expected close frame came",
968 "[ws_connection:{}] user sends close frame",
990 "[ws_connection:{}] try to write while socket is closed",
1028 "[ws_connection:{}] start next write group, " 1066 throw exception_t{
"sendfile write operation not implemented" };
1075 "[ws_connection:{}] handle_current_write_ctx failed: {}",
1090 "[ws_connection:{}] sending data with " 1114 "[ws_connection:{}] outgoing data was sent: {} bytes",
1128 "[ws_connection:{}] after write callback error: {}",
1143 "[ws_connection:{}] finishing current write group",
1169 "[ws_connection:{}] unable to write: {}",
1182 "[ws_connection:{}] notificator error: {}",
1228 "[wd_connection:{}] write operation timed out",
1239 "[wd_connection:{}] waiting for close-frame from peer timed out",
1325 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 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()
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.
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.
void close_impl()
Standard close routine.
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)
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).
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.
~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.
void run_if_first(Action &&action)
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
optional_t< write_group_t > pop_ready_buffers()
void trigger_error_and_close(status_code_t status, MSG_BUILDER msg_builder)
Trigger an error.
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.
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...
A helper class for running exclusive action. Only a first action will run.