fix close code/reason issue (#34)

* fix close code/reason issue

* added code 1006 for abnormal closure
This commit is contained in:
Kumamon38 2019-04-18 19:02:31 +02:00 committed by Benjamin Sergeant
parent d7595b0dd0
commit e3d0c899d3
2 changed files with 36 additions and 7 deletions

View File

@ -69,11 +69,16 @@ namespace ix
const int WebSocketTransport::kDefaultPingTimeoutSecs(-1); const int WebSocketTransport::kDefaultPingTimeoutSecs(-1);
const bool WebSocketTransport::kDefaultEnablePong(true); const bool WebSocketTransport::kDefaultEnablePong(true);
constexpr size_t WebSocketTransport::kChunkSize; constexpr size_t WebSocketTransport::kChunkSize;
const int WebSocketTransport::kInternalErrorCode(1011);
const int WebSocketTransport::kAbnormalCloseCode(1006);
const std::string WebSocketTransport::kInternalErrorMessage("Internal error");
const std::string WebSocketTransport::kAbnormalCloseMessage("Abnormal closure");
WebSocketTransport::WebSocketTransport() : WebSocketTransport::WebSocketTransport() :
_useMask(true), _useMask(true),
_readyState(CLOSED), _readyState(CLOSED),
_closeCode(0), _closeCode(kInternalErrorCode),
_closeReason(kInternalErrorMessage),
_closeWireSize(0), _closeWireSize(0),
_enablePerMessageDeflate(false), _enablePerMessageDeflate(false),
_requestInitCancellation(false), _requestInitCancellation(false),
@ -190,8 +195,8 @@ namespace ix
{ {
std::lock_guard<std::mutex> lock(_closeDataMutex); std::lock_guard<std::mutex> lock(_closeDataMutex);
_onCloseCallback(_closeCode, _closeReason, _closeWireSize); _onCloseCallback(_closeCode, _closeReason, _closeWireSize);
_closeCode = 0; _closeCode = kInternalErrorCode;
_closeReason = std::string(); _closeReason = kInternalErrorMessage;
_closeWireSize = 0; _closeWireSize = 0;
} }
@ -284,6 +289,12 @@ namespace ix
{ {
_rxbuf.clear(); _rxbuf.clear();
_socket->close(); _socket->close();
{
std::lock_guard<std::mutex> lock(_closeDataMutex);
_closeCode = kAbnormalCloseCode;
_closeReason = kAbnormalCloseMessage;
_closeWireSize = 0;
}
setReadyState(CLOSED); setReadyState(CLOSED);
break; break;
} }
@ -526,8 +537,7 @@ namespace ix
// Get the reason. // Get the reason.
std::string reason(_rxbuf.begin()+ws.header_size + 2, std::string reason(_rxbuf.begin()+ws.header_size + 2,
_rxbuf.begin()+ws.header_size + 2 + (size_t) ws.N); _rxbuf.begin()+ws.header_size + (size_t) ws.N);
close(code, reason, _rxbuf.size()); close(code, reason, _rxbuf.size());
} }
@ -843,7 +853,13 @@ namespace ix
// See list of close events here: // See list of close events here:
// https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent // https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
const std::string closure{(char)(code >> 8), (char)(code & 0xff)};
int codeLength = 2;
std::string closure{(char)(code >> 8), (char)(code & 0xff)};
closure.resize(codeLength + reason.size());
// copy reason after code
closure.replace(codeLength, reason.size(), reason);
bool compress = false; bool compress = false;
sendData(wsheader_type::CLOSE, closure, compress); sendData(wsheader_type::CLOSE, closure, compress);

View File

@ -159,23 +159,36 @@ namespace ix
// Used to cancel dns lookup + socket connect + http upgrade // Used to cancel dns lookup + socket connect + http upgrade
std::atomic<bool> _requestInitCancellation; std::atomic<bool> _requestInitCancellation;
// Constants for dealing with closing conneections
static const int kInternalErrorCode;
static const int kAbnormalCloseCode;
const static std::string kInternalErrorMessage;
const static std::string kAbnormalCloseMessage;
// enable auto response to ping // enable auto response to ping
bool _enablePong; bool _enablePong;
static const bool kDefaultEnablePong; static const bool kDefaultEnablePong;
// Optional ping and ping timeout // Optional ping and pong timeout
int _pingIntervalSecs; int _pingIntervalSecs;
int _pingTimeoutSecs; int _pingTimeoutSecs;
int _pingIntervalOrTimeoutGCDSecs; // if both ping interval and timeout are set (> 0), then use GCD of these value to wait for the lowest time int _pingIntervalOrTimeoutGCDSecs; // if both ping interval and timeout are set (> 0), then use GCD of these value to wait for the lowest time
static const int kDefaultPingIntervalSecs; static const int kDefaultPingIntervalSecs;
static const int kDefaultPingTimeoutSecs; static const int kDefaultPingTimeoutSecs;
const static std::string kPingMessage; const static std::string kPingMessage;
// We record when ping are being sent so that we can know when to send the next one, periodically
// We also record when pong are being sent as a reply to pings, to close the connections
// if no pong were received sufficiently fast.
mutable std::mutex _lastSendPingTimePointMutex; mutable std::mutex _lastSendPingTimePointMutex;
mutable std::mutex _lastReceivePongTimePointMutex; mutable std::mutex _lastReceivePongTimePointMutex;
std::chrono::time_point<std::chrono::steady_clock> _lastSendPingTimePoint; std::chrono::time_point<std::chrono::steady_clock> _lastSendPingTimePoint;
std::chrono::time_point<std::chrono::steady_clock> _lastReceivePongTimePoint; std::chrono::time_point<std::chrono::steady_clock> _lastReceivePongTimePoint;
// If this function returns true, it is time to send a new ping
bool pingIntervalExceeded(); bool pingIntervalExceeded();
// No PONG data was received through the socket for longer than ping timeout delay // No PONG data was received through the socket for longer than ping timeout delay
bool pingTimeoutExceeded(); bool pingTimeoutExceeded();