diff options
| author | 2021-05-24 16:59:59 +0100 | |
|---|---|---|
| committer | 2021-08-17 22:30:45 +0100 | |
| commit | 1790dacff5966212d12d88a7dc2a169d607a114d (patch) | |
| tree | 691ca35c13e0f21de3e307cad63f888bd2129aa5 /src/modules/m_websocket.cpp | |
| parent | Minor clean up of the previous commit. (diff) | |
Implement support for websocket subprotocols.
This is based on the current IRCv3 draft but using a vendored protocol.
Diffstat (limited to 'src/modules/m_websocket.cpp')
| -rw-r--r-- | src/modules/m_websocket.cpp | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/modules/m_websocket.cpp b/src/modules/m_websocket.cpp index 264e295f7..672c438e9 100644 --- a/src/modules/m_websocket.cpp +++ b/src/modules/m_websocket.cpp @@ -138,6 +138,7 @@ class WebSocketHook : public IOHookMiddle State state; time_t lastpingpong; WebSocketConfig& config; + bool sendastext; static size_t FillHeader(unsigned char* outbuf, size_t sendlength, OpCode opcode) { @@ -398,6 +399,22 @@ class WebSocketHook : public IOHookMiddle } } + std::string selectedproto; + HTTPHeaderFinder protocolheader; + if (protocolheader.Find(recvq, "Sec-WebSocket-Protocol:", 23, reqend)) + { + irc::spacesepstream protostream(protocolheader.ExtractValue(recvq)); + for (std::string proto; protostream.GetToken(proto); ) + { + bool is_text = stdalgo::string::equalsci(proto, "text.inspircd.org"); + if (stdalgo::string::equalsci(proto, "binary.inspircd.org") || is_text) + { + selectedproto = proto; + sendastext = is_text; + break; + } + } + } HTTPHeaderFinder keyheader; if (!keyheader.Find(recvq, "Sec-WebSocket-Key:", 18, reqend)) @@ -418,7 +435,10 @@ class WebSocketHook : public IOHookMiddle key.append(MagicGUID); std::string reply = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "; - reply.append(BinToBase64((*sha1)->GenerateRaw(key), NULL, '=')).append(newline).append(newline); + reply.append(BinToBase64((*sha1)->GenerateRaw(key), NULL, '=')).append(newline); + if (!selectedproto.empty()) + reply.append("Sec-WebSocket-Protocol: ").append(selectedproto).append(newline); + reply.append(newline); GetSendQ().push_back(StreamSocket::SendQueue::Element(reply)); SocketEngine::ChangeEventMask(sock, FD_ADD_TRIAL_WRITE); @@ -434,6 +454,7 @@ class WebSocketHook : public IOHookMiddle , state(STATE_HTTPREQ) , lastpingpong(0) , config(cfg) + , sendastext(cfg.sendastext) { sock->AddIOHook(this); } @@ -454,7 +475,7 @@ class WebSocketHook : public IOHookMiddle if (*chr == '\n') { // We have found an entire message. Send it in its own frame. - if (config.sendastext) + if (sendastext) { // If we send messages as text then we need to ensure they are valid UTF-8. std::string encoded; |
