websocket_message.cpp
Go to the documentation of this file.
2 
3 namespace async_web_server_cpp
4 {
5 
7 {
8  switch (message.type)
9  {
11  header.opcode = WebsocketFrame::Header::opcode_text;
12  break;
14  header.opcode = WebsocketFrame::Header::opcode_binary;
15  break;
17  header.opcode = WebsocketFrame::Header::opcode_close;
18  break;
20  header.opcode = WebsocketFrame::Header::opcode_ping;
21  break;
23  header.opcode = WebsocketFrame::Header::opcode_pong;
24  break;
25  default:
26  return false;
27  }
28  header.fin = true;
29  header.rsv1 = false;
30  header.rsv2 = false;
31  header.rsv3 = false;
32  content = message.content;
33  length = message.content.size();
34  return true;
35 }
36 
37 bool WebsocketFrame::serialize(std::vector<unsigned char>& buffer)
38 {
39  int header_size = 2; // first two bytes of header
40  if (length < 126)
41  {
42  header.len = length;
43  }
44  else if (length <= std::numeric_limits<uint16_t>::max())
45  {
46  header.len = 126;
47  header_size += 2;
48  }
49  else if (length <= std::numeric_limits<uint64_t>::max())
50  {
51  header.len = 127;
52  header_size += 8;
53  }
54  else
55  return false; // Message too big
56  header.mask = false; // sending from server
57 
58  buffer.resize(header_size + content.size());
59  buffer[0] = header_bytes[0];
60  buffer[1] = header_bytes[1];
61 
62  if (length < 126)
63  {
64  // already copied in header bytes
65  }
66  else if (length <= std::numeric_limits<uint16_t>::max())
67  {
68  buffer[2] = (length >> 8) & 0xFF;
69  buffer[3] = (length >> 0) & 0xFF;
70  }
71  else if (length <= std::numeric_limits<uint64_t>::max())
72  {
73  buffer[2] = (length >> 56) & 0xFF;
74  buffer[3] = (length >> 48) & 0xFF;
75  buffer[4] = (length >> 40) & 0xFF;
76  buffer[5] = (length >> 32) & 0xFF;
77  buffer[6] = (length >> 24) & 0xFF;
78  buffer[7] = (length >> 16) & 0xFF;
79  buffer[8] = (length >> 8) & 0xFF;
80  buffer[9] = (length >> 0) & 0xFF;
81  }
82  content.copy((char*)&buffer[header_size], content.size());
83  return true;
84 }
85 
87 {
88  reset();
89 }
90 
92 {
94 }
95 
96 boost::tribool WebsocketFrameParser::consume(WebsocketFrame& frame, char input)
97 {
98  switch (state_)
99  {
100  case header_byte1:
101  frame.header_bytes[0] = input;
103  return boost::indeterminate;
104  case header_byte2:
105  frame.header_bytes[1] = input;
106  if (frame.header.len < 126)
107  {
108  frame.length = frame.header.len;
109  frame.content.reserve(frame.length);
110  frame.content.resize(0);
111  if (frame.header.mask)
112  state_ = mask_byte1;
113  else if (frame.length > 0)
114  state_ = body;
115  else
116  return true;
117  }
118  else if (frame.header.len == 126)
119  {
120  frame.length = 0;
122  }
123  else
124  {
125  frame.length = 0;
127  }
128  return boost::indeterminate;
129 
130  case length_8bytes_left:
131  frame.length |= ((uint64_t)(input & 0xFF) << 56);
133  return boost::indeterminate;
134  case length_7bytes_left:
135  frame.length |= ((uint64_t)(input & 0xFF) << 48);
137  return boost::indeterminate;
138  case length_6bytes_left:
139  frame.length |= ((uint64_t)(input & 0xFF) << 40);
141  return boost::indeterminate;
142  case length_5bytes_left:
143  frame.length |= ((uint64_t)(input & 0xFF) << 32);
145  return boost::indeterminate;
146  case length_4bytes_left:
147  frame.length |= ((uint64_t)(input & 0xFF) << 24);
149  return boost::indeterminate;
150  case length_3bytes_left:
151  frame.length |= ((uint64_t)(input & 0xFF) << 16);
153  return boost::indeterminate;
154  case length_2bytes_left:
155  frame.length |= ((uint64_t)(input & 0xFF) << 8);
157  return boost::indeterminate;
158  case length_1bytes_left:
159  frame.length |= ((uint64_t)(input & 0xFF) << 0);
160  frame.content.reserve(frame.length);
161  frame.content.resize(0);
162  if (frame.header.mask)
163  state_ = mask_byte1;
164  else
165  state_ = body;
166  return boost::indeterminate;
167 
168  case mask_byte1:
169  frame.mask[0] = input;
170  state_ = mask_byte2;
171  return boost::indeterminate;
172  case mask_byte2:
173  frame.mask[1] = input;
174  state_ = mask_byte3;
175  return boost::indeterminate;
176  case mask_byte3:
177  frame.mask[2] = input;
178  state_ = mask_byte4;
179  return boost::indeterminate;
180  case mask_byte4:
181  frame.mask[3] = input;
182  if (frame.length > 0)
183  state_ = body;
184  else
185  return true;
186  return boost::indeterminate;
187 
188  case body:
189  frame.content += input;
190  if (frame.content.size() < frame.length)
191  return boost::indeterminate;
192  // unmask the frame
193  if (frame.header.mask)
194  {
195  for (uint64_t i = 0; i < frame.length; ++i)
196  {
197  frame.content[i] = frame.content[i] ^ frame.mask[i % 4];
198  }
199  }
200  return true;
201  default:
202  return false;
203  }
204 }
205 
207 
209  WebsocketFrame& frame)
210 {
211  if (frame.header.opcode == WebsocketFrame::Header::opcode_continuation)
212  {
213  if (message.type == WebsocketMessage::type_unknown)
214  return false;
215  else
216  message.content.append(frame.content);
217  }
218  else
219  {
220  switch (frame.header.opcode)
221  {
222  case WebsocketFrame::Header::opcode_text:
224  break;
225  case WebsocketFrame::Header::opcode_binary:
227  break;
228  case WebsocketFrame::Header::opcode_close:
230  break;
231  case WebsocketFrame::Header::opcode_ping:
233  break;
234  case WebsocketFrame::Header::opcode_pong:
236  break;
237  default:
239  return false;
240  }
241  message.content = frame.content;
242  }
243  if (frame.header.fin)
244  return true;
245  else
246  return boost::indeterminate;
247 }
248 
249 } // namespace async_web_server_cpp
async_web_server_cpp::WebsocketFrame::fromMessage
bool fromMessage(const WebsocketMessage &message)
Definition: websocket_message.cpp:6
async_web_server_cpp::WebsocketFrame::serialize
bool serialize(std::vector< unsigned char > &buffer)
Definition: websocket_message.cpp:37
async_web_server_cpp::WebsocketFrameParser::reset
void reset()
Definition: websocket_message.cpp:91
async_web_server_cpp::WebsocketMessage::type_binary
@ type_binary
Definition: websocket_message.hpp:117
async_web_server_cpp::WebsocketFrame::header_bytes
char header_bytes[2]
Definition: websocket_message.hpp:54
async_web_server_cpp::WebsocketFrameParser::mask_byte4
@ mask_byte4
Definition: websocket_message.hpp:100
async_web_server_cpp::WebsocketFrameParser::state_
enum async_web_server_cpp::WebsocketFrameParser::state state_
async_web_server_cpp::WebsocketFrameParser::length_7bytes_left
@ length_7bytes_left
Definition: websocket_message.hpp:90
async_web_server_cpp::WebsocketMessage::type_ping
@ type_ping
Definition: websocket_message.hpp:119
async_web_server_cpp::WebsocketFrame
Definition: websocket_message.hpp:27
async_web_server_cpp::WebsocketFrameParser::body
@ body
Definition: websocket_message.hpp:101
async_web_server_cpp::WebsocketFrame::length
uint64_t length
Definition: websocket_message.hpp:56
async_web_server_cpp::WebsocketMessage::WebsocketMessage
WebsocketMessage()
Definition: websocket_message.cpp:206
async_web_server_cpp::WebsocketFrameParser::length_5bytes_left
@ length_5bytes_left
Definition: websocket_message.hpp:92
async_web_server_cpp
Definition: http_connection.hpp:14
async_web_server_cpp::WebsocketMessage::type
type
Definition: websocket_message.hpp:113
async_web_server_cpp::WebsocketFrame::content
std::string content
Definition: websocket_message.hpp:58
async_web_server_cpp::WebsocketFrameParser::length_6bytes_left
@ length_6bytes_left
Definition: websocket_message.hpp:91
async_web_server_cpp::WebsocketMessage::type_pong
@ type_pong
Definition: websocket_message.hpp:120
async_web_server_cpp::WebsocketFrameParser::length_4bytes_left
@ length_4bytes_left
Definition: websocket_message.hpp:93
async_web_server_cpp::WebsocketMessage::type_close
@ type_close
Definition: websocket_message.hpp:118
async_web_server_cpp::WebsocketFrame::header
Header header
Definition: websocket_message.hpp:53
websocket_message.hpp
async_web_server_cpp::WebsocketFrameParser::consume
boost::tribool consume(WebsocketFrame &frame, char input)
Definition: websocket_message.cpp:96
async_web_server_cpp::WebsocketFrameParser::length_3bytes_left
@ length_3bytes_left
Definition: websocket_message.hpp:94
async_web_server_cpp::WebsocketMessage::type_unknown
@ type_unknown
Definition: websocket_message.hpp:115
async_web_server_cpp::WebsocketFrameParser::header_byte1
@ header_byte1
Definition: websocket_message.hpp:87
async_web_server_cpp::WebsocketFrameParser::header_byte2
@ header_byte2
Definition: websocket_message.hpp:88
async_web_server_cpp::WebsocketFrameParser::length_2bytes_left
@ length_2bytes_left
Definition: websocket_message.hpp:95
async_web_server_cpp::WebsocketMessage
Definition: websocket_message.hpp:109
async_web_server_cpp::WebsocketFrameParser::mask_byte1
@ mask_byte1
Definition: websocket_message.hpp:97
async_web_server_cpp::WebsocketFrameParser::mask_byte2
@ mask_byte2
Definition: websocket_message.hpp:98
async_web_server_cpp::WebsocketFrameBuffer::consume
boost::tribool consume(WebsocketMessage &message, WebsocketFrame &frame)
Definition: websocket_message.cpp:208
async_web_server_cpp::WebsocketFrameParser::mask_byte3
@ mask_byte3
Definition: websocket_message.hpp:99
async_web_server_cpp::WebsocketMessage::content
std::string content
Definition: websocket_message.hpp:122
async_web_server_cpp::WebsocketFrameParser::length_1bytes_left
@ length_1bytes_left
Definition: websocket_message.hpp:96
async_web_server_cpp::WebsocketMessage::type_text
@ type_text
Definition: websocket_message.hpp:116
async_web_server_cpp::WebsocketFrameParser::WebsocketFrameParser
WebsocketFrameParser()
Definition: websocket_message.cpp:86
async_web_server_cpp::WebsocketFrame::mask
unsigned char mask[4]
Definition: websocket_message.hpp:57
async_web_server_cpp::WebsocketFrameParser::length_8bytes_left
@ length_8bytes_left
Definition: websocket_message.hpp:89


async_web_server_cpp
Author(s): Mitchell Wills , Russel Toris
autogenerated on Tue Mar 1 2022 23:49:06