diff options
author | Peter Powell <petpow@saberuk.com> | 2018-10-31 05:11:41 +0000 |
---|---|---|
committer | Peter Powell <petpow@saberuk.com> | 2018-11-03 14:12:59 +0000 |
commit | efdb51bc9d46283e55d95cd47398cf463b401d96 (patch) | |
tree | c7030efcadbe1293af4c0cc4a7964494309bcc9c /src | |
parent | 99af213a58946185621b3e4de01970a7c21cce93 (diff) |
WebSocket: send messages as text by default.
This requires all messages to be UTF-8. If you are using a UTF-8
incompatible text encoding then you can disable this by setting
<websocket:sendastext> to false.
Diffstat (limited to 'src')
-rw-r--r-- | src/modules/m_websocket.cpp | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/src/modules/m_websocket.cpp b/src/modules/m_websocket.cpp index 7458e56b6..51dada299 100644 --- a/src/modules/m_websocket.cpp +++ b/src/modules/m_websocket.cpp @@ -16,11 +16,15 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +/// $CompilerFlags: -Ivendor_directory("utfcpp") + #include "inspircd.h" #include "iohook.h" #include "modules/hash.h" +#include <utf8.h> + typedef std::vector<std::string> OriginList; static const char MagicGUID[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; @@ -31,6 +35,7 @@ class WebSocketHookProvider : public IOHookProvider { public: OriginList allowedorigins; + bool sendastext; WebSocketHookProvider(Module* mod) : IOHookProvider(mod, "websocket", IOHookProvider::IOH_UNKNOWN, true) @@ -106,6 +111,7 @@ class WebSocketHook : public IOHookMiddle State state; time_t lastpingpong; OriginList& allowedorigins; + bool& sendastext; static size_t FillHeader(unsigned char* outbuf, size_t sendlength, OpCode opcode) { @@ -358,11 +364,12 @@ class WebSocketHook : public IOHookMiddle } public: - WebSocketHook(IOHookProvider* Prov, StreamSocket* sock, OriginList& AllowedOrigins) + WebSocketHook(IOHookProvider* Prov, StreamSocket* sock, OriginList& AllowedOrigins, bool& SendAsText) : IOHookMiddle(Prov) , state(STATE_HTTPREQ) , lastpingpong(0) , allowedorigins(AllowedOrigins) + , sendastext(SendAsText) { sock->AddIOHook(this); } @@ -383,8 +390,21 @@ class WebSocketHook : public IOHookMiddle if (*chr == '\n') { // We have found an entire message. Send it in its own frame. - mysendq.push_back(PrepareSendQElem(message.length(), OP_BINARY)); - mysendq.push_back(message); + if (sendastext) + { + // If we send messages as text then we need to ensure they are valid UTF-8. + std::string encoded; + utf8::replace_invalid(message.begin(), message.end(), std::back_inserter(encoded)); + + mysendq.push_back(PrepareSendQElem(encoded.length(), OP_TEXT)); + mysendq.push_back(encoded); + } + else + { + // Otherwise, send the raw message as a binary frame. + mysendq.push_back(PrepareSendQElem(message.length(), OP_BINARY)); + mysendq.push_back(message); + } message.clear(); } else if (*chr != '\r') @@ -431,7 +451,7 @@ class WebSocketHook : public IOHookMiddle void WebSocketHookProvider::OnAccept(StreamSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) { - new WebSocketHook(this, sock, allowedorigins); + new WebSocketHook(this, sock, allowedorigins, sendastext); } class ModuleWebSocket : public Module @@ -465,6 +485,9 @@ class ModuleWebSocket : public Module allowedorigins.push_back(allow); } + + ConfigTag* tag = ServerInstance->Config->ConfValue("websocket"); + hookprov->sendastext = tag->getBool("sendastext", true); hookprov->allowedorigins.swap(allowedorigins); } |