RESTinio
message.hpp
Go to the documentation of this file.
1 /*
2  restinio
3 */
4 
5 /*!
6  WebSocket messgage handler definition.
7 */
8 
9 #pragma once
10 
11 #include <functional>
12 
13 #include <restinio/utils/impl/bitops.hpp>
14 
15 namespace restinio
16 {
17 
18 namespace websocket
19 {
20 
21 namespace basic
22 {
23 
24 #define RESTINIO_WEBSOCKET_OPCODES_MAP( RESTINIO_GEN )
25  RESTINIO_GEN( continuation_frame, 0x00 )
26  RESTINIO_GEN( text_frame, 0x01 )
27  RESTINIO_GEN( binary_frame, 0x02 )
28  RESTINIO_GEN( connection_close_frame, 0x08 )
29  RESTINIO_GEN( ping_frame, 0x09 )
30  RESTINIO_GEN( pong_frame, 0x0A )
31 
32 //
33 // opcode_t
34 //
35 
36 enum class opcode_t : std::uint8_t
37 {
38 #define RESTINIO_WEBSOCKET_OPCODES_GEN( name, code ) name = code,
40 #undef RESTINIO_WEBSOCKET_OPCODES_GEN
41  unknown_frame = 0x0F
42 };
43 
44 //! Helper sunction to get method string name.
45 inline const char *
47 {
48  const char * result = "unknown_frame";
49  switch( opcode )
50  {
51  #define RESTINIO_WEBSOCKET_OPCODES_GEN( name, code )
52  case opcode_t::name: result = #name; break;
53 
54  RESTINIO_WEBSOCKET_OPCODES_MAP( RESTINIO_WEBSOCKET_OPCODES_GEN )
55  #undef RESTINIO_WEBSOCKET_OPCODES_GEN
56 
57  default:; // Ignore.
58  };
59 
60  return result;
61 }
62 
63 inline bool
65 {
66  bool result = true;
67  switch( opcode )
68  {
69  #define RESTINIO_WEBSOCKET_OPCODES_GEN( name, code )
70  case opcode_t::name: break;
71 
72  RESTINIO_WEBSOCKET_OPCODES_MAP( RESTINIO_WEBSOCKET_OPCODES_GEN )
73  #undef RESTINIO_WEBSOCKET_OPCODES_GEN
74 
75  default: result = false; // Ignore.
76  };
77 
78  return result;
79 }
80 
81 //
82 // status_code_t
83 //
84 
85 enum class status_code_t : std::uint16_t
86 {
87  normal_closure = 1000,
88  going_away = 1001,
89  protocol_error = 1002,
90  cant_accept_data = 1003,
91  no_status_provided = 1005,
92  connection_lost = 1006,
93  invalid_message_data = 1007,
94  policy_violation = 1008,
95  too_big_message = 1009,
98 };
99 
100 inline std::string
102 {
103  using namespace ::restinio::utils::impl::bitops;
104 
105  return {
106  n_bits_from<char, 8>( static_cast<std::uint16_t>(code) ),
107  n_bits_from<char, 0>( static_cast<std::uint16_t>(code) )
108  };
109 }
110 
111 inline status_code_t
112 status_code_from_bin( string_view_t data )
113 {
114  using namespace ::restinio::utils::impl::bitops;
115 
116  std::uint16_t result{ 0 };
117  if( 2 <= data.size() )
118  {
119  result |= static_cast< std::uint8_t >( data[ 0 ] );
120  result <<= 8;
121  result |= static_cast< std::uint8_t >( data[ 1 ] );
122  }
123 
124  // TODO: make it ok.
125  return static_cast<status_code_t>(result);
126 }
127 
128 //
129 // final_frame_flag_t
130 //
131 
132 //! WS frame (message) "final"/"not final" flag.
134 
137 
138 //
139 // message_t
140 //
141 
142 //! WebSocket message.
143 class message_t final
144  : public std::enable_shared_from_this< message_t >
145 {
146  public:
147 
148  message_t() = default;
149 
151  final_frame_flag_t final_flag,
152  opcode_t opcode )
153  : m_final_flag{ final_flag }
154  , m_opcode{ opcode }
155  {}
156 
158  final_frame_flag_t final_flag,
159  opcode_t opcode,
160  std::string payload )
161  : m_final_flag{ final_flag }
162  , m_opcode{ opcode }
163  , m_payload{ std::move( payload ) }
164  {}
165 
166  //! Get final flag.
168  final_flag() const noexcept
169  {
170  return m_final_flag;
171  }
172 
173  void
174  set_final_flag( final_frame_flag_t final_flag ) noexcept
175  {
176  m_final_flag = final_flag;
177  }
178 
179  bool
180  is_final() const noexcept
181  {
182  return final_frame == final_flag();
183  }
184 
185  opcode_t
186  opcode() const noexcept
187  {
188  return m_opcode;
189  }
190 
191  void
192  set_opcode( opcode_t opcode ) noexcept
193  {
194  m_opcode = opcode;
195  }
196 
197  const std::string&
198  payload() const noexcept
199  {
200  return m_payload;
201  }
202 
203  std::string&
204  payload() noexcept
205  {
206  return m_payload;
207  }
208 
209  void
210  set_payload( std::string str )
211  {
212  m_payload = std::move( str );
213  }
214 
215  private:
216  //! Final flag.
218 
219  //! Opcode.
221 
222  //! Websocket message payload.
224 };
225 
226 //! Request handler, that is the type for calling request handlers.
228 
229 //
230 // default_request_handler_t
231 //
232 
235 
236 } /* namespace basic */
237 
238 } /* namespace websocket */
239 
240 } /* namespace restinio */
constexpr final_frame_flag_t final_frame
Definition: message.hpp:135
#define RESTINIO_WEBSOCKET_OPCODES_MAP(RESTINIO_GEN)
Definition: message.hpp:24
std::string & payload() noexcept
Definition: message.hpp:204
status_code_t status_code_from_bin(string_view_t data)
Definition: message.hpp:112
final_frame_flag_t final_flag() const noexcept
Get final flag.
Definition: message.hpp:168
void set_payload(std::string str)
Definition: message.hpp:210
message_t(final_frame_flag_t final_flag, opcode_t opcode, std::string payload)
Definition: message.hpp:157
message_t(final_frame_flag_t final_flag, opcode_t opcode)
Definition: message.hpp:150
final_frame_flag_t
WS frame (message) "final"/"not final" flag.
Definition: message.hpp:133
bool is_final() const noexcept
Definition: message.hpp:180
std::string status_code_to_bin(status_code_t code)
Definition: message.hpp:101
const char * opcode_to_string(opcode_t opcode)
Helper sunction to get method string name.
Definition: message.hpp:46
std::string m_payload
Websocket message payload.
Definition: message.hpp:223
final_frame_flag_t m_final_flag
Final flag.
Definition: message.hpp:217
const std::string & payload() const noexcept
Definition: message.hpp:198
constexpr final_frame_flag_t not_final_frame
Definition: message.hpp:136
bool is_valid_opcode(opcode_t opcode)
Definition: message.hpp:64
void set_opcode(opcode_t opcode) noexcept
Definition: message.hpp:192
void set_final_flag(final_frame_flag_t final_flag) noexcept
Definition: message.hpp:174
opcode_t opcode() const noexcept
Definition: message.hpp:186
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 &params, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...
Definition: value_or.hpp:64