@@ -565,83 +565,93 @@ void AsyncWebSocketClient::_onDisconnect(){
565565 _server->_handleDisconnect (this );
566566}
567567
568- void AsyncWebSocketClient::_onData (void *buf , size_t plen){
568+ void AsyncWebSocketClient::_onData (void *pbuf , size_t plen){
569569 _lastMessageTime = millis ();
570- uint8_t *fdata = (uint8_t *)buf;
571- uint8_t * data = fdata;
572- if (!_pstate){
573- _pinfo.index = 0 ;
574- _pinfo.final = (fdata[0 ] & 0x80 ) != 0 ;
575- _pinfo.opcode = fdata[0 ] & 0x0F ;
576- _pinfo.masked = (fdata[1 ] & 0x80 ) != 0 ;
577- _pinfo.len = fdata[1 ] & 0x7F ;
578- data += 2 ;
579- plen = plen - 2 ;
580- if (_pinfo.len == 126 ){
581- _pinfo.len = fdata[3 ] | (uint16_t )(fdata[2 ]) << 8 ;
570+ uint8_t *data = (uint8_t *)pbuf;
571+ while (plen > 0 ){
572+ if (!_pstate){
573+ const uint8_t *fdata = data;
574+ _pinfo.index = 0 ;
575+ _pinfo.final = (fdata[0 ] & 0x80 ) != 0 ;
576+ _pinfo.opcode = fdata[0 ] & 0x0F ;
577+ _pinfo.masked = (fdata[1 ] & 0x80 ) != 0 ;
578+ _pinfo.len = fdata[1 ] & 0x7F ;
582579 data += 2 ;
583- plen = plen - 2 ;
584- } else if (_pinfo.len == 127 ){
585- _pinfo.len = fdata[9 ] | (uint16_t )(fdata[8 ]) << 8 | (uint32_t )(fdata[7 ]) << 16 | (uint32_t )(fdata[6 ]) << 24 | (uint64_t )(fdata[5 ]) << 32 | (uint64_t )(fdata[4 ]) << 40 | (uint64_t )(fdata[3 ]) << 48 | (uint64_t )(fdata[2 ]) << 56 ;
586- data += 8 ;
587- plen = plen - 8 ;
588- }
580+ plen -= 2 ;
581+ if (_pinfo.len == 126 ){
582+ _pinfo.len = fdata[3 ] | (uint16_t )(fdata[2 ]) << 8 ;
583+ data += 2 ;
584+ plen -= 2 ;
585+ } else if (_pinfo.len == 127 ){
586+ _pinfo.len = fdata[9 ] | (uint16_t )(fdata[8 ]) << 8 | (uint32_t )(fdata[7 ]) << 16 | (uint32_t )(fdata[6 ]) << 24 | (uint64_t )(fdata[5 ]) << 32 | (uint64_t )(fdata[4 ]) << 40 | (uint64_t )(fdata[3 ]) << 48 | (uint64_t )(fdata[2 ]) << 56 ;
587+ data += 8 ;
588+ plen -= 8 ;
589+ }
589590
590- if (_pinfo.masked ){
591- memcpy (_pinfo.mask , data, 4 );
592- data += 4 ;
593- plen = plen - 4 ;
594- size_t i;
595- for (i=0 ;i<plen;i++)
596- data[i] = data[i] ^ _pinfo.mask [(_pinfo.index +i)%4 ];
591+ if (_pinfo.masked ){
592+ memcpy (_pinfo.mask , data, 4 );
593+ data += 4 ;
594+ plen -= 4 ;
595+ }
597596 }
598- } else {
597+
598+ const size_t datalen = std::min ((size_t )(_pinfo.len - _pinfo.index ), plen);
599+ const auto datalast = data[datalen];
600+
599601 if (_pinfo.masked ){
600- size_t i;
601- for (i=0 ;i<plen;i++)
602- data[i] = data[i] ^ _pinfo.mask [(_pinfo.index +i)%4 ];
602+ for (size_t i=0 ;i<datalen;i++)
603+ data[i] ^= _pinfo.mask [(_pinfo.index +i)%4 ];
603604 }
604- }
605- if ((plen + _pinfo.index ) < _pinfo.len ){
606- _pstate = 1 ;
607605
608- if (_pinfo.index == 0 ){
609- if (_pinfo.opcode ){
610- _pinfo.message_opcode = _pinfo.opcode ;
611- _pinfo.num = 0 ;
612- } else _pinfo.num += 1 ;
613- }
614- _server->_handleEvent (this , WS_EVT_DATA, (void *)&_pinfo, (uint8_t *)data, plen);
615-
616- _pinfo.index += plen;
617- } else if ((plen + _pinfo.index ) == _pinfo.len ){
618- _pstate = 0 ;
619- if (_pinfo.opcode == WS_DISCONNECT){
620- if (plen){
621- uint16_t reasonCode = (uint16_t )(data[0 ] << 8 ) + data[1 ];
622- char * reasonString = (char *)(data+2 );
623- if (reasonCode > 1001 ){
624- _server->_handleEvent (this , WS_EVT_ERROR, (void *)&reasonCode, (uint8_t *)reasonString, strlen (reasonString));
625- }
606+ if ((datalen + _pinfo.index ) < _pinfo.len ){
607+ _pstate = 1 ;
608+
609+ if (_pinfo.index == 0 ){
610+ if (_pinfo.opcode ){
611+ _pinfo.message_opcode = _pinfo.opcode ;
612+ _pinfo.num = 0 ;
613+ } else _pinfo.num += 1 ;
626614 }
627- if (_status == WS_DISCONNECTING){
628- _status = WS_DISCONNECTED;
629- _client->close (true );
630- } else {
631- _status = WS_DISCONNECTING;
632- _queueControl (new AsyncWebSocketControl (WS_DISCONNECT, data, plen));
615+ _server->_handleEvent (this , WS_EVT_DATA, (void *)&_pinfo, (uint8_t *)data, datalen);
616+
617+ _pinfo.index += datalen;
618+ } else if ((datalen + _pinfo.index ) == _pinfo.len ){
619+ _pstate = 0 ;
620+ if (_pinfo.opcode == WS_DISCONNECT){
621+ if (datalen){
622+ uint16_t reasonCode = (uint16_t )(data[0 ] << 8 ) + data[1 ];
623+ char * reasonString = (char *)(data+2 );
624+ if (reasonCode > 1001 ){
625+ _server->_handleEvent (this , WS_EVT_ERROR, (void *)&reasonCode, (uint8_t *)reasonString, strlen (reasonString));
626+ }
627+ }
628+ if (_status == WS_DISCONNECTING){
629+ _status = WS_DISCONNECTED;
630+ _client->close (true );
631+ } else {
632+ _status = WS_DISCONNECTING;
633+ _queueControl (new AsyncWebSocketControl (WS_DISCONNECT, data, datalen));
634+ }
635+ } else if (_pinfo.opcode == WS_PING){
636+ _queueControl (new AsyncWebSocketControl (WS_PONG, data, datalen));
637+ } else if (_pinfo.opcode == WS_PONG){
638+ if (datalen != AWSC_PING_PAYLOAD_LEN || memcmp (AWSC_PING_PAYLOAD, data, AWSC_PING_PAYLOAD_LEN) != 0 )
639+ _server->_handleEvent (this , WS_EVT_PONG, NULL , data, datalen);
640+ } else if (_pinfo.opcode < 8 ){// continuation or text/binary frame
641+ _server->_handleEvent (this , WS_EVT_DATA, (void *)&_pinfo, data, datalen);
633642 }
634- } else if (_pinfo.opcode == WS_PING){
635- _queueControl (new AsyncWebSocketControl (WS_PONG, data, plen));
636- } else if (_pinfo.opcode == WS_PONG){
637- if (plen != AWSC_PING_PAYLOAD_LEN || memcmp (AWSC_PING_PAYLOAD, data, AWSC_PING_PAYLOAD_LEN) != 0 )
638- _server->_handleEvent (this , WS_EVT_PONG, NULL , (uint8_t *)data, plen);
639- } else if (_pinfo.opcode < 8 ){// continuation or text/binary frame
640- _server->_handleEvent (this , WS_EVT_DATA, (void *)&_pinfo, (uint8_t *)data, plen);
643+ } else {
644+ // os_printf("frame error: len: %u, index: %llu, total: %llu\n", datalen, _pinfo.index, _pinfo.len);
645+ // what should we do?
646+ break ;
641647 }
642- } else {
643- // os_printf("frame error: len: %u, index: %llu, total: %llu\n", plen, _pinfo.index, _pinfo.len);
644- // what should we do?
648+
649+ // restore byte as _handleEvent may have added a null terminator i.e., data[len] = 0;
650+ if (datalen > 0 )
651+ data[datalen] = datalast;
652+
653+ data += datalen;
654+ plen -= datalen;
645655 }
646656}
647657
0 commit comments