SNode.C
Loading...
Searching...
No Matches
web::websocket::Receiver Class Referenceabstract

#include <Receiver.h>

Inheritance diagram for web::websocket::Receiver:
Collaboration diagram for web::websocket::Receiver:

Classes

union  ELength2
 
union  ELength8
 

Public Member Functions

 Receiver (bool maskingExpected)
 
 Receiver (const Receiver &)=delete
 
Receiveroperator= (const Receiver &)=delete
 
virtual ~Receiver ()
 
std::size_t receive ()
 
std::size_t getPayloadTotalRead () const
 

Private Types

enum struct  ParserState {
  BEGIN , OPCODE , LENGTH , ELENGTH ,
  MASKINGKEY , PAYLOAD , ERROR
}
 

Private Member Functions

std::size_t readFrameData (char *chunk, std::size_t chunkLen)
 
std::size_t readOpcode ()
 
std::size_t readLength ()
 
std::size_t readELength ()
 
std::size_t readMaskingKey ()
 
std::size_t readPayload ()
 
std::size_t readELength2 ()
 
std::size_t readELength8 ()
 
virtual void onMessageStart (int opCode)=0
 
virtual void onMessageData (const char *chunk, uint64_t chunkLen)=0
 
virtual void onMessageEnd ()=0
 
virtual void onMessageError (uint16_t errnum)=0
 
void reset ()
 
virtual std::size_t readFrameChunk (char *chunk, std::size_t chunkLen) const =0
 

Private Attributes

enum web::websocket::Receiver::ParserState parserState = ParserState::BEGIN
 
bool fin = false
 
bool continuation = false
 
bool masked = false
 
bool maskingExpected = false
 
uint8_t opCode = 0
 
char maskingKey [4]
 
union web::websocket::Receiver::ELength8 eLength8
 
union web::websocket::Receiver::ELength2 eLength2
 
uint8_t elengthNumBytes = 0
 
uint8_t elengthNumBytesLeft = 0
 
uint64_t payloadNumBytes = 0
 
uint64_t payloadNumBytesLeft = 0
 
uint8_t maskingKeyNumBytes = 4
 
uint8_t maskingKeyNumBytesLeft = 4
 
uint16_t errorState = 0
 
std::size_t payloadTotalRead = 0
 

Detailed Description

Definition at line 54 of file Receiver.h.

Member Enumeration Documentation

◆ ParserState

Constructor & Destructor Documentation

◆ Receiver() [1/2]

web::websocket::Receiver::Receiver ( bool  maskingExpected)

Definition at line 60 of file Receiver.cpp.

References maskingExpected.

Referenced by web::websocket::SubProtocolContext::SubProtocolContext().

Here is the caller graph for this function:

◆ Receiver() [2/2]

web::websocket::Receiver::Receiver ( const Receiver )
delete

◆ ~Receiver()

web::websocket::Receiver::~Receiver ( )
virtual

Definition at line 64 of file Receiver.cpp.

64 {
65 }

Member Function Documentation

◆ getPayloadTotalRead()

std::size_t web::websocket::Receiver::getPayloadTotalRead ( ) const

Definition at line 104 of file Receiver.cpp.

104 {
105 return payloadTotalRead;
106 }
std::size_t payloadTotalRead
Definition Receiver.h:122

References payloadTotalRead.

Referenced by web::websocket::SocketContextUpgrade< SubProtocolT, RequestT, ResponseT >::getPayloadTotalRead().

Here is the caller graph for this function:

◆ onMessageData()

virtual void web::websocket::Receiver::onMessageData ( const char *  chunk,
uint64_t  chunkLen 
)
privatepure virtual

◆ onMessageEnd()

virtual void web::websocket::Receiver::onMessageEnd ( )
privatepure virtual

◆ onMessageError()

virtual void web::websocket::Receiver::onMessageError ( uint16_t  errnum)
privatepure virtual

◆ onMessageStart()

virtual void web::websocket::Receiver::onMessageStart ( int  opCode)
privatepure virtual

◆ operator=()

Receiver & web::websocket::Receiver::operator= ( const Receiver )
delete

◆ readELength()

std::size_t web::websocket::Receiver::readELength ( )
private

Definition at line 216 of file Receiver.cpp.

216 {
217 std::size_t ret = 0;
218
219 switch (elengthNumBytes) {
220 case 2:
221 ret = readELength2();
222 break;
223 case 8:
224 ret = readELength8();
225 break;
226 }
227
228 if (elengthNumBytesLeft == 0) {
229 if ((payloadNumBytes & static_cast<uint64_t>(0x01) << 63) != 0) {
231 errorState = 1004;
232 } else if (masked) {
234 } else {
236 }
237 }
238
239 return ret;
240 }
std::size_t readELength2()
Definition Receiver.cpp:180
std::size_t readELength8()
Definition Receiver.cpp:198

References elengthNumBytes, elengthNumBytesLeft, ERROR, errorState, masked, MASKINGKEY, PAYLOAD, payloadNumBytes, readELength2(), and readELength8().

Referenced by receive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readELength2()

std::size_t web::websocket::Receiver::readELength2 ( )
private

Definition at line 180 of file Receiver.cpp.

180 {
181 char elengthChunk[2]{};
182
183 const std::size_t ret = readFrameData(elengthChunk, elengthNumBytesLeft);
184
185 const std::size_t cursor = static_cast<std::size_t>(elengthNumBytes - elengthNumBytesLeft);
186 for (std::size_t i = 0; i < ret; i++) {
187 eLength2.asBytes[cursor + i] = elengthChunk[i];
189 }
190
191 if (elengthNumBytesLeft == 0) {
193 }
194
195 return ret;
196 }
std::size_t readFrameData(char *chunk, std::size_t chunkLen)
Definition Receiver.cpp:108
union web::websocket::Receiver::ELength2 eLength2

References web::websocket::Receiver::ELength2::asBytes, web::websocket::Receiver::ELength2::asValue, elengthNumBytes, elengthNumBytesLeft, payloadNumBytes, payloadNumBytesLeft, and readFrameData().

Referenced by readELength().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readELength8()

std::size_t web::websocket::Receiver::readELength8 ( )
private

Definition at line 198 of file Receiver.cpp.

198 {
199 char elengthChunk[8]{};
200
201 const std::size_t ret = readFrameData(elengthChunk, elengthNumBytesLeft);
202
203 const std::size_t cursor = static_cast<std::size_t>(elengthNumBytes - elengthNumBytesLeft);
204 for (std::size_t i = 0; i < ret; i++) {
205 eLength8.asBytes[cursor + i] = elengthChunk[i];
207 }
208
209 if (elengthNumBytesLeft == 0) {
211 }
212
213 return ret;
214 }
union web::websocket::Receiver::ELength8 eLength8

References web::websocket::Receiver::ELength8::asBytes, web::websocket::Receiver::ELength8::asValue, elengthNumBytes, elengthNumBytesLeft, payloadNumBytes, payloadNumBytesLeft, and readFrameData().

Referenced by readELength().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readFrameChunk()

virtual std::size_t web::websocket::Receiver::readFrameChunk ( char *  chunk,
std::size_t  chunkLen 
) const
privatepure virtual

◆ readFrameData()

std::size_t web::websocket::Receiver::readFrameData ( char *  chunk,
std::size_t  chunkLen 
)
private

Definition at line 108 of file Receiver.cpp.

108 {
109 return readFrameChunk(chunk, chunkLen);
110 }
virtual std::size_t readFrameChunk(char *chunk, std::size_t chunkLen) const =0

References readFrameChunk().

Referenced by readELength2(), readELength8(), readLength(), readMaskingKey(), readOpcode(), and readPayload().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readLength()

std::size_t web::websocket::Receiver::readLength ( )
private

Definition at line 138 of file Receiver.cpp.

138 {
139 char byte = 0;
140 const std::size_t ret = readFrameData(&byte, 1);
141
142 if (ret > 0) {
143 const uint8_t lengthByte = static_cast<uint8_t>(byte);
144
145 masked = (lengthByte & 0b10000000) != 0;
146 if (masked == maskingExpected) {
147 payloadNumBytes = payloadNumBytesLeft = lengthByte & 0b01111111;
148
149 if (payloadNumBytes > 125) {
150 switch (payloadNumBytes) {
151 case 126:
153 break;
154 case 127:
156 break;
157 }
160 } else {
161 if (masked) {
163 } else if (payloadNumBytes > 0) {
165 } else {
166 if (fin) {
167 onMessageEnd();
168 }
169 reset();
170 }
171 }
172 } else {
174 }
175 }
176
177 return ret;
178 }
virtual void onMessageEnd()=0

References ELENGTH, elengthNumBytes, elengthNumBytesLeft, ERROR, fin, masked, maskingExpected, MASKINGKEY, onMessageEnd(), PAYLOAD, payloadNumBytes, payloadNumBytesLeft, readFrameData(), and reset().

Referenced by receive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readMaskingKey()

std::size_t web::websocket::Receiver::readMaskingKey ( )
private

Definition at line 242 of file Receiver.cpp.

242 {
243 char maskingKeyChunk[4]{};
244
245 const std::size_t ret = readFrameData(maskingKeyChunk, maskingKeyNumBytesLeft);
246
247 const std::size_t cursor = static_cast<std::size_t>(maskingKeyNumBytes - maskingKeyNumBytesLeft);
248 for (std::size_t i = 0; i < ret; i++) {
249 maskingKey[cursor + i] = maskingKeyChunk[i];
251 }
252
253 if (maskingKeyNumBytesLeft == 0) {
254 if (payloadNumBytes > 0) {
256 } else {
257 if (fin) {
258 onMessageEnd();
259 }
260 reset();
261 }
262 }
263
264 return ret;
265 }

References fin, maskingKey, maskingKeyNumBytes, maskingKeyNumBytesLeft, onMessageEnd(), PAYLOAD, payloadNumBytes, readFrameData(), and reset().

Referenced by receive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readOpcode()

std::size_t web::websocket::Receiver::readOpcode ( )
private

Definition at line 112 of file Receiver.cpp.

112 {
113 char byte = 0;
114 const std::size_t ret = readFrameData(&byte, 1);
115
116 if (ret > 0) {
117 const uint8_t opCodeByte = static_cast<uint8_t>(byte);
118
119 fin = (opCodeByte & 0b10000000) != 0;
120 opCode = opCodeByte & 0b00001111;
121
122 if (!continuation) {
125 } else if (opCode == 0) {
127 } else {
129 errorState = 1002;
130 LOG(ERROR) << "WebSocket: Error opcode in continuation frame";
131 }
132 continuation = !fin;
133 }
134
135 return ret;
136 }
virtual void onMessageStart(int opCode)=0

References continuation, ERROR, errorState, fin, LENGTH, onMessageStart(), opCode, and readFrameData().

Referenced by receive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readPayload()

std::size_t web::websocket::Receiver::readPayload ( )
private

Definition at line 267 of file Receiver.cpp.

267 {
268 char payloadChunk[MAX_PAYLOAD_CHUNK_LEN]{};
269
270 const std::size_t payloadChunkLeft = (MAX_PAYLOAD_CHUNK_LEN <= payloadNumBytesLeft)
271 ? static_cast<std::size_t>(MAX_PAYLOAD_CHUNK_LEN)
272 : static_cast<std::size_t>(payloadNumBytesLeft);
273 const std::size_t ret = readFrameData(payloadChunk, payloadChunkLeft);
274
275 if (ret > 0) {
276 const std::size_t payloadChunkLen = static_cast<std::size_t>(ret);
277
278 if (masked) {
279 for (std::size_t i = 0; i < payloadChunkLen; i++) {
280 *(payloadChunk + i) = *(payloadChunk + i) ^ *(maskingKey + (i + payloadNumBytes - payloadNumBytesLeft) % 4);
281 }
282 }
283
284 LOG(TRACE) << "WebSocket receive: Frame data\n" << utils::hexDump(payloadChunk, payloadChunkLen, 32, true);
285
286 onMessageData(payloadChunk, payloadChunkLen);
287
288 payloadNumBytesLeft -= payloadChunkLen;
289 payloadTotalRead += payloadChunkLen;
290 }
291
292 if (payloadNumBytesLeft == 0) {
293 if (fin) {
294 onMessageEnd();
295 }
296 reset();
297 }
298
299 return ret;
300 }
#define MAX_PAYLOAD_CHUNK_LEN
Definition Receiver.cpp:55
virtual void onMessageData(const char *chunk, uint64_t chunkLen)=0
std::string hexDump(const std::vector< char > &bytes, int prefixLength, bool prefixAtFirstLine)
Definition hexdump.cpp:58

References fin, utils::hexDump(), masked, maskingKey, onMessageData(), onMessageEnd(), payloadNumBytes, payloadNumBytesLeft, payloadTotalRead, readFrameData(), and reset().

Referenced by receive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ receive()

std::size_t web::websocket::Receiver::receive ( )

Definition at line 67 of file Receiver.cpp.

67 {
68 std::size_t ret = 0;
69 std::size_t consumed = 0;
70
71 // dumpFrame(chunk, chunkLen);
72
73 do {
74 switch (parserState) {
77 [[fallthrough]];
79 ret = readOpcode();
80 break;
82 ret = readLength();
83 break;
85 ret = readELength();
86 break;
88 ret = readMaskingKey();
89 break;
91 ret = readPayload();
92 break;
95 reset();
96 break;
97 }
98 consumed += ret;
100
101 return consumed;
102 }
std::size_t readLength()
Definition Receiver.cpp:138
std::size_t readMaskingKey()
Definition Receiver.cpp:242
std::size_t readELength()
Definition Receiver.cpp:216
virtual void onMessageError(uint16_t errnum)=0
std::size_t readPayload()
Definition Receiver.cpp:267
std::size_t readOpcode()
Definition Receiver.cpp:112

References BEGIN, ELENGTH, ERROR, errorState, LENGTH, MASKINGKEY, onMessageError(), OPCODE, PAYLOAD, readELength(), readLength(), readMaskingKey(), readOpcode(), readPayload(), and reset().

Referenced by web::websocket::SocketContextUpgrade< SubProtocolT, RequestT, ResponseT >::onReceivedFromPeer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reset()

void web::websocket::Receiver::reset ( )
private

Definition at line 302 of file Receiver.cpp.

302 {
304
305 fin = false;
306 continuation = false;
307 masked = false;
308
309 opCode = 0;
310
311 elengthNumBytes = 0;
313
314 payloadNumBytes = 0;
316
319
320 errorState = 0;
321 }

References BEGIN, continuation, elengthNumBytes, elengthNumBytesLeft, errorState, fin, masked, maskingKeyNumBytes, maskingKeyNumBytesLeft, opCode, payloadNumBytes, and payloadNumBytesLeft.

Referenced by readLength(), readMaskingKey(), readPayload(), and receive().

Here is the caller graph for this function:

Member Data Documentation

◆ continuation

bool web::websocket::Receiver::continuation = false
private

Definition at line 92 of file Receiver.h.

Referenced by readOpcode(), and reset().

◆ eLength2

union web::websocket::Receiver::ELength2 web::websocket::Receiver::eLength2
private

◆ eLength8

union web::websocket::Receiver::ELength8 web::websocket::Receiver::eLength8
private

◆ elengthNumBytes

uint8_t web::websocket::Receiver::elengthNumBytes = 0
private

Definition at line 111 of file Receiver.h.

Referenced by readELength(), readELength2(), readELength8(), readLength(), and reset().

◆ elengthNumBytesLeft

uint8_t web::websocket::Receiver::elengthNumBytesLeft = 0
private

Definition at line 112 of file Receiver.h.

Referenced by readELength(), readELength2(), readELength8(), readLength(), and reset().

◆ errorState

uint16_t web::websocket::Receiver::errorState = 0
private

Definition at line 120 of file Receiver.h.

Referenced by readELength(), readOpcode(), receive(), and reset().

◆ fin

bool web::websocket::Receiver::fin = false
private

Definition at line 91 of file Receiver.h.

Referenced by readLength(), readMaskingKey(), readOpcode(), readPayload(), and reset().

◆ masked

bool web::websocket::Receiver::masked = false
private

Definition at line 93 of file Receiver.h.

Referenced by readELength(), readLength(), readPayload(), and reset().

◆ maskingExpected

bool web::websocket::Receiver::maskingExpected = false
private

Definition at line 95 of file Receiver.h.

Referenced by readLength(), and Receiver().

◆ maskingKey

char web::websocket::Receiver::maskingKey[4]
private

Definition at line 99 of file Receiver.h.

Referenced by readMaskingKey(), and readPayload().

◆ maskingKeyNumBytes

uint8_t web::websocket::Receiver::maskingKeyNumBytes = 4
private

Definition at line 117 of file Receiver.h.

Referenced by readMaskingKey(), and reset().

◆ maskingKeyNumBytesLeft

uint8_t web::websocket::Receiver::maskingKeyNumBytesLeft = 4
private

Definition at line 118 of file Receiver.h.

Referenced by readMaskingKey(), and reset().

◆ opCode

uint8_t web::websocket::Receiver::opCode = 0
private

Definition at line 97 of file Receiver.h.

Referenced by readOpcode(), and reset().

◆ parserState

enum web::websocket::Receiver::ParserState web::websocket::Receiver::parserState = ParserState::BEGIN
private

◆ payloadNumBytes

uint64_t web::websocket::Receiver::payloadNumBytes = 0
private

◆ payloadNumBytesLeft

uint64_t web::websocket::Receiver::payloadNumBytesLeft = 0
private

Definition at line 115 of file Receiver.h.

Referenced by readELength2(), readELength8(), readLength(), readPayload(), and reset().

◆ payloadTotalRead

std::size_t web::websocket::Receiver::payloadTotalRead = 0
private

Definition at line 122 of file Receiver.h.

Referenced by getPayloadTotalRead(), and readPayload().


The documentation for this class was generated from the following files: