[Libreoffice-commits] online.git: loolwsd/configure.ac loolwsd/LOOLWSD.cpp loolwsd/LOOLWSD.hpp loolwsd/UserMessages.hpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Thu Jul 14 02:19:15 UTC 2016


 loolwsd/LOOLWSD.cpp      |   41 +++++++++++++++++++++++++++++++++++++++++
 loolwsd/LOOLWSD.hpp      |    2 ++
 loolwsd/UserMessages.hpp |    1 +
 loolwsd/configure.ac     |   20 ++++++++++++++++++++
 4 files changed, 64 insertions(+)

New commits:
commit f52fa89036de03d955f64db721ac2f1565f48273
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Wed Jul 13 22:01:23 2016 -0400

    Build-time configurable WSD limits
    
    The server can now be configured at build time
    to limit the total number of connections and/or
    the number of open documents, at a given time.
    
    ./configure --with-max-documents=10 --with-max-connections=20
    will limit the number of documents to 10 and total
    number of connections (on one or all documents) to 20.
    
    Change-Id: I0c73a7e906c4f567cb3da480e885524815c9cc89
    Reviewed-on: https://gerrit.libreoffice.org/27203
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index bcf70a0..20f1756 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -594,6 +594,15 @@ private:
                 throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_INTERNAL_ERROR);
             }
 
+#if MAX_DOCUMENTS > 0
+            if (++LOOLWSD::NumDocBrokers > MAX_DOCUMENTS)
+            {
+                --LOOLWSD::NumDocBrokers;
+                Log::error("Maximum number of open documents reached.");
+                throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_LIMIT_REACHED);
+            }
+#endif
+
             // Set one we just created.
             Log::debug("New DocumentBroker for docKey [" + docKey + "].");
             docBroker = std::make_shared<DocumentBroker>(uriPublic, docKey, LOOLWSD::ChildRoot, child);
@@ -609,6 +618,9 @@ private:
                 // Remove.
                 std::unique_lock<std::mutex> lock(docBrokersMutex);
                 docBrokers.erase(docKey);
+#if MAX_DOCUMENTS > 0
+                --LOOLWSD::NumDocBrokers;
+#endif
             }
 
             throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_INTERNAL_ERROR);
@@ -723,6 +735,9 @@ private:
                 std::unique_lock<std::mutex> docBrokersLock(docBrokersMutex);
                 Log::debug("Removing DocumentBroker for docKey [" + docKey + "].");
                 docBrokers.erase(docKey);
+#if MAX_DOCUMENTS > 0
+                --LOOLWSD::NumDocBrokers;
+#endif
                 Log::info("Removing complete doc [" + docKey + "] from Admin.");
                 Admin::instance().rmDoc(docKey);
             }
@@ -810,7 +825,20 @@ public:
                 request, response))
             return;
 
+#if MAX_CONNECTIONS > 0
+        if (++LOOLWSD::NumConnections > MAX_CONNECTIONS)
+        {
+            --LOOLWSD::NumConnections;
+            Log::error("Maximum number of connections reached.");
+            throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_LIMIT_REACHED);
+        }
+#endif
+
         handleClientRequest(request,response);
+
+#if MAX_CONNECTIONS > 0
+        --LOOLWSD::NumConnections;
+#endif
     }
 
     static void handleClientRequest(HTTPServerRequest& request, HTTPServerResponse& response)
@@ -1197,6 +1225,8 @@ bool LOOLWSD::SSLEnabled =
 static std::string UnitTestLibrary;
 
 unsigned int LOOLWSD::NumPreSpawnedChildren = 0;
+std::atomic<unsigned> LOOLWSD::NumDocBrokers;
+std::atomic<unsigned> LOOLWSD::NumConnections;
 
 class AppConfigMap : public Poco::Util::MapConfiguration
 {
@@ -1293,6 +1323,17 @@ void LOOLWSD::initialize(Application& self)
         setenv("MAX_CONCURRENCY", std::to_string(maxConcurrency).c_str(), 1);
     }
 
+    // In Trial Versions we might want to set some limits.
+    LOOLWSD::NumDocBrokers = 0;
+    LOOLWSD::NumConnections = 0;
+    Log::info() << "Open Documents Limit: " << (MAX_DOCUMENTS > 0 ?
+                                                std::to_string(MAX_DOCUMENTS) :
+                                                std::string("unlimited")) << Log::end;
+
+    Log::info() << "Client Connections Limit: " << (MAX_CONNECTIONS > 0 ?
+                                                    std::to_string(MAX_CONNECTIONS) :
+                                                    std::string("unlimited")) << Log::end;
+
     StorageBase::initialize();
 
     ServerApplication::initialize(self);
diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp
index 76e942e..b750bda 100644
--- a/loolwsd/LOOLWSD.hpp
+++ b/loolwsd/LOOLWSD.hpp
@@ -44,6 +44,8 @@ public:
     static std::string FileServerRoot;
     static std::string LOKitVersion;
     static bool SSLEnabled;
+    static std::atomic<unsigned> NumDocBrokers;
+    static std::atomic<unsigned> NumConnections;
 
     static
     std::string GenSessionId()
diff --git a/loolwsd/UserMessages.hpp b/loolwsd/UserMessages.hpp
index 93e3e57..5208b09 100644
--- a/loolwsd/UserMessages.hpp
+++ b/loolwsd/UserMessages.hpp
@@ -13,6 +13,7 @@
 #define INCLUDED_USERMESSAGES_HPP
 
 constexpr auto SERVICE_UNAVALABLE_INTERNAL_ERROR = "Service is unavailable. Please try again later and report to your administrator if the issue persists.";
+constexpr auto SERVICE_UNAVALABLE_LIMIT_REACHED = "This server has reached the number of connections or documents it supports at a given time.";
 
 #endif
 
diff --git a/loolwsd/configure.ac b/loolwsd/configure.ac
index 3b01637..4f2565e 100644
--- a/loolwsd/configure.ac
+++ b/loolwsd/configure.ac
@@ -80,6 +80,14 @@ AC_ARG_ENABLE([ssl],
             AS_HELP_STRING([--disable-ssl],
                            [Compile without SSL support]))
 
+AC_ARG_WITH([max-documents],
+             AS_HELP_STRING([--max-documents],
+                            [Compile with a hard-coded limit on the number of documents]))
+
+AC_ARG_WITH([max-connections],
+            AS_HELP_STRING([--max-connections],
+                           [Compile with a hard-coded limit on the total number of client connections]))
+
 # Handle options
 AS_IF([test "$enable_debug" = yes -a -n "$with_poco_libs"],
       [POCO_DEBUG_SUFFIX=d],
@@ -96,6 +104,18 @@ else
 fi
 AC_SUBST(ENABLE_DEBUG)
 
+MAX_DOCUMENTS=0
+AS_IF([test -n "$with_max_documents"],
+      [MAX_DOCUMENTS="$with_max_documents"])
+AC_DEFINE_UNQUOTED([MAX_DOCUMENTS],[$MAX_DOCUMENTS],[Limit the maximum number of open documents])
+AC_SUBST(MAX_DOCUMENTS)
+
+MAX_CONNECTIONS=0
+AS_IF([test -n "$with_max_connections"],
+      [MAX_CONNECTIONS="$with_max_connections"])
+AC_DEFINE_UNQUOTED([MAX_CONNECTIONS],[$MAX_CONNECTIONS],[Limit the maximum number of open documents])
+AC_SUBST(MAX_CONNECTIONS)
+
 # Test for build environment
 
 CXXFLAGS="$CXXFLAGS -std=c++11"


More information about the Libreoffice-commits mailing list