@@ -32,7 +32,7 @@ namespace SL {
3232 else if (secs.count () > 0 ) {
3333 socket->read_deadline .async_wait ([parent, socket](const std::error_code& ec) {
3434 if (ec != asio::error::operation_aborted) {
35- return closeImpl (parent, socket, 1001 , " read timer expired on the socket " );
35+ return sendclosemessage (parent, socket, 1001 , " read timer expired on the socket " );
3636 }
3737 });
3838 }
@@ -54,7 +54,7 @@ namespace SL {
5454 else if (secs.count () > 0 ) {
5555 socket->write_deadline .async_wait ([parent, socket](const std::error_code& ec) {
5656 if (ec != asio::error::operation_aborted) {
57- return closeImpl (parent, socket, 1001 , " write timer expired on the socket " );
57+ return sendclosemessage (parent, socket, 1001 , " write timer expired on the socket " );
5858 }
5959 });
6060 }
@@ -86,7 +86,7 @@ namespace SL {
8686 socket->SendMessageQueue .emplace_back (SendQueueItem{ msg, compressmessage });
8787 if (socket->SendMessageQueue .size () == 1 ) {
8888 SL::WS_LITE::startwrite (parent, socket);
89- }
89+ }
9090 // update the socket status to reflect it is closing to prevent other messages from being sent.. this is the last valid message
9191 // make sure to do this after a call to startwrite so the write process sends the close message, but no others
9292 if (msg.code == OpCode::CLOSE) {
@@ -95,7 +95,7 @@ namespace SL {
9595 }
9696 });
9797 }
98- template <class PARENTTYPE , class SOCKETTYPE >void closeImpl (const PARENTTYPE& parent, const SOCKETTYPE& socket, unsigned short code, const std::string& msg) {
98+ template <class PARENTTYPE , class SOCKETTYPE >void sendclosemessage (const PARENTTYPE& parent, const SOCKETTYPE& socket, unsigned short code, const std::string& msg) {
9999 SL_WS_LITE_LOG (Logging_Levels::INFO_log_level, " closeImpl " << msg);
100100 WSMessage ws;
101101 ws.code = OpCode::CLOSE;
@@ -107,6 +107,9 @@ namespace SL {
107107 sendImpl (parent, socket, ws, false );
108108 }
109109
110+
111+
112+
110113
111114 template <class PARENTTYPE , class SOCKETTYPE , class SENDBUFFERTYPE >inline void handleclose (const PARENTTYPE& parent, const SOCKETTYPE& socket, const SENDBUFFERTYPE& msg) {
112115 SL_WS_LITE_LOG (Logging_Levels::INFO_log_level, " Closed: " << msg.code );
@@ -119,6 +122,16 @@ namespace SL {
119122 socket->Socket .lowest_layer ().shutdown (asio::ip::tcp::socket::shutdown_both, ec);
120123 ec.clear ();
121124 socket->Socket .lowest_layer ().close (ec);
125+ }
126+
127+ template <class PARENTTYPE , class SOCKETTYPE , class SENDBUFFERTYPE >void closeImpl (const PARENTTYPE& parent, const SOCKETTYPE& socket, unsigned short code, const std::string& msg, const SENDBUFFERTYPE& networkmsg) {
128+ if (networkmsg.code == OpCode::CLOSE) {
129+ // failed when sending a close message... get out and notify
130+ handleclose (parent, socket, networkmsg);
131+ }
132+ else {
133+ sendclosemessage (parent, socket, code, msg);
134+ }
122135 }
123136 template <class PARENTTYPE , class SOCKETTYPE , class SENDBUFFERTYPE >inline void write_end (const PARENTTYPE& parent, const SOCKETTYPE& socket, const SENDBUFFERTYPE& msg) {
124137
@@ -129,7 +142,7 @@ namespace SL {
129142 UNUSED (bytes_transferred);
130143 if (ec)
131144 {
132- return closeImpl (parent, socket, 1002 , " write header failed " + ec.message ());
145+ return closeImpl (parent, socket, 1002 , " write header failed " + ec.message (), msg );
133146 }
134147 assert (msg.len == bytes_transferred);
135148 if (msg.code == OpCode::CLOSE) {
@@ -161,7 +174,7 @@ namespace SL {
161174 handleclose (parent, socket, msg);
162175 }
163176 else {
164- return closeImpl (parent, socket, 1002 , " write mask failed " + ec.message ());
177+ return closeImpl (parent, socket, 1002 , " write mask failed " + ec.message (), msg );
165178 }
166179 }
167180 else {
@@ -212,7 +225,7 @@ namespace SL {
212225 writeend (parent, socket, msg);
213226 }
214227 else {
215- return closeImpl (parent, socket, 1002 , " write header failed " + ec.message ());
228+ return closeImpl (parent, socket, 1002 , " write header failed " + ec.message (), msg );
216229 }
217230
218231 }
@@ -237,26 +250,26 @@ namespace SL {
237250 if (!getFin (socket->ReceiveHeader )) {
238251 if (socket->LastOpCode == OpCode::INVALID) {
239252 if (opcode != OpCode::BINARY && opcode != OpCode::TEXT) {
240- return closeImpl (parent, socket, 1002 , " First Non Fin Frame must be binary or text" );
253+ return sendclosemessage (parent, socket, 1002 , " First Non Fin Frame must be binary or text" );
241254 }
242255 socket->LastOpCode = opcode;
243256 }
244257 else if (opcode != OpCode::CONTINUATION) {
245- return closeImpl (parent, socket, 1002 , " Continuation Received without a previous frame" );
258+ return sendclosemessage (parent, socket, 1002 , " Continuation Received without a previous frame" );
246259 }
247260 ReadHeaderNext (parent, socket);
248261 }
249262 else {
250263
251264 if (socket->LastOpCode != OpCode::INVALID && opcode != OpCode::CONTINUATION) {
252- return closeImpl (parent, socket, 1002 , " Continuation Received without a previous frame" );
265+ return sendclosemessage (parent, socket, 1002 , " Continuation Received without a previous frame" );
253266 }
254267 else if (socket->LastOpCode == OpCode::INVALID && opcode == OpCode::CONTINUATION) {
255- return closeImpl (parent, socket, 1002 , " Continuation Received without a previous frame" );
268+ return sendclosemessage (parent, socket, 1002 , " Continuation Received without a previous frame" );
256269 }
257270 else if (socket->LastOpCode == OpCode::TEXT || opcode == OpCode::TEXT) {
258271 if (!isValidUtf8 (socket->ReceiveBuffer , socket->ReceiveBufferSize )) {
259- return closeImpl (parent, socket, 1007 , " Frame not valid utf8" );
272+ return sendclosemessage (parent, socket, 1007 , " Frame not valid utf8" );
260273 }
261274 }
262275 if (parent->onMessage ) {
@@ -280,26 +293,26 @@ namespace SL {
280293 auto closecode = hton (*reinterpret_cast <unsigned short *>(buffer.get ()));
281294 if (size > 2 ) {
282295 if (!isValidUtf8 (buffer.get () + sizeof (closecode), size - sizeof (closecode))) {
283- return closeImpl (parent, socket, 1007 , " Frame not valid utf8" );
296+ return sendclosemessage (parent, socket, 1007 , " Frame not valid utf8" );
284297 }
285298 }
286299
287300 if (((closecode >= 1000 && closecode <= 1011 ) || (closecode >= 3000 && closecode <= 4999 )) && closecode != 1004 && closecode != 1005 && closecode != 1006 ) {
288- return closeImpl (parent, socket, 1000 , " " );
301+ return sendclosemessage (parent, socket, 1000 , " " );
289302 }
290303 else
291304 {
292- return closeImpl (parent, socket, 1002 , " " );
305+ return sendclosemessage (parent, socket, 1002 , " " );
293306 }
294307 }
295308 else if (size != 0 ) {
296- return closeImpl (parent, socket, 1002 , " " );
309+ return sendclosemessage (parent, socket, 1002 , " " );
297310 }
298- return closeImpl (parent, socket, 1000 , " " );
311+ return sendclosemessage (parent, socket, 1000 , " " );
299312 }
300313 template <class PARENTTYPE , class SOCKETTYPE >inline void ProcessControlMessage (const PARENTTYPE& parent, const SOCKETTYPE& socket, const std::shared_ptr<unsigned char >& buffer, size_t size) {
301314 if (!getFin (socket->ReceiveHeader )) {
302- return closeImpl (parent, socket, 1002 , " Closing connection. Control Frames must be Fin" );
315+ return sendclosemessage (parent, socket, 1002 , " Closing connection. Control Frames must be Fin" );
303316 }
304317 auto opcode = getOpCode (socket->ReceiveHeader );
305318
@@ -321,19 +334,19 @@ namespace SL {
321334 return ProcessClose (parent, socket, buffer, size);
322335
323336 default :
324- return closeImpl (parent, socket, 1002 , " Closing connection. nonvalid op code" );
337+ return sendclosemessage (parent, socket, 1002 , " Closing connection. nonvalid op code" );
325338 }
326339 ReadHeaderNext (parent, socket);
327340
328341 }
329342 template <class PARENTTYPE , class SOCKETTYPE >inline void ReadBody (const PARENTTYPE& parent, const SOCKETTYPE& socket) {
330343
331344 if (!DidPassMaskRequirement<PARENTTYPE>(socket->ReceiveHeader )) {// Close connection if it did not meet the mask requirement.
332- return closeImpl (parent, socket, 1002 , " Closing connection because mask requirement not met" );
345+ return sendclosemessage (parent, socket, 1002 , " Closing connection because mask requirement not met" );
333346 }
334347
335348 if (getrsv2 (socket->ReceiveHeader ) || getrsv3 (socket->ReceiveHeader ) || (getrsv1 (socket->ReceiveHeader ) && !socket->CompressionEnabled )) {
336- return closeImpl (parent, socket, 1002 , " Closing connection. rsv bit set" );
349+ return sendclosemessage (parent, socket, 1002 , " Closing connection. rsv bit set" );
337350 }
338351
339352 auto opcode = getOpCode (socket->ReceiveHeader );
@@ -346,7 +359,7 @@ namespace SL {
346359 case 127 :
347360 size = static_cast <size_t >(ntoh (getpayloadLength8 (socket->ReceiveHeader )));
348361 if (size > std::numeric_limits<std::size_t >::max ()) {
349- return closeImpl (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
362+ return sendclosemessage (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
350363 }
351364 break ;
352365 default :
@@ -356,23 +369,23 @@ namespace SL {
356369 size += AdditionalBodyBytesToRead<PARENTTYPE>();
357370 if (opcode == OpCode::PING || opcode == OpCode::PONG || opcode == OpCode::CLOSE) {
358371 if (size - AdditionalBodyBytesToRead<PARENTTYPE>() > CONTROLBUFFERMAXSIZE) {
359- return closeImpl (parent, socket, 1002 , " Payload exceeded for control frames. Size requested " + std::to_string (size));
372+ return sendclosemessage (parent, socket, 1002 , " Payload exceeded for control frames. Size requested " + std::to_string (size));
360373 }
361374 else if (size > 0 ) {
362375 auto buffer = std::shared_ptr<unsigned char >(new unsigned char [size], [](auto p) { delete[] p; });
363376 asio::async_read (socket->Socket , asio::buffer (buffer.get (), size), [parent, socket, buffer, size](const std::error_code& ec, size_t bytes_transferred) {
364377
365378 if (!ec || bytes_transferred != size) {
366379 if (size != bytes_transferred) {
367- return closeImpl (parent, socket, 1002 , " Did not receive all bytes ... " );
380+ return sendclosemessage (parent, socket, 1002 , " Did not receive all bytes ... " );
368381 }
369382 UnMaskMessage (parent, size, buffer.get ());
370383
371384 auto tempsize = size - AdditionalBodyBytesToRead<PARENTTYPE>();
372385 ProcessControlMessage (parent, socket, buffer, tempsize);
373386 }
374387 else {
375- return closeImpl (parent, socket, 1002 , " ReadBody Error " + ec.message ());
388+ return sendclosemessage (parent, socket, 1002 , " ReadBody Error " + ec.message ());
376389 }
377390 });
378391 }
@@ -386,37 +399,37 @@ namespace SL {
386399 auto addedsize = socket->ReceiveBufferSize + size;
387400 if (addedsize > std::numeric_limits<std::size_t >::max ()) {
388401 SL_WS_LITE_LOG (Logging_Levels::ERROR_log_level, " payload exceeds memory on system!!! " );
389- return closeImpl (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
402+ return sendclosemessage (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
390403 }
391404 socket->ReceiveBufferSize = addedsize;
392405
393406 if (socket->ReceiveBufferSize > parent->MaxPayload ) {
394- return closeImpl (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
407+ return sendclosemessage (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
395408 }
396409 if (socket->ReceiveBufferSize > std::numeric_limits<std::size_t >::max ()) {
397410 SL_WS_LITE_LOG (Logging_Levels::ERROR_log_level, " payload exceeds memory on system!!! " );
398- return closeImpl (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
411+ return sendclosemessage (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
399412 }
400413
401414 if (size > 0 ) {
402415 socket->ReceiveBuffer = static_cast <unsigned char *>(realloc (socket->ReceiveBuffer , socket->ReceiveBufferSize ));
403416 if (!socket->ReceiveBuffer ) {
404417 SL_WS_LITE_LOG (Logging_Levels::ERROR_log_level, " MEMORY ALLOCATION ERROR!!! Tried to realloc " << socket->ReceiveBufferSize );
405- return closeImpl (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
418+ return sendclosemessage (parent, socket, 1009 , " Payload exceeded MaxPayload size" );
406419 }
407420 asio::async_read (socket->Socket , asio::buffer (socket->ReceiveBuffer + socket->ReceiveBufferSize - size, size), [parent, socket, size](const std::error_code& ec, size_t bytes_transferred) {
408421
409422 if (!ec || bytes_transferred != size) {
410423 if (size != bytes_transferred) {
411- return closeImpl (parent, socket, 1002 , " Did not receive all bytes ... " );
424+ return sendclosemessage (parent, socket, 1002 , " Did not receive all bytes ... " );
412425 }
413426 auto buffer = socket->ReceiveBuffer + socket->ReceiveBufferSize - size;
414427 UnMaskMessage (parent, size, buffer);
415428 socket->ReceiveBufferSize -= AdditionalBodyBytesToRead<PARENTTYPE>();
416429 ProcessMessage (parent, socket);
417430 }
418431 else {
419- return closeImpl (parent, socket, 1002 , " ReadBody Error " + ec.message ());
432+ return sendclosemessage (parent, socket, 1002 , " ReadBody Error " + ec.message ());
420433 }
421434 });
422435 }
@@ -425,7 +438,7 @@ namespace SL {
425438 }
426439 }
427440 else {
428- return closeImpl (parent, socket, 1002 , " Closing connection. nonvalid op code" );
441+ return sendclosemessage (parent, socket, 1002 , " Closing connection. nonvalid op code" );
429442 }
430443
431444 }
@@ -460,7 +473,7 @@ namespace SL {
460473 ReadBody (parent, socket);
461474 }
462475 else {
463- return closeImpl (parent, socket, 1002 , " readheader ExtendedPayloadlen " + ec.message ());
476+ return sendclosemessage (parent, socket, 1002 , " readheader ExtendedPayloadlen " + ec.message ());
464477 }
465478 });
466479 }
@@ -470,7 +483,7 @@ namespace SL {
470483
471484 }
472485 else {
473- return closeImpl (parent, socket, 1002 , " WebSocket ReadHeader failed " + ec.message ());
486+ return sendclosemessage (parent, socket, 1002 , " WebSocket ReadHeader failed " + ec.message ());
474487 }
475488 });
476489 }
0 commit comments