[Libreoffice-commits] online.git: loolwsd/LOOLWSD.cpp loolwsd/test

Henry Castro hcastro at collabora.com
Wed Apr 13 18:45:46 UTC 2016


 loolwsd/LOOLWSD.cpp         |   21 +++++++++---
 loolwsd/test/httpwstest.cpp |   72 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 86 insertions(+), 7 deletions(-)

New commits:
commit 096f7db6d06ca2c66d7b69970853b83b03b3d914
Author: Henry Castro <hcastro at collabora.com>
Date:   Wed Apr 13 14:22:56 2016 -0400

    loolwsd: report indicator status before websocket is ready

diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 51ac2fe..e53906b 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -518,6 +518,10 @@ private:
             throw;
         }
 
+        // indicator to the client that document broker is searching
+        std::string status("statusindicator: find");
+        ws->sendFrame(status.data(), (int) status.size());
+
         const auto uriPublic = DocumentBroker::sanitizeURI(uri);
         const auto docKey = DocumentBroker::getDocKey(uriPublic);
         std::shared_ptr<DocumentBroker> docBroker;
@@ -561,24 +565,29 @@ private:
         // thread that handles them. This is so that we can empty the queue when we get a
         // "canceltiles" message.
         auto queue = std::make_shared<BasicTileQueue>();
-
         auto session = std::make_shared<MasterProcessSession>(id, LOOLSession::Kind::ToClient, ws, docBroker, queue);
         docBroker->addWSSession(id, session);
         auto wsSessionsCount = docBroker->getWSSessionsCount();
         Log::trace(docKey + ", ws_sessions++: " + std::to_string(wsSessionsCount));
         docBrokersLock.unlock();
 
+        // indicator to a client that is waiting to connect to lokit process
+        status = "statusindicator: connect";
+        ws->sendFrame(status.data(), (int) status.size());
+
         if (!waitBridgeCompleted(session, docBroker))
         {
-            Log::error(session->getName() + ": Failed to connect to child. Client cannot serve now.");
+            Log::error(session->getName() + ": Failed to connect to lokit process. Client cannot serve now.");
             // Let the client know we can't serve now.
-            response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE);
-            response.setContentLength(0);
-            response.send();
-            return;
+            status = "statusindicator: fail";
+            ws->sendFrame(status.data(), (int) status.size());
+            ws->shutdown();
+            throw WebSocketException("Failed to connect to lokit process", WebSocket::WS_ENDPOINT_GOING_AWAY);
         }
         // Now the bridge beetween the client and kit process is connected
         // Let messages flow
+        status = "statusindicator: ready";
+        ws->sendFrame(status.data(), (int) status.size());
 
         QueueHandler handler(queue, session, "wsd_queue_" + session->getId());
 
diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp
index cf015b5..168242b 100644
--- a/loolwsd/test/httpwstest.cpp
+++ b/loolwsd/test/httpwstest.cpp
@@ -49,6 +49,7 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture
     CPPUNIT_TEST(testCountHowManyLoolkits);
 
     CPPUNIT_TEST(testBadRequest);
+    CPPUNIT_TEST(testHandShake);
     CPPUNIT_TEST(testLoad);
     CPPUNIT_TEST(testBadLoad);
     CPPUNIT_TEST(testReload);
@@ -70,6 +71,7 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture
 
     void testCountHowManyLoolkits();
     void testBadRequest();
+    void testHandShake();
     void testLoad();
     void testBadLoad();
     void testReload();
@@ -172,6 +174,73 @@ void HTTPWSTest::testBadRequest()
     }
 }
 
+void HTTPWSTest::testHandShake()
+{
+    try
+    {
+        int bytes;
+        int flags;
+        char buffer[1024];
+        // Load a document and get its status.
+        const std::string documentPath = Util::getTempFilePath(TDOC, "hello.odt");
+        const std::string documentURL = "file://" + Poco::Path(documentPath).makeAbsolute().toString();
+
+        Poco::Net::HTTPResponse response;
+        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL);
+#ifdef ENABLE_SSL
+        Poco::Net::HTTPSClientSession session(_uri.getHost(), _uri.getPort());
+#else
+        Poco::Net::HTTPClientSession session(_uri.getHost(), _uri.getPort());
+#endif
+        Poco::Net::WebSocket socket(session, request, response);
+
+        const std::string prefixEdit = "editlock:";
+        const char* fail = "fail";
+        std::string payload("statusindicator: find");
+
+        std::string receive;
+        bytes = socket.receiveFrame(buffer, sizeof(buffer), flags);
+        CPPUNIT_ASSERT(bytes == (int) payload.size());
+        CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0);
+        CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT);
+
+        // After document broker finish searching it sends editlok
+        // it should be at end on handshake
+        bytes = socket.receiveFrame(buffer, sizeof(buffer), flags);
+        CPPUNIT_ASSERT(prefixEdit.compare(0, prefixEdit.size(), buffer, 0, prefixEdit.size()) == 0);
+        CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT);
+
+        payload = "statusindicator: connect";
+        bytes = socket.receiveFrame(buffer, sizeof(buffer), flags);
+        CPPUNIT_ASSERT(bytes == (int) payload.size());
+        CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0);
+        CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT);
+
+        bytes = socket.receiveFrame(buffer, sizeof(buffer), flags);
+        if (std::strstr(buffer, fail))
+        {
+            payload = "statusindicator: fail";
+            CPPUNIT_ASSERT(bytes == (int) payload.size());
+            CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0);
+            CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT);
+        }
+        else
+        {
+            payload = "statusindicator: ready";
+            CPPUNIT_ASSERT(bytes == (int) payload.size());
+            CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0);
+            CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT);
+        }
+
+        socket.shutdown();
+        Util::removeFile(documentPath);
+    }
+    catch (const Poco::Exception& exc)
+    {
+        CPPUNIT_FAIL(exc.displayText());
+    }
+}
+
 void HTTPWSTest::testLoad()
 {
     try
@@ -258,7 +327,8 @@ void HTTPWSTest::testBadLoad()
 
                 // For some reason the server claims a client has the 'edit lock' even if no
                 // document has been successfully loaded
-                if (LOOLProtocol::getFirstToken(buffer, n) == "editlock:")
+                if (LOOLProtocol::getFirstToken(buffer, n) == "editlock:" ||
+                    LOOLProtocol::getFirstToken(buffer, n) == "statusindicator:")
                     continue;
 
                 CPPUNIT_ASSERT_EQUAL(std::string("error: cmd=status kind=nodocloaded"), line);


More information about the Libreoffice-commits mailing list