43 std::size_t Receiver::receive() {
45 std::size_t consumed = 0;
50 switch (parserState) {
51 case ParserState::BEGIN:
52 parserState = ParserState::OPCODE;
54 case ParserState::OPCODE:
57 case ParserState::LENGTH:
60 case ParserState::ELENGTH:
63 case ParserState::MASKINGKEY:
64 ret = readMaskingKey();
66 case ParserState::PAYLOAD:
69 case ParserState::ERROR:
70 onMessageError(errorState);
75 }
while (ret > 0 && parserState != ParserState::BEGIN && parserState != ParserState::ERROR);
80 std::size_t Receiver::readOpcode() {
82 const std::size_t ret = readFrameData(&byte, 1);
85 const uint8_t opCodeByte =
static_cast<uint8_t>(byte);
87 fin = (opCodeByte & 0b10000000) != 0;
88 opCode = opCodeByte & 0b00001111;
91 onMessageStart(opCode);
92 parserState = ParserState::LENGTH;
93 }
else if (opCode == 0) {
94 parserState = ParserState::LENGTH;
96 parserState = ParserState::ERROR;
98 LOG(ERROR) <<
"WebSocket: Error opcode in continuation frame";
106 std::size_t Receiver::readLength() {
108 const std::size_t ret = readFrameData(&byte, 1);
111 const uint8_t lengthByte =
static_cast<uint8_t>(byte);
113 masked = (lengthByte & 0b10000000) != 0;
114 payLoadNumBytes = payLoadNumBytesLeft = lengthByte & 0b01111111;
116 if (payLoadNumBytes > 125) {
117 switch (payLoadNumBytes) {
119 elengthNumBytes = elengthNumBytesLeft = 2;
122 elengthNumBytes = elengthNumBytesLeft = 8;
125 parserState = ParserState::ELENGTH;
126 payLoadNumBytes = payLoadNumBytesLeft = 0;
129 parserState = ParserState::MASKINGKEY;
130 }
else if (payLoadNumBytes > 0) {
131 parserState = ParserState::PAYLOAD;
144 std::size_t Receiver::readELength() {
145 const std::size_t ret = readFrameData(elengthChunk, elengthNumBytesLeft);
147 for (std::size_t i = 0; i < ret; i++) {
148 payLoadNumBytes |= *
reinterpret_cast<uint64_t*>(elengthChunk + i) << (elengthNumBytes - elengthNumBytesLeft) * 8;
150 elengthNumBytesLeft--;
153 if (elengthNumBytesLeft == 0) {
154 switch (elengthNumBytes) {
156 payLoadNumBytes = payLoadNumBytesLeft = be16toh(
static_cast<uint16_t>(payLoadNumBytes));
159 payLoadNumBytes = payLoadNumBytesLeft = be64toh(payLoadNumBytes);
163 if ((payLoadNumBytes &
static_cast<uint64_t>(0x01) << 63) != 0) {
164 parserState = ParserState::ERROR;
167 parserState = ParserState::MASKINGKEY;
169 parserState = ParserState::PAYLOAD;
176 std::size_t Receiver::readMaskingKey() {
177 const std::size_t ret = readFrameData(maskingKeyChunk, maskingKeyNumBytesLeft);
179 for (std::size_t i = 0; i < ret; i++) {
180 maskingKey |=
static_cast<uint32_t>(*
reinterpret_cast<
unsigned char*>(maskingKeyChunk + i))
181 << (maskingKeyNumBytes - maskingKeyNumBytesLeft) * 8;
182 maskingKeyNumBytesLeft--;
185 if (maskingKeyNumBytesLeft == 0) {
186 maskingKeyAsArray = {.key = maskingKey};
188 if (payLoadNumBytes > 0) {
189 parserState = ParserState::PAYLOAD;
201 std::size_t Receiver::readPayload() {
203 :
static_cast<std::size_t>(payLoadNumBytesLeft);
205 const std::size_t ret = readFrameData(payloadChunk, payloadChunkLeft);
208 const std::size_t payloadChunkLen =
static_cast<std::size_t>(ret);
211 for (std::size_t i = 0; i < payloadChunkLen; i++) {
212 *(payloadChunk + i) =
213 *(payloadChunk + i) ^ *(maskingKeyAsArray.keyAsArray + (i + payLoadNumBytes - payLoadNumBytesLeft) % 4);
217 LOG(TRACE) <<
"WebSocket receive: Frame data\n" << utils::hexDump(payloadChunk, payloadChunkLen, 32,
true);
219 onMessageData(payloadChunk, payloadChunkLen);
221 payLoadNumBytesLeft -= payloadChunkLen;
224 if (payLoadNumBytesLeft == 0) {