2
3
6
7
13#include <restinio/websocket/message.hpp>
14#include <restinio/websocket/impl/ws_connection_base.hpp>
15#include <restinio/websocket/impl/ws_connection.hpp>
16#include <restinio/utils/base64.hpp>
17#include <restinio/utils/sha1.hpp>
34
35
36
37
49 ws.m_ws_connection_handle->init_read( ws.shared_from_this() );
76
77
78
82 return m_ws_connection_handle ? m_ws_connection_handle->connection_id() : 0;
90 if( m_ws_connection_handle )
92 auto con = std::move( m_ws_connection_handle );
102 if( m_ws_connection_handle )
104 auto con = std::move( m_ws_connection_handle );
117 if( m_ws_connection_handle )
122 writable_items_container_t bufs;
127 final_flag, opcode, asio_ns::buffer_size( payload
.buf() ) };
132 bufs.emplace_back( std::move( payload ) );
142 const bool is_close_frame =
143 opcode_t::connection_close_frame == opcode;
147 auto con = std::move( m_ws_connection_handle );
154 m_ws_connection_handle->write_data(
213 typename WS_Message_Handler >
217 generic_request_type_from_traits_t<Traits> & req,
223 WS_Message_Handler ws_message_handler )
233 "{} field is mandatory for upgrade response" ),
239 upgrade_response_header_fields.set_field(
http_field::upgrade,
"websocket" );
243 auto conn_ptr = std::move(
restinio::
impl::access_req_connection( req ) );
246 throw exception_t{ "no connection for upgrade: already moved" };
248 auto & con =
dynamic_cast< connection_t & >( *conn_ptr );
252 auto upgrade_internals = con.move_upgrade_internals();
254 std::make_shared< ws_connection_t >(
256 std::move( upgrade_internals.m_settings ),
257 std::move( upgrade_internals.m_socket ),
258 std::move( upgrade_internals.m_lifetime_monitor ),
259 std::move( ws_message_handler ) );
261 writable_items_container_t upgrade_response_bufs;
264 upgrade_response_header
.swap_fields( upgrade_response_header_fields );
267 const auto content_length_flag =
270 upgrade_response_bufs.emplace_back(
272 upgrade_response_header,
273 content_length_flag ) );
276 ws_connection->write_data(
281 std::make_shared<
ws_t >( std::move( ws_connection ), req.remote_endpoint() );
294 typename WS_Message_Handler >
297 generic_request_type_from_traits_t<Traits> & req,
299 std::string sec_websocket_accept_field_value,
300 WS_Message_Handler ws_message_handler )
303 upgrade_response_header_fields.set_field(
305 std::move( sec_websocket_accept_field_value ) );
308 upgrade< Traits, WS_Message_Handler >(
311 std::move( upgrade_response_header_fields ),
312 std::move( ws_message_handler ) );
317 typename WS_Message_Handler >
320 generic_request_type_from_traits_t<Traits> & req,
322 std::string sec_websocket_accept_field_value,
323 std::string sec_websocket_protocol_field_value,
324 WS_Message_Handler ws_message_handler )
327 upgrade_response_header_fields.set_field(
329 std::move( sec_websocket_accept_field_value ) );
331 upgrade_response_header_fields.set_field(
333 std::move( sec_websocket_protocol_field_value ) );
336 upgrade< Traits, WS_Message_Handler >(
339 std::move( upgrade_response_header_fields ),
340 std::move( ws_message_handler ) );
345 typename WS_Message_Handler >
348 generic_request_type_from_traits_t<Traits> & req,
350 WS_Message_Handler ws_message_handler )
352 const char * websocket_accept_field_suffix =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
355 websocket_accept_field_suffix;
359 std::string sec_websocket_accept_field_value = utils::base64::encode(
363 upgrade_response_header_fields.set_field(
365 std::move( sec_websocket_accept_field_value ) );
368 upgrade< Traits, WS_Message_Handler >(
371 std::move( upgrade_response_header_fields ),
372 std::move( ws_message_handler ) );
Exception class for all exceptions thrown by RESTinio.
exception_t(const char *err)
request_handler_type_from_traits_t< Traits > request_handler_t
Websocket message class with more detailed protocol information.
std::weak_ptr< ws_t > ws_weak_handle_t
final_frame_flag_t final_flag() const noexcept
Get final flag.
opcode_t opcode() const noexcept
ws_t & operator=(ws_t &&)=delete
void send_message(message_t msg, write_status_cb_t wscb=write_status_cb_t{})
ws_t(impl::ws_connection_handle_t ws_connection_handle, endpoint_t remote_endpoint)
ws_t & operator=(const ws_t &)=delete
ws_t(const ws_t &)=delete
impl::ws_connection_handle_t m_ws_connection_handle
connection_id_t connection_id() const
Get connection id.
void shutdown()
Shutdown websocket: wait for all outgoing data to be sent, and close connection.
void kill()
Kill websocket: close underlying tcp socket. Do not tolerate unsent outgoing data.
friend void activate(ws_t &ws)
Activate websocket: start receiving messages.
const endpoint_t & remote_endpoint() const noexcept
Get the remote endpoint of the underlying connection.
const endpoint_t m_remote_endpoint
Remote endpoint for this ws-connection.
void send_message(final_frame_flag_t final_flag, opcode_t opcode, writable_item_t payload, write_status_cb_t wscb=write_status_cb_t{})
Send_websocket message.
Class for storing the buffers used for streaming body (request/response).
asio_ns::const_buffer buf() const
Create a buf reference object used by ASIO.
writable_item_type_t write_type() const noexcept
Get a type of a stored buffer object.
Group of writable items transported to the context of underlying connection as one solid piece.
void after_write_notificator(write_status_cb_t notificator) noexcept
Set after write notificator.
#define RESTINIO_FMT_FORMAT_STRING(s)
content_length_field_presence_t
std::string to_string(const digest_t &what)
raw_data_t write_message_details(const message_details_t &message)
Serialize websocket message details into bytes buffer.
std::shared_ptr< ws_connection_base_t > ws_connection_handle_t
Alias for WebSocket connection handle.
auto upgrade(generic_request_type_from_traits_t< Traits > &req, activation_t activation_flag, std::string sec_websocket_accept_field_value, WS_Message_Handler ws_message_handler)
auto upgrade(generic_request_type_from_traits_t< Traits > &req, activation_t activation_flag, WS_Message_Handler ws_message_handler)
activation_t
Flags for websocket activation policies.
@ immediate
Activate immediately after upgrade operation.
@ delayed
User will initiate activation later.
ws_handle_t upgrade(generic_request_type_from_traits_t< Traits > &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.
std::shared_ptr< ws_t > ws_handle_t
Alias for ws_t handle.
final_frame_flag_t
WS frame (message) "final"/"not final" flag.
auto upgrade(generic_request_type_from_traits_t< Traits > &req, activation_t activation_flag, std::string sec_websocket_accept_field_value, std::string sec_websocket_protocol_field_value, WS_Message_Handler ws_message_handler)
asio_ns::ip::tcp::endpoint endpoint_t
An alias for endpoint type from Asio.
http_field_t http_field
Helper alies to omitt _t suffix.
http_connection_header_t
Values for conection header field.
std::function< void(const asio_ns::error_code &ec) > write_status_cb_t
An alias for a callback to be invoked after the write operation of a particular group of "buffers".
writable_item_type_t
Buffers write operation type.
@ trivial_write_operation
Item is a buffer and must be written trivially.
const char * field_to_string(http_field_t f) noexcept
Helper sunction to get method string name.
http_status_line_t status_switching_protocols()
std::uint64_t connection_id_t
Type for ID of connection.