[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-3' - kit/Kit.cpp net/WebSocketHandler.hpp

Michael Meeks michael.meeks at collabora.com
Mon Jun 18 10:50:20 UTC 2018


 kit/Kit.cpp              |    2 -
 net/WebSocketHandler.hpp |   49 +++++++++++++++++++++++++++++++++++------------
 2 files changed, 38 insertions(+), 13 deletions(-)

New commits:
commit 58f05039f5efd2cc2c4d890662c628be7ac9d74f
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Jun 15 14:18:31 2018 +0100

    Implement client websocket masking.
    
    Disable this for easy strace debugging and a bit of perf. to the forkit.
    
    Change-Id: Ia330582817481410d26df50db5eb42b4692ad01c
    Reviewed-on: https://gerrit.libreoffice.org/55870
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>
    Tested-by: Jan Holesovsky <kendy at collabora.com>

diff --git a/kit/Kit.cpp b/kit/Kit.cpp
index 83becc634..b688e760d 100644
--- a/kit/Kit.cpp
+++ b/kit/Kit.cpp
@@ -1953,7 +1953,7 @@ class KitWebSocketHandler final : public WebSocketHandler, public std::enable_sh
 
 public:
     KitWebSocketHandler(const std::string& socketName, const std::shared_ptr<lok::Office>& loKit, const std::string& jailId, SocketPoll& socketPoll) :
-        WebSocketHandler(/* isClient = */ true),
+        WebSocketHandler(/* isClient = */ true, /* isMasking */ false),
         _queue(std::make_shared<TileQueue>()),
         _socketName(socketName),
         _loKit(loKit),
diff --git a/net/WebSocketHandler.hpp b/net/WebSocketHandler.hpp
index 1294a51ec..2ec2ed973 100644
--- a/net/WebSocketHandler.hpp
+++ b/net/WebSocketHandler.hpp
@@ -36,6 +36,7 @@ protected:
     std::vector<char> _wsPayload;
     std::atomic<bool> _shuttingDown;
     bool _isClient;
+    bool _isMasking;
 
     struct WSFrameMask
     {
@@ -48,11 +49,12 @@ protected:
 
 public:
     /// Perform upgrade ourselves, or select a client web socket.
-    WebSocketHandler(bool isClient = false) :
+    WebSocketHandler(bool isClient = false, bool isMasking = true) :
         _lastPingSentTime(std::chrono::steady_clock::now()),
         _pingTimeUs(0),
         _shuttingDown(false),
-        _isClient(isClient)
+        _isClient(isClient),
+        _isMasking(isClient && isMasking)
     {
     }
 
@@ -65,7 +67,8 @@ public:
                   std::chrono::milliseconds(InitialPingDelayMs)),
         _pingTimeUs(0),
         _shuttingDown(false),
-        _isClient(false)
+        _isClient(false),
+        _isMasking(false)
     {
         upgradeToWebSocket(request);
     }
@@ -381,14 +384,14 @@ public:
         return sendFrame(socket, data, len, WSFrameMask::Fin | static_cast<unsigned char>(code), flush);
     }
 
-protected:
+private:
 
     /// Sends a WebSocket frame given the data, length, and flags.
     /// Returns the number of bytes written (including frame overhead) on success,
     /// 0 for closed/invalid socket, and -1 for other errors.
-    static int sendFrame(const std::shared_ptr<StreamSocket>& socket,
-                         const char* data, const size_t len,
-                         const unsigned char flags, const bool flush = true)
+    int sendFrame(const std::shared_ptr<StreamSocket>& socket,
+                  const char* data, const size_t len,
+                  unsigned char flags, const bool flush = true) const
     {
         if (!socket || data == nullptr || len == 0)
             return -1;
@@ -402,19 +405,20 @@ protected:
 
         out.push_back(flags);
 
+        int maskFlag = _isMasking ? 0x80 : 0;
         if (len < 126)
         {
-            out.push_back((char)len);
+            out.push_back((char)(len | maskFlag));
         }
         else if (len <= 0xffff)
         {
-            out.push_back((char)126);
+            out.push_back((char)(126 | maskFlag));
             out.push_back(static_cast<char>((len >> 8) & 0xff));
             out.push_back(static_cast<char>((len >> 0) & 0xff));
         }
         else
         {
-            out.push_back((char)127);
+            out.push_back((char)(127 | maskFlag));
             out.push_back(static_cast<char>((len >> 56) & 0xff));
             out.push_back(static_cast<char>((len >> 48) & 0xff));
             out.push_back(static_cast<char>((len >> 40) & 0xff));
@@ -425,8 +429,27 @@ protected:
             out.push_back(static_cast<char>((len >> 0) & 0xff));
         }
 
-        // Copy the data.
-        out.insert(out.end(), data, data + len);
+        if (_isMasking)
+        { // flip some top bits - perhaps it helps.
+            size_t mask = out.size();
+
+            out.push_back(static_cast<char>(0x81));
+            out.push_back(static_cast<char>(0x76));
+            out.push_back(static_cast<char>(0x81));
+            out.push_back(static_cast<char>(0x76));
+
+            // Copy the data.
+            out.insert(out.end(), data, data + len);
+
+            // Mask it.
+            for (size_t i = 4; i < out.size() - mask; ++i)
+                out[mask + i] = out[mask + i] ^ out[mask + (i%4)];
+        }
+        else
+        {
+            // Copy the data.
+            out.insert(out.end(), data, data + len);
+        }
         const size_t size = out.size() - oldSize;
 
         if (flush)
@@ -435,6 +458,8 @@ protected:
         return size;
     }
 
+protected:
+
     /// To be overriden to handle the websocket messages the way you need.
     virtual void handleMessage(bool /*fin*/, WSOpCode /*code*/, std::vector<char> &/*data*/)
     {


More information about the Libreoffice-commits mailing list