CppServer  1.0.4.0
C++ Server Library
wss_session.cpp
Go to the documentation of this file.
1 
10 #include "server/ws/wss_server.h"
11 
12 namespace CppServer {
13 namespace WS {
14 
15 WSSSession::WSSSession(const std::shared_ptr<WSSServer>& server)
16  : HTTP::HTTPSSession(server)
17 {
18 }
19 
21 {
22  // Disconnect WebSocket
23  if (_ws_handshaked)
24  {
25  _ws_handshaked = false;
27  }
28 
29  // Reset WebSocket upgrade HTTP request and response
30  _request.Clear();
31  _response.Clear();
32 
33  // Clear WebSocket send/receive buffers
35 
36  // Initialize new WebSocket random nonce
37  InitWSNonce();
38 }
39 
40 void WSSSession::onReceived(const void* buffer, size_t size)
41 {
42  // Check for WebSocket handshaked status
43  if (_ws_handshaked)
44  {
45  // Prepare receive frame
46  PrepareReceiveFrame(buffer, size);
47  return;
48  }
49 
50  HTTPSSession::onReceived(buffer, size);
51 }
52 
54 {
55  // Check for WebSocket handshaked status
56  if (_ws_handshaked)
57  return;
58 
59  // Try to perform WebSocket upgrade
60  if (!PerformServerUpgrade(request, response()))
61  {
62  HTTPSSession::onReceivedRequestHeader(request);
63  return;
64  }
65 }
66 
68 {
69  // Check for WebSocket handshaked status
70  if (_ws_handshaked)
71  {
72  // Prepare receive frame from the remaining request body
73  auto body = _request.body();
74  PrepareReceiveFrame(body.data(), body.size());
75  return;
76  }
77 
78  HTTPSSession::onReceivedRequest(request);
79 }
80 
81 void WSSSession::onReceivedRequestError(const HTTP::HTTPRequest& request, const std::string& error)
82 {
83  // Check for WebSocket handshaked status
84  if (_ws_handshaked)
85  {
86  onError(asio::error::fault, "WebSocket error", error);
87  return;
88  }
89 
90  HTTPSSession::onReceivedRequestError(request, error);
91 }
92 
94 {
95  std::string result;
96 
97  if (!_ws_handshaked)
98  return result;
99 
100  std::vector<uint8_t> cache;
101 
102  // Receive WebSocket frame data
103  while (!_ws_final_received)
104  {
105  while (!_ws_frame_received)
106  {
107  size_t required = RequiredReceiveFrameSize();
108  cache.resize(required);
109  size_t received = HTTPSSession::Receive(cache.data(), required);
110  if (received != required)
111  return result;
112  PrepareReceiveFrame(cache.data(), received);
113  }
114  if (!_ws_final_received)
115  PrepareReceiveFrame(nullptr, 0);
116  }
117 
118  // Copy WebSocket frame data
120  PrepareReceiveFrame(nullptr, 0);
121  return result;
122 }
123 
124 std::string WSSSession::ReceiveText(const CppCommon::Timespan& timeout)
125 {
126  std::string result;
127 
128  if (!_ws_handshaked)
129  return result;
130 
131  std::vector<uint8_t> cache;
132 
133  // Receive WebSocket frame data
134  while (!_ws_final_received)
135  {
136  while (!_ws_frame_received)
137  {
138  size_t required = RequiredReceiveFrameSize();
139  cache.resize(required);
140  size_t received = HTTPSSession::Receive(cache.data(), required, timeout);
141  if (received != required)
142  return result;
143  PrepareReceiveFrame(cache.data(), received);
144  }
145  if (!_ws_final_received)
146  PrepareReceiveFrame(nullptr, 0);
147  }
148 
149  // Copy WebSocket frame data
151  PrepareReceiveFrame(nullptr, 0);
152  return result;
153 }
154 
155 std::vector<uint8_t> WSSSession::ReceiveBinary()
156 {
157  std::vector<uint8_t> result;
158 
159  if (!_ws_handshaked)
160  return result;
161 
162  std::vector<uint8_t> cache;
163 
164  // Receive WebSocket frame data
165  while (!_ws_final_received)
166  {
167  while (!_ws_frame_received)
168  {
169  size_t required = RequiredReceiveFrameSize();
170  cache.resize(required);
171  size_t received = HTTPSSession::Receive(cache.data(), required);
172  if (received != required)
173  return result;
174  PrepareReceiveFrame(cache.data(), received);
175  }
176  if (!_ws_final_received)
177  PrepareReceiveFrame(nullptr, 0);
178  }
179 
180  // Copy WebSocket frame data
182  PrepareReceiveFrame(nullptr, 0);
183  return result;
184 }
185 
186 std::vector<uint8_t> WSSSession::ReceiveBinary(const CppCommon::Timespan& timeout)
187 {
188  std::vector<uint8_t> result;
189 
190  if (!_ws_handshaked)
191  return result;
192 
193  std::vector<uint8_t> cache;
194 
195  // Receive WebSocket frame data
196  while (!_ws_final_received)
197  {
198  while (!_ws_frame_received)
199  {
200  size_t required = RequiredReceiveFrameSize();
201  cache.resize(required);
202  size_t received = HTTPSSession::Receive(cache.data(), required, timeout);
203  if (received != required)
204  return result;
205  PrepareReceiveFrame(cache.data(), received);
206  }
207  if (!_ws_final_received)
208  PrepareReceiveFrame(nullptr, 0);
209  }
210 
211  // Copy WebSocket frame data
213  PrepareReceiveFrame(nullptr, 0);
214  return result;
215 }
216 
217 } // namespace WS
218 } // namespace CppServer
virtual void onError(int error, const std::string &category, const std::string &message)
Handle error notification.
Definition: ssl_session.h:238
HTTPRequest & Clear()
Clear the HTTP request cache.
std::string_view body() const noexcept
Get the HTTP request body.
Definition: http_request.h:72
HTTPResponse & Clear()
Clear the HTTP response cache.
HTTPRequest _request
HTTP request.
HTTPResponse & response() noexcept
Get the HTTP response.
Definition: https_session.h:45
HTTPResponse _response
HTTP response.
CppCommon::FileCache & cache() noexcept
Get the static content cache.
Definition: https_session.h:41
void onDisconnected() override
Handle session disconnected notification.
Definition: wss_session.cpp:20
void onReceivedRequest(const HTTP::HTTPRequest &request) override
Handle HTTP request received notification.
Definition: wss_session.cpp:67
void onReceived(const void *buffer, size_t size) override
Handle buffer received notification.
Definition: wss_session.cpp:40
std::vector< uint8_t > ReceiveBinary()
void onReceivedRequestHeader(const HTTP::HTTPRequest &request) override
Handle HTTP request header received notification.
Definition: wss_session.cpp:53
void onReceivedRequestError(const HTTP::HTTPRequest &request, const std::string &error) override
Handle HTTP request error notification.
Definition: wss_session.cpp:81
WSSSession(const std::shared_ptr< WSSServer > &server)
Definition: wss_session.cpp:15
size_t _ws_payload_size
Received frame payload size.
Definition: ws.h:180
bool _ws_frame_received
Received frame flag.
Definition: ws.h:174
void InitWSNonce()
Initialize WebSocket random nonce.
Definition: ws.cpp:21
void PrepareReceiveFrame(const void *buffer, size_t size)
Prepare WebSocket receive frame.
Definition: ws.cpp:273
std::vector< uint8_t > _ws_receive_final_buffer
Receive final buffer.
Definition: ws.h:184
void ClearWSBuffers()
Clear WebSocket send/receive buffers.
Definition: ws.cpp:484
size_t RequiredReceiveFrameSize()
Required WebSocket receive frame size.
Definition: ws.cpp:458
bool _ws_final_received
Received final flag.
Definition: ws.h:176
size_t _ws_header_size
Received frame header size.
Definition: ws.h:178
virtual void onWSDisconnected()
Handle WebSocket client disconnected notification.
Definition: ws.h:132
bool PerformServerUpgrade(const HTTP::HTTPRequest &request, HTTP::HTTPResponse &response)
Perform WebSocket server upgrade.
Definition: ws.cpp:103
bool _ws_handshaked
Handshaked flag.
Definition: ws.h:169
C++ Server project definitions.
Definition: asio.h:56
WebSocket secure server definition.
WebSocket secure session definition.