@@ -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
398430size_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
424456void 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