Skip to content

Commit 07fac31

Browse files
committed
WSClient don't support continuation frames(opcode 0) #133
1 parent 404bd6d commit 07fac31

File tree

7 files changed

+317
-197
lines changed

7 files changed

+317
-197
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,7 @@ protected:
14331433
SendResponseAsync(response().MakeGetResponse(value));
14341434
}
14351435
else
1436-
SendResponseAsync(response().MakeErrorResponse("Required cache value was not found for the key: " + key, 404));
1436+
SendResponseAsync(response().MakeErrorResponse(404, "Required cache value was not found for the key: " + key));
14371437
}
14381438
else if ((request.method() == "POST") || (request.method() == "PUT"))
14391439
{
@@ -1468,7 +1468,7 @@ protected:
14681468
SendResponseAsync(response().MakeGetResponse(value));
14691469
}
14701470
else
1471-
SendResponseAsync(response().MakeErrorResponse("Deleted cache value was not found for the key: " + key, 404));
1471+
SendResponseAsync(response().MakeErrorResponse(404, "Deleted cache value was not found for the key: " + key));
14721472
}
14731473
else if (request.method() == "OPTIONS")
14741474
SendResponseAsync(response().MakeOptionsResponse());
@@ -1811,7 +1811,7 @@ protected:
18111811
SendResponseAsync(response().MakeGetResponse(value));
18121812
}
18131813
else
1814-
SendResponseAsync(response().MakeErrorResponse("Required cache value was not found for the key: " + key, 404));
1814+
SendResponseAsync(response().MakeErrorResponse(404, "Required cache value was not found for the key: " + key));
18151815
}
18161816
else if ((request.method() == "POST") || (request.method() == "PUT"))
18171817
{
@@ -1846,7 +1846,7 @@ protected:
18461846
SendResponseAsync(response().MakeGetResponse(value));
18471847
}
18481848
else
1849-
SendResponseAsync(response().MakeErrorResponse("Deleted cache value was not found for the key: " + key, 404));
1849+
SendResponseAsync(response().MakeErrorResponse(404, "Deleted cache value was not found for the key: " + key));
18501850
}
18511851
else if (request.method() == "OPTIONS")
18521852
SendResponseAsync(response().MakeOptionsResponse());

include/server/ws/ws.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,20 @@ class WebSocket
167167
//! Handshaked flag
168168
bool _ws_handshaked{false};
169169

170+
//! Received frame opcode
171+
uint8_t _ws_opcode;
170172
//! Received frame flag
171-
bool _ws_received{false};
173+
bool _ws_frame_received{false};
174+
//! Received final flag
175+
bool _ws_final_received{false};
172176
//! Received frame header size
173177
size_t _ws_header_size{0};
174178
//! Received frame payload size
175179
size_t _ws_payload_size{0};
176-
//! Receive buffer
177-
std::vector<uint8_t> _ws_receive_buffer;
180+
//! Receive frame buffer
181+
std::vector<uint8_t> _ws_receive_frame_buffer;
182+
//! Receive final buffer
183+
std::vector<uint8_t> _ws_receive_final_buffer;
178184
//! Receive mask
179185
uint8_t _ws_receive_mask[4];
180186

source/server/ws/ws.cpp

Lines changed: 96 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -257,176 +257,210 @@ void WebSocket::PrepareReceiveFrame(const void* buffer, size_t size)
257257
const uint8_t* data = (const uint8_t*)buffer;
258258

259259
// Clear received data after WebSocket frame was processed
260-
if (_ws_received)
260+
if (_ws_frame_received)
261261
{
262-
_ws_received = false;
262+
_ws_frame_received = false;
263263
_ws_header_size = 0;
264264
_ws_payload_size = 0;
265-
_ws_receive_buffer.clear();
265+
_ws_receive_frame_buffer.clear();
266266
*((uint32_t*)_ws_receive_mask) = 0;
267267
}
268+
if (_ws_final_received)
269+
{
270+
_ws_final_received = false;
271+
_ws_receive_final_buffer.clear();
272+
}
268273

269274
while (size > 0)
270275
{
271276
// Clear received data after WebSocket frame was processed
272-
if (_ws_received)
277+
if (_ws_frame_received)
273278
{
274-
_ws_received = false;
279+
_ws_frame_received = false;
275280
_ws_header_size = 0;
276281
_ws_payload_size = 0;
277-
_ws_receive_buffer.clear();
282+
_ws_receive_frame_buffer.clear();
278283
*((uint32_t*)_ws_receive_mask) = 0;
279284
}
285+
if (_ws_final_received)
286+
{
287+
_ws_final_received = false;
288+
_ws_receive_final_buffer.clear();
289+
}
280290

281291
// Prepare WebSocket frame opcode and mask flag
282-
if (_ws_receive_buffer.size() < 2)
292+
if (_ws_receive_frame_buffer.size() < 2)
283293
{
284294
for (size_t i = 0; i < 2; ++i, ++data, --size)
285295
{
286296
if (size == 0)
287297
return;
288-
_ws_receive_buffer.push_back(*data);
298+
_ws_receive_frame_buffer.push_back(*data);
289299
}
290300
}
291301

292-
uint8_t opcode = _ws_receive_buffer[0] & 0x0F;
293-
[[maybe_unused]] bool fin = ((_ws_receive_buffer[0] >> 7) & 0x01) != 0;
294-
bool mask = ((_ws_receive_buffer[1] >> 7) & 0x01) != 0;
295-
size_t payload = _ws_receive_buffer[1] & (~0x80);
302+
uint8_t opcode = _ws_receive_frame_buffer[0] & 0x0F;
303+
[[maybe_unused]] bool fin = ((_ws_receive_frame_buffer[0] >> 7) & 0x01) != 0;
304+
bool mask = ((_ws_receive_frame_buffer[1] >> 7) & 0x01) != 0;
305+
size_t payload = _ws_receive_frame_buffer[1] & (~0x80);
306+
307+
// Prepare WebSocket opcode
308+
_ws_opcode = (opcode != 0) ? opcode : _ws_opcode;
296309

297310
// Prepare WebSocket frame size
298311
if (payload <= 125)
299312
{
300313
_ws_header_size = 2 + (mask ? 4 : 0);
301314
_ws_payload_size = payload;
302-
_ws_receive_buffer.reserve(_ws_header_size + _ws_payload_size);
315+
_ws_receive_frame_buffer.reserve(_ws_header_size + _ws_payload_size);
316+
_ws_receive_final_buffer.reserve(_ws_header_size + _ws_payload_size);
303317
}
304318
else if (payload == 126)
305319
{
306-
if (_ws_receive_buffer.size() < 4)
320+
if (_ws_receive_frame_buffer.size() < 4)
307321
{
308322
for (size_t i = 0; i < 2; ++i, ++data, --size)
309323
{
310324
if (size == 0)
311325
return;
312-
_ws_receive_buffer.push_back(*data);
326+
_ws_receive_frame_buffer.push_back(*data);
313327
}
314328
}
315329

316-
payload = (((size_t)_ws_receive_buffer[2] << 8) | ((size_t)_ws_receive_buffer[3] << 0));
330+
payload = (((size_t)_ws_receive_frame_buffer[2] << 8) | ((size_t)_ws_receive_frame_buffer[3] << 0));
317331
_ws_header_size = 4 + (mask ? 4 : 0);
318332
_ws_payload_size = payload;
319-
_ws_receive_buffer.reserve(_ws_header_size + _ws_payload_size);
333+
_ws_receive_frame_buffer.reserve(_ws_header_size + _ws_payload_size);
334+
_ws_receive_final_buffer.reserve(_ws_header_size + _ws_payload_size);
320335
}
321336
else if (payload == 127)
322337
{
323-
if (_ws_receive_buffer.size() < 10)
338+
if (_ws_receive_frame_buffer.size() < 10)
324339
{
325340
for (size_t i = 0; i < 8; ++i, ++data, --size)
326341
{
327342
if (size == 0)
328343
return;
329-
_ws_receive_buffer.push_back(*data);
344+
_ws_receive_frame_buffer.push_back(*data);
330345
}
331346
}
332347

333-
payload = (((size_t)_ws_receive_buffer[2] << 56) | ((size_t)_ws_receive_buffer[3] << 48) | ((size_t)_ws_receive_buffer[4] << 40) | ((size_t)_ws_receive_buffer[5] << 32) | ((size_t)_ws_receive_buffer[6] << 24) | ((size_t)_ws_receive_buffer[7] << 16) | ((size_t)_ws_receive_buffer[8] << 8) | ((size_t)_ws_receive_buffer[9] << 0));
348+
payload = (((size_t)_ws_receive_frame_buffer[2] << 56) | ((size_t)_ws_receive_frame_buffer[3] << 48) | ((size_t)_ws_receive_frame_buffer[4] << 40) | ((size_t)_ws_receive_frame_buffer[5] << 32) | ((size_t)_ws_receive_frame_buffer[6] << 24) | ((size_t)_ws_receive_frame_buffer[7] << 16) | ((size_t)_ws_receive_frame_buffer[8] << 8) | ((size_t)_ws_receive_frame_buffer[9] << 0));
334349
_ws_header_size = 10 + (mask ? 4 : 0);
335350
_ws_payload_size = payload;
336-
_ws_receive_buffer.reserve(_ws_header_size + _ws_payload_size);
351+
_ws_receive_frame_buffer.reserve(_ws_header_size + _ws_payload_size);
352+
_ws_receive_final_buffer.reserve(_ws_header_size + _ws_payload_size);
337353
}
338354

339355
// Prepare WebSocket frame mask
340356
if (mask)
341357
{
342-
if (_ws_receive_buffer.size() < _ws_header_size)
358+
if (_ws_receive_frame_buffer.size() < _ws_header_size)
343359
{
344360
for (size_t i = 0; i < 4; ++i, ++data, --size)
345361
{
346362
if (size == 0)
347363
return;
348-
_ws_receive_buffer.push_back(*data);
364+
_ws_receive_frame_buffer.push_back(*data);
349365
_ws_receive_mask[i] = *data;
350366
}
351367
}
352368
}
353369

354370
size_t total = _ws_header_size + _ws_payload_size;
355-
size_t length = std::min(total - _ws_receive_buffer.size(), size);
371+
size_t length = std::min(total - _ws_receive_frame_buffer.size(), size);
356372

357373
// Prepare WebSocket frame payload
358-
_ws_receive_buffer.insert(_ws_receive_buffer.end(), data, data + length);
374+
_ws_receive_frame_buffer.insert(_ws_receive_frame_buffer.end(), data, data + length);
359375
data += length;
360376
size -= length;
361377

362378
// Process WebSocket frame
363-
if (_ws_receive_buffer.size() == total)
379+
if (_ws_receive_frame_buffer.size() == total)
364380
{
365-
size_t offset = _ws_header_size;
366-
367381
// Unmask WebSocket frame content
368382
if (mask)
383+
{
369384
for (size_t i = 0; i < _ws_payload_size; ++i)
370-
_ws_receive_buffer[offset + i] ^= _ws_receive_mask[i % 4];
385+
_ws_receive_final_buffer.push_back(_ws_receive_frame_buffer[_ws_header_size + i] ^ _ws_receive_mask[i % 4]);
386+
}
387+
else
388+
_ws_receive_final_buffer.insert(_ws_receive_final_buffer.end(), _ws_receive_frame_buffer.begin() + _ws_header_size, _ws_receive_frame_buffer.end());
371389

372-
_ws_received = true;
390+
_ws_frame_received = true;
373391

374-
if ((opcode & WS_PING) == WS_PING)
392+
// Finalize WebSocket frame
393+
if (fin)
375394
{
376-
// Call the WebSocket ping handler
377-
onWSPing(_ws_receive_buffer.data() + offset, _ws_payload_size);
378-
}
379-
else if ((opcode & WS_PONG) == WS_PONG)
380-
{
381-
// Call the WebSocket pong handler
382-
onWSPong(_ws_receive_buffer.data() + offset, _ws_payload_size);
383-
}
384-
else if ((opcode & WS_CLOSE) == WS_CLOSE)
385-
{
386-
// Call the WebSocket close handler
387-
onWSClose(_ws_receive_buffer.data() + offset, _ws_payload_size);
388-
}
389-
else if (((opcode & WS_TEXT) == WS_TEXT) || ((opcode & WS_BINARY) == WS_BINARY))
390-
{
391-
// Call the WebSocket received handler
392-
onWSReceived(_ws_receive_buffer.data() + offset, _ws_payload_size);
395+
_ws_final_received = true;
396+
397+
switch (_ws_opcode)
398+
{
399+
case WS_PING:
400+
{
401+
// Call the WebSocket ping handler
402+
onWSPing(_ws_receive_final_buffer.data(), _ws_receive_final_buffer.size());
403+
break;
404+
}
405+
case WS_PONG:
406+
{
407+
// Call the WebSocket pong handler
408+
onWSPong(_ws_receive_final_buffer.data(), _ws_receive_final_buffer.size());
409+
break;
410+
}
411+
case WS_CLOSE:
412+
{
413+
// Call the WebSocket close handler
414+
onWSClose(_ws_receive_final_buffer.data(), _ws_receive_final_buffer.size());
415+
break;
416+
}
417+
case WS_BINARY:
418+
case WS_TEXT:
419+
{
420+
// Call the WebSocket received handler
421+
onWSReceived(_ws_receive_final_buffer.data(), _ws_receive_final_buffer.size());
422+
break;
423+
}
424+
}
393425
}
394426
}
395427
}
396428
}
397429

398430
size_t WebSocket::RequiredReceiveFrameSize()
399431
{
400-
if (_ws_received)
432+
if (_ws_frame_received)
401433
return 0;
402434

403435
// Required WebSocket frame opcode and mask flag
404-
if (_ws_receive_buffer.size() < 2)
405-
return 2 - _ws_receive_buffer.size();
436+
if (_ws_receive_frame_buffer.size() < 2)
437+
return 2 - _ws_receive_frame_buffer.size();
406438

407-
bool mask = ((_ws_receive_buffer[1] >> 7) & 0x01) != 0;
408-
size_t payload = _ws_receive_buffer[1] & (~0x80);
439+
bool mask = ((_ws_receive_frame_buffer[1] >> 7) & 0x01) != 0;
440+
size_t payload = _ws_receive_frame_buffer[1] & (~0x80);
409441

410442
// Required WebSocket frame size
411-
if ((payload == 126) && (_ws_receive_buffer.size() < 4))
412-
return 4 - _ws_receive_buffer.size();
413-
if ((payload == 127) && (_ws_receive_buffer.size() < 10))
414-
return 10 - _ws_receive_buffer.size();
443+
if ((payload == 126) && (_ws_receive_frame_buffer.size() < 4))
444+
return 4 - _ws_receive_frame_buffer.size();
445+
if ((payload == 127) && (_ws_receive_frame_buffer.size() < 10))
446+
return 10 - _ws_receive_frame_buffer.size();
415447

416448
// Required WebSocket frame mask
417-
if ((mask) && (_ws_receive_buffer.size() < _ws_header_size))
418-
return _ws_header_size - _ws_receive_buffer.size();
449+
if ((mask) && (_ws_receive_frame_buffer.size() < _ws_header_size))
450+
return _ws_header_size - _ws_receive_frame_buffer.size();
419451

420452
// Required WebSocket frame payload
421-
return _ws_header_size + _ws_payload_size - _ws_receive_buffer.size();
453+
return _ws_header_size + _ws_payload_size - _ws_receive_frame_buffer.size();
422454
}
423455

424456
void WebSocket::ClearWSBuffers()
425457
{
426-
_ws_received = false;
458+
_ws_frame_received = false;
459+
_ws_final_received = false;
427460
_ws_header_size = 0;
428461
_ws_payload_size = 0;
429-
_ws_receive_buffer.clear();
462+
_ws_receive_frame_buffer.clear();
463+
_ws_receive_final_buffer.clear();
430464
*((uint32_t*)_ws_receive_mask) = 0;
431465

432466
std::scoped_lock locker(_ws_send_lock);

0 commit comments

Comments
 (0)