summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2018-10-31 05:11:41 +0000
committerPeter Powell <petpow@saberuk.com>2018-11-03 14:12:59 +0000
commitefdb51bc9d46283e55d95cd47398cf463b401d96 (patch)
treec7030efcadbe1293af4c0cc4a7964494309bcc9c /src
parent99af213a58946185621b3e4de01970a7c21cce93 (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.cpp31
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);
}