Skip to content

Commit 3c9bb75

Browse files
committed
Restore _pinfo.masked to a boolean state (0 or 1) to keep backward compatibility.
1 parent 87f5219 commit 3c9bb75

File tree

1 file changed

+40
-13
lines changed

1 file changed

+40
-13
lines changed

src/AsyncWebSocket.cpp

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,12 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) {
518518
_pinfo.masked = ((fdata[1] & 0x80) != 0) ? 1 : 0;
519519
_pinfo.len = fdata[1] & 0x7F;
520520

521-
// async_ws_log_d("WS[%" PRIu32 "]: _onData: %" PRIu32, _clientId, plen);
522-
// async_ws_log_d("WS[%" PRIu32 "]: _status = %" PRIu32, _clientId, _status);
523-
// async_ws_log_d("WS[%" PRIu32 "]: _pinfo: index: %" PRIu64 ", final: %" PRIu8 ", opcode: %" PRIu8 ", masked: %" PRIu8 ", len: %" PRIu64, _clientId, _pinfo.index, _pinfo.final, _pinfo.opcode, _pinfo.masked, _pinfo.len);
521+
// async_ws_log_w("WS[%" PRIu32 "]: _onData: %" PRIu32, _clientId, plen);
522+
// async_ws_log_w("WS[%" PRIu32 "]: _status = %" PRIu32, _clientId, _status);
523+
// async_ws_log_w(
524+
// "WS[%" PRIu32 "]: _pinfo: index: %" PRIu64 ", final: %" PRIu8 ", opcode: %" PRIu8 ", masked: %" PRIu8 ", len: %" PRIu64, _clientId, _pinfo.index,
525+
// _pinfo.final, _pinfo.opcode, _pinfo.masked, _pinfo.len
526+
// );
524527

525528
data += 2;
526529
plen -= 2;
@@ -538,24 +541,48 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) {
538541
}
539542
}
540543

541-
if (_pinfo.masked > 0 && _pinfo.masked < 5) {
542-
// Handle fragmented mask data - Safari may split the 4-byte mask across multiple packets
543-
while (_pinfo.masked < 5) {
544-
if (plen == 0) {
545-
//wait for more data
544+
if (_pinfo.masked) {
545+
// Read mask bytes (may be fragmented across packets in Safari)
546+
size_t mask_offset = 0;
547+
548+
// If we're resuming from a previous fragmented read, check _pinfo.index
549+
if (_pstate == 1 && _pinfo.index < 4) {
550+
mask_offset = _pinfo.index;
551+
}
552+
553+
// Read as many mask bytes as available
554+
while (mask_offset < 4 && plen > 0) {
555+
_pinfo.mask[mask_offset++] = *data++;
556+
plen--;
557+
}
558+
559+
// Check if we have all 4 mask bytes
560+
if (mask_offset < 4) {
561+
// Incomplete mask
562+
if (_pinfo.opcode == WS_DISCONNECT && plen == 0) {
563+
// Safari close frame edge case: masked bit set but no mask data
564+
// async_ws_log_w("WS[%" PRIu32 "]: close frame with incomplete mask, treating as unmasked", _clientId);
565+
_pinfo.masked = 0;
566+
_pinfo.index = 0;
567+
} else {
568+
// Wait for more data
569+
// async_ws_log_w("WS[%" PRIu32 "]: waiting for more mask data: read=%zu/4", _clientId, mask_offset);
570+
_pinfo.index = mask_offset; // Save progress
546571
_pstate = 1;
547572
return;
548573
}
549-
_pinfo.mask[_pinfo.masked - 1] = data[0];
550-
data += 1;
551-
plen -= 1;
552-
_pinfo.masked++;
574+
} else {
575+
// All mask bytes received
576+
// async_ws_log_w("WS[%" PRIu32 "]: mask complete", _clientId);
577+
_pinfo.index = 0; // Reset index for payload processing
553578
}
554579
}
555580

556581
const size_t datalen = std::min((size_t)(_pinfo.len - _pinfo.index), plen);
557582
const auto datalast = data[datalen];
558583

584+
// async_ws_log_w("WS[%" PRIu32 "]: _processing data: datalen=%" PRIu32 ", plen=%" PRIu32, _clientId, datalen, plen);
585+
559586
if (_pinfo.masked) {
560587
for (size_t i = 0; i < datalen; i++) {
561588
data[i] ^= _pinfo.mask[(_pinfo.index + i) % 4];
@@ -614,7 +641,7 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) {
614641
}
615642
}
616643
} else {
617-
// os_printf("frame error: len: %u, index: %llu, total: %llu\n", datalen, _pinfo.index, _pinfo.len);
644+
// async_ws_log_w("frame error: len: %u, index: %llu, total: %llu\n", datalen, _pinfo.index, _pinfo.len);
618645
// what should we do?
619646
break;
620647
}

0 commit comments

Comments
 (0)