[Libreoffice-commits] online.git: Branch 'private/Ashod/nonblocking' - net/loolnb.cpp

Michael Meeks michael.meeks at collabora.com
Thu Feb 16 18:50:10 UTC 2017


 net/loolnb.cpp |   99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 94 insertions(+), 5 deletions(-)

New commits:
commit b9d1721e46950bbfb960e9d975d616705265b293
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Feb 16 18:49:31 2017 +0000

    WS - basic handshake / upgrade and start of read framing.

diff --git a/net/loolnb.cpp b/net/loolnb.cpp
index 636a4d9..fe027fa 100644
--- a/net/loolnb.cpp
+++ b/net/loolnb.cpp
@@ -32,22 +32,25 @@ using Poco::StringTokenizer;
 
 constexpr int PortNumber = 9191;
 
+static std::string computeAccept(const std::string &key);
+
 class SimpleResponseClient : public ClientSocket
 {
     int _wsVersion;
     std::string _wsKey;
     std::string _wsProtocol;
+    std::vector<char> _wsPayload;
+    enum { HTTP, WEBSOCKET } _wsState;
 
 public:
     SimpleResponseClient(const int fd) :
         ClientSocket(fd),
-        _wsVersion(0)
+        _wsVersion(0),
+        _wsState(HTTP)
     {
     }
-    virtual void handleIncomingMessage() override
+    virtual void handleHTTP()
     {
-        std::cerr << "message had size " << _inBuffer.size() << "\n";
-
         int number = 0;
         MemoryInputStream message(&_inBuffer[0], _inBuffer.size());
         Poco::Net::HTTPRequest req;
@@ -57,6 +60,7 @@ public:
         size_t consumed = std::min(_inBuffer.size(),
                                    std::max((size_t)message.tellg(), size_t(0)));
         _inBuffer.erase(_inBuffer.begin(), _inBuffer.begin() + consumed);
+        std::cerr << "_inBuffer has " << _inBuffer.size() << " remaining\n";
 
         StringTokenizer tokens(req.getURI(), "/?");
         if (tokens.count() == 4)
@@ -93,14 +97,79 @@ public:
             oss << "HTTP/1.1 101 Switching Protocols\r\n"
                 << "Upgrade: websocket\r\n"
                 << "Connection: Upgrade\r\n"
-                << "Sec-Websocket-Accept: " << _wsKey << "\r\n"
+                << "Sec-Websocket-Accept: " << computeAccept(_wsKey) << "\r\n"
                 << "\r\n";
             std::string str = oss.str();
             _outBuffer.insert(_outBuffer.end(), str.begin(), str.end());
+            _wsState = WEBSOCKET;
         }
         else
             std::cerr << " unknown tokens " << tokens.count() << std::endl;
     }
+
+    enum WSOpCode {
+        Continuation, // 0x0
+        Text,         // 0x1
+        Binary,       // 0x2
+        Reserved1,    // 0x3
+        Reserved2,    // 0x4
+        Reserved3,    // 0x5
+        Reserved4,    // 0x6
+        Reserved5,    // 0x7
+        Close,        // 0x8
+        Ping,         // 0x9
+        Pong          // 0xa
+        // ... reserved
+    };
+
+    virtual void handleIncomingMessage() override
+    {
+        std::cerr << "incoming message with buffer size " << _inBuffer.size() << "\n";
+        if (_wsState == HTTP)
+        {
+            handleHTTP();
+            return;
+        }
+
+        // websocket fun !
+        size_t len = _inBuffer.size();
+        const char *p = &_inBuffer[0];
+        if (len < 2) // partial read
+            return;
+
+        bool fin = *p & 0x80;
+        WSOpCode code = static_cast<WSOpCode>(*p & 0x0f);
+        p++;
+        bool mask = *p & 0x80;
+        size_t payloadLen = *p & 0x7f;
+        p++;
+
+        if (payloadLen == 126) // 2 byte length
+        {
+            if (len < 2 + 2)
+                return;
+            std::cerr << "Implement me 2 byte\n";
+        }
+        else if (payloadLen == 127) // 8 byte length
+        {
+            if (len < 2 + 8)
+                return;
+            std::cerr << "Implement me 8 byte\n";
+        }
+        else
+        {
+            _wsPayload.insert(_wsPayload.end(), p, p + std::min(payloadLen, len));
+        }
+        // FIXME: fin, aggregating payloads into _wsPayload etc.
+        handleWSMessage(fin, code, mask, _wsPayload);
+        _wsPayload.clear();
+    }
+
+    virtual void handleWSMessage( bool fin, WSOpCode code, bool mask, std::vector<char> &data)
+    {
+        std::cerr << "Message: fin? " << fin << " code " << code << " mask? " << mask << " data size " << data.size() << "\n";
+    }
+
 };
 
 // FIXME: use Poco Thread instead (?)
@@ -260,4 +329,24 @@ int main(int, const char**)
     return 0;
 }
 
+// Saves writing this ourselves:
+
+#include <Poco/Net/WebSocket.h>
+
+namespace {
+#include <Poco/Net/WebSocket.h>
+    struct Puncture : private Poco::Net::WebSocket {
+        static std::string doComputeAccept(const std::string &key)
+        {
+            return computeAccept(key);
+        }
+    };
+}
+
+static std::string computeAccept(const std::string &key)
+{
+    return Puncture::doComputeAccept(key);
+}
+
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list