diff --git a/module/Library/Net.cpp b/module/Library/Net.cpp index aa94b254..b56945b0 100644 --- a/module/Library/Net.cpp +++ b/module/Library/Net.cpp @@ -22,6 +22,8 @@ void InitializeNet() #endif #ifndef NO_SSL f |= MG_FEATURES_SSL; +#else + OutputMessage("Network compiled without SSL support."); #endif #ifndef NO_CGI f |= MG_FEATURES_CGI; @@ -135,6 +137,11 @@ int WebSocketClient::DataHandler(int flags, char * data, size_t data_len) noexce { LogFtl("Failed to queue web-socket data"); } + // Should we auto-close the connection + if (((flags & 0xF) == MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE) && mAutoClose.load() == true) + { + return 0; + } // Return 1 to keep the connection open return 1; } @@ -173,6 +180,7 @@ void Register_Net(HSQUIRRELVM vm) .Prop(_SC("OnClose"), &WebSocketClient::GetOnClose, &WebSocketClient::SetOnClose) .Prop(_SC("Valid"), &WebSocketClient::IsValid) .Prop(_SC("Closing"), &WebSocketClient::IsClosing) + .Prop(_SC("AutoClose"), &WebSocketClient::GetAutoClose, &WebSocketClient::SetAutoClose) // Member Methods .FmtFunc(_SC("SetTag"), &WebSocketClient::ApplyTag) .FmtFunc(_SC("SetData"), &WebSocketClient::ApplyData) diff --git a/module/Library/Net.hpp b/module/Library/Net.hpp index 49b45b36..c88b970b 100644 --- a/module/Library/Net.hpp +++ b/module/Library/Net.hpp @@ -159,6 +159,13 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient > */ std::atomic< bool > mClosed{false}; + /* -------------------------------------------------------------------------------------------- + * Whether to not keep the connection open after receiving the close event. + * Internally this event is ignored but if set to true the connection is immediatelly closed + * in the internal event handler, before the event may reach the script callback. + */ + std::atomic< bool > mAutoClose{false}; + /* -------------------------------------------------------------------------------------------- * Server host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost". */ @@ -184,7 +191,8 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient > */ WebSocketClient() : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() - , mPort(0), mSecure(false), mClosing(false), mClosed(false), mHost(), mPath(), mOrigin(), mExtensions() + , mPort(0), mSecure(false), mClosing(false), mClosed(false), mAutoClose(false) + , mHost(), mPath(), mOrigin(), mExtensions() { ChainInstance(); // Remember this instance } @@ -194,7 +202,7 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient > */ WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path) : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() - , mPort(port), mSecure(false), mClosing(false), mClosed(false) + , mPort(port), mSecure(false), mClosing(false), mClosed(false), mAutoClose(false) , mHost(host.mPtr, host.GetSize()) , mPath(path.mPtr, path.GetSize()) , mOrigin(), mExtensions() @@ -207,7 +215,7 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient > */ WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path, bool secure) : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() - , mPort(port), mSecure(secure), mClosing(false), mClosed(false) + , mPort(port), mSecure(secure), mClosing(false), mClosed(false), mAutoClose(false) , mHost(host.mPtr, host.GetSize()) , mPath(path.mPtr, path.GetSize()) , mOrigin(), mExtensions() @@ -220,7 +228,7 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient > */ WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path, bool secure, StackStrF & origin) : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() - , mPort(port), mSecure(secure), mClosing(false), mClosed(false) + , mPort(port), mSecure(secure), mClosing(false), mClosed(false), mAutoClose(false) , mHost(host.mPtr, host.GetSize()) , mPath(path.mPtr, path.GetSize()) , mOrigin(origin.mPtr, origin.GetSize()) @@ -234,7 +242,7 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient > */ WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path, bool secure, StackStrF & origin, StackStrF & ext) : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() - , mPort(port), mSecure(secure), mClosing(false), mClosed(false) + , mPort(port), mSecure(secure), mClosing(false), mClosed(false), mAutoClose(false) , mHost(host.mPtr, host.GetSize()) , mPath(path.mPtr, path.GetSize()) , mOrigin(origin.mPtr, origin.GetSize()) @@ -294,6 +302,22 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient > return mClosing.load(); } + /* -------------------------------------------------------------------------------------------- + * Retrieve whether auto-closing is enabled or not. + */ + SQMOD_NODISCARD bool GetAutoClose() const + { + return mAutoClose.load(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify whether auto-closing is enabled or not. + */ + void SetAutoClose(bool toggle) + { + mAutoClose.store(toggle); + } + /* -------------------------------------------------------------------------------------------- * Retrieve the associated user tag. */