diff --git a/ixwebsocket/IXWebSocket.cpp b/ixwebsocket/IXWebSocket.cpp index e6759abd..34109feb 100644 --- a/ixwebsocket/IXWebSocket.cpp +++ b/ixwebsocket/IXWebSocket.cpp @@ -45,11 +45,11 @@ namespace ix _pingTimeoutSecs(kDefaultPingTimeoutSecs) { _ws.setOnCloseCallback( - [this](uint16_t code, const std::string& reason, size_t wireSize) + [this](uint16_t code, const std::string& reason, size_t wireSize, bool remote) { _onMessageCallback(WebSocket_MessageType_Close, "", wireSize, WebSocketErrorInfo(), WebSocketOpenInfo(), - WebSocketCloseInfo(code, reason)); + WebSocketCloseInfo(code, reason, remote)); } ); } diff --git a/ixwebsocket/IXWebSocket.h b/ixwebsocket/IXWebSocket.h index 2b374a31..8c6bf702 100644 --- a/ixwebsocket/IXWebSocket.h +++ b/ixwebsocket/IXWebSocket.h @@ -61,11 +61,14 @@ namespace ix { uint16_t code; std::string reason; + bool remote; WebSocketCloseInfo(uint16_t c = 0, - const std::string& r = std::string()) + const std::string& r = std::string(), + bool rem = false) : code(c) , reason(r) + , remote(rem) { ; } diff --git a/ixwebsocket/IXWebSocketTransport.cpp b/ixwebsocket/IXWebSocketTransport.cpp index 7bb78311..a8853a90 100644 --- a/ixwebsocket/IXWebSocketTransport.cpp +++ b/ixwebsocket/IXWebSocketTransport.cpp @@ -71,9 +71,11 @@ namespace ix constexpr size_t WebSocketTransport::kChunkSize; const uint16_t WebSocketTransport::kInternalErrorCode(1011); const uint16_t WebSocketTransport::kAbnormalCloseCode(1006); + const uint16_t WebSocketTransport::kProtocolErrorCode(1002); const std::string WebSocketTransport::kInternalErrorMessage("Internal error"); const std::string WebSocketTransport::kAbnormalCloseMessage("Abnormal closure"); const std::string WebSocketTransport::kPingTimeoutMessage("Ping timeout"); + const std::string WebSocketTransport::kProtocolErrorMessage("Protocol error"); WebSocketTransport::WebSocketTransport() : _useMask(true), @@ -81,6 +83,7 @@ namespace ix _closeCode(kInternalErrorCode), _closeReason(kInternalErrorMessage), _closeWireSize(0), + _closeRemote(false), _enablePerMessageDeflate(false), _requestInitCancellation(false), _enablePong(kDefaultEnablePong), @@ -203,10 +206,11 @@ namespace ix if (readyStateValue == CLOSED) { std::lock_guard lock(_closeDataMutex); - _onCloseCallback(_closeCode, _closeReason, _closeWireSize); + _onCloseCallback(_closeCode, _closeReason, _closeWireSize, _closeRemote); _closeCode = kInternalErrorCode; _closeReason = kInternalErrorMessage; _closeWireSize = 0; + _closeRemote = false; } _readyState = readyStateValue; @@ -302,6 +306,7 @@ namespace ix _closeCode = kAbnormalCloseCode; _closeReason = kAbnormalCloseMessage; _closeWireSize = 0; + _closeRemote = true; } setReadyState(CLOSED); break; @@ -544,12 +549,16 @@ namespace ix // Get the reason. std::string reason(_rxbuf.begin()+ws.header_size + 2, _rxbuf.begin()+ws.header_size + (size_t) ws.N); + + bool remote = true; - close(code, reason, _rxbuf.size()); + close(code, reason, _rxbuf.size(), remote); } else { - close(); + // Unexpected frame type + + close(kProtocolErrorCode, kProtocolErrorMessage, _rxbuf.size()); } // Erase the message that has been processed from the input/read buffer @@ -850,7 +859,7 @@ namespace ix } } - void WebSocketTransport::close(uint16_t code, const std::string& reason, size_t closeWireSize) + void WebSocketTransport::close(uint16_t code, const std::string& reason, size_t closeWireSize, bool remote) { _requestInitCancellation = true; @@ -878,6 +887,7 @@ namespace ix _closeCode = code; _closeReason = reason; _closeWireSize = closeWireSize; + _closeRemote = remote; } setReadyState(CLOSED); diff --git a/ixwebsocket/IXWebSocketTransport.h b/ixwebsocket/IXWebSocketTransport.h index 2dbb0e2e..bf93adc8 100644 --- a/ixwebsocket/IXWebSocketTransport.h +++ b/ixwebsocket/IXWebSocketTransport.h @@ -62,7 +62,8 @@ namespace ix MessageKind)>; using OnCloseCallback = std::function; + size_t, + bool)>; WebSocketTransport(); ~WebSocketTransport(); @@ -86,7 +87,8 @@ namespace ix void close(uint16_t code = 1000, const std::string& reason = "Normal closure", - size_t closeWireSize = 0); + size_t closeWireSize = 0, + bool remote = false); ReadyStateValues getReadyState() const; void setReadyState(ReadyStateValues readyStateValue); @@ -150,6 +152,7 @@ namespace ix uint16_t _closeCode; std::string _closeReason; size_t _closeWireSize; + bool _closeRemote; mutable std::mutex _closeDataMutex; // Data used for Per Message Deflate compression (with zlib) @@ -163,9 +166,11 @@ namespace ix // Constants for dealing with closing conneections static const uint16_t kInternalErrorCode; static const uint16_t kAbnormalCloseCode; + static const uint16_t kProtocolErrorCode; static const std::string kInternalErrorMessage; static const std::string kAbnormalCloseMessage; static const std::string kPingTimeoutMessage; + static const std::string kProtocolErrorMessage; // enable auto response to ping bool _enablePong;