Skip to content

Commit 7db8c73

Browse files
committed
fixing error when sending close and an error occurs
1 parent 21bc731 commit 7db8c73

File tree

3 files changed

+49
-39
lines changed

3 files changed

+49
-39
lines changed

include/internal/DataStructures.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ namespace SL {
156156
if (SocketStatus_ == SocketStatus::CONNECTED) {//only send a close to an open socket
157157
auto self(std::static_pointer_cast<WSocket<SOCKETTYPE, PARENTTYPE>>(shared_from_this()));
158158
auto p(Parent);
159-
if (p) closeImpl(p, self, code, msg);
159+
if (p) sendclosemessage(p, self, code, msg);
160160
}
161161
}
162162

include/internal/WebSocketProtocol.h

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/internal/ClientImpl.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,7 @@ namespace SL {
7272
socket->SocketStatus_ = SocketStatus::CONNECTED;
7373
if (self->onConnection) {
7474
self->onConnection(socket, header);
75-
}/*
76-
if (read_buffer->size() > bytes_transferred) {
77-
SL_WS_LITE_LOG(Logging_Levels::INFO_log_level, "Read Extra Data " << read_buffer->size() - bytes_transferred);
78-
}*/
75+
}
7976
ReadHeaderStart(self, socket);
8077
}
8178
else {

0 commit comments

Comments
 (0)