[Libreoffice-commits] online.git: 3 commits - loolwsd/AdminModel.cpp loolwsd/AdminModel.hpp loolwsd/Auth.cpp loolwsd/Auth.hpp loolwsd/DocumentBroker.cpp loolwsd/Makefile.am loolwsd/Storage.cpp loolwsd/Storage.hpp

Pranav Kant pranavk at collabora.com
Thu Mar 31 07:32:31 UTC 2016


 loolwsd/AdminModel.cpp     |  361 ++++++++++++++++++++++++++++++++++++++++++
 loolwsd/AdminModel.hpp     |  385 +++------------------------------------------
 loolwsd/Auth.cpp           |  211 ++++++++++++++++++++++++
 loolwsd/Auth.hpp           |  187 ---------------------
 loolwsd/DocumentBroker.cpp |    2 
 loolwsd/Makefile.am        |   97 ++++++++---
 loolwsd/Storage.cpp        |  275 ++++++++++++++++++++++++++++++++
 loolwsd/Storage.hpp        |  245 +---------------------------
 8 files changed, 972 insertions(+), 791 deletions(-)

New commits:
commit 4ae077200cb1090b109125d4534dfbf5282a9740
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu Mar 31 12:55:35 2016 +0530

    loolwsd: Separate AdminModel header and implementation
    
    Change-Id: Iddf107aa7985988deba800030e75243a831a7532

diff --git a/loolwsd/AdminModel.cpp b/loolwsd/AdminModel.cpp
new file mode 100644
index 0000000..644fa9c
--- /dev/null
+++ b/loolwsd/AdminModel.cpp
@@ -0,0 +1,361 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <memory>
+#include <set>
+#include <sstream>
+#include <string>
+
+#include <Poco/Net/WebSocket.h>
+#include <Poco/Process.h>
+#include <Poco/StringTokenizer.h>
+
+#include "AdminModel.hpp"
+#include "Util.hpp"
+
+using Poco::StringTokenizer;
+
+/////////////////
+// Document Impl
+////////////////
+void Document::addView(int nSessionId)
+{
+    const auto ret = _views.emplace(nSessionId, View(nSessionId));
+    if (!ret.second)
+    {
+        Log::warn() << "View with SessionID [" + std::to_string(nSessionId) + "] already exists." << Log::end;
+    }
+    else
+    {
+        _nActiveViews++;
+    }
+}
+
+void Document::removeView(int nSessionId)
+{
+    auto it = _views.find(nSessionId);
+    if (it != _views.end())
+    {
+        it->second.expire();
+        _nActiveViews--;
+    }
+}
+
+///////////////////
+// Subscriber Impl
+//////////////////
+bool Subscriber::notify(const std::string& message)
+{
+    StringTokenizer tokens(message, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+
+    if (_subscriptions.find(tokens[0]) == _subscriptions.end())
+        return true;
+
+    auto webSocket = _ws.lock();
+    if (webSocket)
+    {
+        webSocket->sendFrame(message.data(), message.length());
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+bool  Subscriber::subscribe(const std::string& command)
+{
+    auto ret = _subscriptions.insert(command);
+    return ret.second;
+}
+
+void  Subscriber::unsubscribe(const std::string& command)
+{
+    _subscriptions.erase(command);
+}
+
+///////////////////
+// AdminModel Impl
+//////////////////
+
+void AdminModel::update(const std::string& data)
+{
+    StringTokenizer tokens(data, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+
+    Log::info("AdminModel Recv: " + data);
+
+    if (tokens[0] == "document")
+    {
+        addDocument(std::stoi(tokens[1]), tokens[2]);
+        unsigned mem = Util::getMemoryUsage(std::stoi(tokens[1]));
+        std::string response = data + std::to_string(mem);
+        notify(response);
+        return;
+    }
+    else if (tokens[0] == "addview")
+    {
+        auto it = _documents.find(std::stoi(tokens[1]));
+        if (it != _documents.end())
+        {
+            const unsigned nSessionId = Util::decodeId(tokens[2]);
+            it->second.addView(nSessionId);
+        }
+    }
+    else if (tokens[0] == "rmview")
+    {
+        auto it = _documents.find(std::stoi(tokens[1]));
+        if (it != _documents.end())
+        {
+            const unsigned nSessionId = Util::decodeId(tokens[2]);
+            it->second.removeView(nSessionId);
+        }
+    }
+    else if (tokens[0] == "rmdoc")
+    {
+        removeDocument(std::stoi(tokens[1]));
+    }
+
+    notify(data);
+}
+
+std::string AdminModel::query(const std::string command)
+{
+    StringTokenizer tokens(command, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+
+    if (tokens[0] == "documents")
+    {
+        return getDocuments();
+    }
+    else if (tokens[0] == "active_users_count")
+    {
+        return std::to_string(getTotalActiveViews());
+    }
+    else if (tokens[0] == "active_docs_count")
+    {
+        return std::to_string(_documents.size());
+    }
+    else if (tokens[0] == "mem_stats")
+    {
+        return getMemStats();
+    }
+    else if (tokens[0] == "mem_stats_size")
+    {
+        return std::to_string(_memStatsSize);
+    }
+    else if (tokens[0] == "cpu_stats")
+    {
+        return getCpuStats();
+    }
+    else if (tokens[0] == "cpu_stats_size")
+    {
+        return std::to_string(_cpuStatsSize);
+    }
+
+    return std::string("");
+}
+
+/// Returns memory consumed by all active loolkit processes
+unsigned AdminModel::getTotalMemoryUsage()
+{
+    unsigned totalMem = 0;
+    for (auto& it: _documents)
+    {
+        if (it.second.isExpired())
+            continue;
+
+        totalMem += Util::getMemoryUsage(it.second.getPid());
+    }
+
+    return totalMem;
+}
+
+void AdminModel::subscribe(int nSessionId, std::shared_ptr<Poco::Net::WebSocket>& ws)
+{
+    const auto ret = _subscribers.emplace(nSessionId, Subscriber(nSessionId, ws));
+    if (!ret.second)
+    {
+        Log::warn() << "Subscriber already exists" << Log::end;
+    }
+}
+
+void AdminModel::subscribe(int nSessionId, const std::string& command)
+{
+    auto subscriber = _subscribers.find(nSessionId);
+    if (subscriber == _subscribers.end() )
+        return;
+
+    subscriber->second.subscribe(command);
+}
+
+void AdminModel::unsubscribe(int nSessionId, const std::string& command)
+{
+    auto subscriber = _subscribers.find(nSessionId);
+    if (subscriber == _subscribers.end())
+        return;
+
+    subscriber->second.unsubscribe(command);
+}
+
+void AdminModel::addMemStats(unsigned memUsage)
+{
+    _memStats.push_back(memUsage);
+    if (_memStats.size() > _memStatsSize)
+    {
+        _memStats.pop_front();
+    }
+
+    std::ostringstream oss;
+    oss << "mem_stats "
+        << std::to_string(memUsage);
+    notify(oss.str());
+}
+
+void AdminModel::addCpuStats(unsigned cpuUsage)
+{
+    _cpuStats.push_back(cpuUsage);
+    if (_cpuStats.size() > _cpuStatsSize)
+    {
+        _cpuStats.pop_front();
+    }
+
+    std::ostringstream oss;
+    oss << "cpu_stats "
+        << std::to_string(cpuUsage);
+    notify(oss.str());
+}
+
+void AdminModel::setCpuStatsSize(unsigned size)
+{
+    int wasteValuesLen = _cpuStats.size() - size;
+    while (wasteValuesLen-- > 0)
+    {
+        _cpuStats.pop_front();
+    }
+    _cpuStatsSize = size;
+
+    std::ostringstream oss;
+    oss << "settings "
+        << "cpu_stats_size="
+        << std::to_string(_cpuStatsSize);
+    notify(oss.str());
+}
+
+void AdminModel::setMemStatsSize(unsigned size)
+{
+    int wasteValuesLen = _memStats.size() - size;
+    while (wasteValuesLen-- > 0)
+    {
+        _memStats.pop_front();
+    }
+    _memStatsSize = size;
+
+    std::ostringstream oss;
+    oss << "settings "
+        << "mem_stats_size="
+        << std::to_string(_memStatsSize);
+    notify(oss.str());
+}
+
+void AdminModel::notify(const std::string& message)
+{
+    auto it = std::begin(_subscribers);
+    while (it != std::end(_subscribers))
+    {
+        if (!it->second.notify(message))
+        {
+            it = _subscribers.erase(it);
+        }
+        else
+        {
+            it++;
+        }
+    }
+}
+
+void AdminModel::addDocument(Poco::Process::PID pid, std::string url)
+{
+    const auto ret = _documents.emplace(pid, Document(pid, url));
+    if (!ret.second)
+    {
+        Log::warn() << "Document with PID [" + std::to_string(pid) + "] already exists." << Log::end;
+    }
+}
+
+void AdminModel::removeDocument(Poco::Process::PID pid)
+{
+    auto it = _documents.find(pid);
+    if (it != _documents.end() && !it->second.isExpired())
+    {
+        // TODO: The idea is to only expire the document and keep the history
+        // of documents open and close, to be able to give a detailed summary
+        // to the admin console with views. For now, just remove the document.
+        it->second.expire();
+        _documents.erase(it);
+    }
+}
+
+std::string AdminModel::getMemStats()
+{
+    std::string response;
+    for (auto& i: _memStats)
+    {
+        response += std::to_string(i) + ",";
+    }
+
+    return response;
+}
+
+std::string AdminModel::getCpuStats()
+{
+    std::string response;
+    for (auto& i: _cpuStats)
+    {
+        response += std::to_string(i) + ",";
+    }
+
+    return response;
+}
+
+unsigned AdminModel::getTotalActiveViews()
+{
+    unsigned nTotalViews = 0;
+    for (auto& it: _documents)
+    {
+        if (it.second.isExpired())
+            continue;
+
+        nTotalViews += it.second.getActiveViews();
+    }
+
+    return nTotalViews;
+}
+
+std::string AdminModel::getDocuments()
+{
+    std::ostringstream oss;
+    for (auto& it: _documents)
+    {
+        if (it.second.isExpired())
+            continue;
+
+        std::string sPid = std::to_string(it.second.getPid());
+        std::string sUrl = it.second.getUrl();
+        std::string sViews = std::to_string(it.second.getActiveViews());
+        std::string sMem = std::to_string(Util::getMemoryUsage(it.second.getPid()));
+
+        oss << sPid << " "
+            << sUrl << " "
+            << sViews << " "
+            << sMem << " \n ";
+    }
+
+    return oss.str();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/AdminModel.hpp b/loolwsd/AdminModel.hpp
index af38c6d..444689b 100644
--- a/loolwsd/AdminModel.hpp
+++ b/loolwsd/AdminModel.hpp
@@ -12,13 +12,10 @@
 
 #include <memory>
 #include <set>
-#include <sstream>
 #include <string>
-#include <queue>
 
 #include <Poco/Net/WebSocket.h>
 #include <Poco/Process.h>
-#include <Poco/StringTokenizer.h>
 
 #include "Util.hpp"
 
@@ -30,15 +27,9 @@ public:
           _start(std::time(nullptr))
     {    }
 
-    void expire()
-    {
-        _end = std::time(nullptr);
-    }
+    void expire() { _end = std::time(nullptr); }
 
-    bool isExpired()
-    {
-        return _end != 0 && std::time(nullptr) >= _end;
-    }
+    bool isExpired() { return _end != 0 && std::time(nullptr) >= _end; }
 
 private:
     int _nSessionId;
@@ -63,53 +54,19 @@ public:
         Log::info("Document " + std::to_string(_nPid) + " dtor.");
     }
 
-    Poco::Process::PID getPid() const
-    {
-        return _nPid;
-    }
+    Poco::Process::PID getPid() const { return _nPid; }
 
-    std::string getUrl() const
-    {
-        return _sUrl;
-    }
+    std::string getUrl() const { return _sUrl; }
 
-    void expire()
-    {
-        _end = std::time(nullptr);
-    }
+    void expire() { _end = std::time(nullptr); }
 
-    bool isExpired() const
-    {
-        return _end != 0 && std::time(nullptr) >= _end;
-    }
+    bool isExpired() const { return _end != 0 && std::time(nullptr) >= _end; }
 
-    void addView(int nSessionId)
-    {
-        const auto ret = _views.emplace(nSessionId, View(nSessionId));
-        if (!ret.second)
-        {
-            Log::warn() << "View with SessionID [" + std::to_string(nSessionId) + "] already exists." << Log::end;
-        }
-        else
-        {
-            _nActiveViews++;
-        }
-    }
+    void addView(int nSessionId);
 
-    void removeView(int nSessionId)
-    {
-        auto it = _views.find(nSessionId);
-        if (it != _views.end())
-        {
-            it->second.expire();
-            _nActiveViews--;
-        }
-    }
+    void removeView(int nSessionId);
 
-    unsigned getActiveViews() const
-    {
-        return _nActiveViews;
-    }
+    unsigned getActiveViews() const { return _nActiveViews; }
 
 private:
     Poco::Process::PID _nPid;
@@ -140,45 +97,15 @@ public:
         Log::info("Subscriber dtor.");
     }
 
-    bool notify(const std::string& message)
-    {
-        Poco::StringTokenizer tokens(message, " ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
-
-        if (_subscriptions.find(tokens[0]) == _subscriptions.end())
-            return true;
-
-        auto webSocket = _ws.lock();
-        if (webSocket)
-        {
-            webSocket->sendFrame(message.data(), message.length());
-            return true;
-        }
-        else
-        {
-            return false;
-        }
-    }
+    bool notify(const std::string& message);
 
-    bool subscribe(const std::string& command)
-    {
-        auto ret = _subscriptions.insert(command);
-        return ret.second;
-    }
+    bool subscribe(const std::string& command);
 
-    void unsubscribe(const std::string& command)
-    {
-        _subscriptions.erase(command);
-    }
+    void unsubscribe(const std::string& command);
 
-    void expire()
-    {
-        _end = std::time(nullptr);
-    }
+    void expire() { _end = std::time(nullptr); }
 
-    bool isExpired() const
-    {
-        return _end != 0 && std::time(nullptr) >= _end;
-    }
+    bool isExpired() const { return _end != 0 && std::time(nullptr) >= _end; }
 
 private:
     /// Admin session Id
@@ -210,290 +137,44 @@ public:
         Log::info("AdminModel dtor.");
     }
 
-    void update(const std::string& data)
-    {
-        Poco::StringTokenizer tokens(data, " ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
-
-        Log::info("AdminModel Recv: " + data);
-
-        if (tokens[0] == "document")
-        {
-            addDocument(std::stoi(tokens[1]), tokens[2]);
-            unsigned mem = Util::getMemoryUsage(std::stoi(tokens[1]));
-            std::string response = data + std::to_string(mem);
-            notify(response);
-            return;
-        }
-        else if (tokens[0] == "addview")
-        {
-            auto it = _documents.find(std::stoi(tokens[1]));
-            if (it != _documents.end())
-            {
-                const unsigned nSessionId = Util::decodeId(tokens[2]);
-                it->second.addView(nSessionId);
-            }
-        }
-        else if (tokens[0] == "rmview")
-        {
-            auto it = _documents.find(std::stoi(tokens[1]));
-            if (it != _documents.end())
-            {
-                const unsigned nSessionId = Util::decodeId(tokens[2]);
-                it->second.removeView(nSessionId);
-            }
-        }
-        else if (tokens[0] == "rmdoc")
-        {
-            removeDocument(std::stoi(tokens[1]));
-        }
-
-        notify(data);
-    }
+    void update(const std::string& data);
 
-    std::string query(const std::string command)
-    {
-        Poco::StringTokenizer tokens(command, " ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
-
-        if (tokens[0] == "documents")
-        {
-            return getDocuments();
-        }
-        else if (tokens[0] == "active_users_count")
-        {
-            return std::to_string(getTotalActiveViews());
-        }
-        else if (tokens[0] == "active_docs_count")
-        {
-            return std::to_string(_documents.size());
-        }
-        else if (tokens[0] == "mem_stats")
-        {
-            return getMemStats();
-        }
-        else if (tokens[0] == "mem_stats_size")
-        {
-            return std::to_string(_memStatsSize);
-        }
-        else if (tokens[0] == "cpu_stats")
-        {
-            return getCpuStats();
-        }
-        else if (tokens[0] == "cpu_stats_size")
-        {
-            return std::to_string(_cpuStatsSize);
-        }
-
-        return std::string("");
-    }
+    std::string query(const std::string command);
 
     /// Returns memory consumed by all active loolkit processes
-    unsigned getTotalMemoryUsage()
-    {
-        unsigned totalMem = 0;
-        for (auto& it: _documents)
-        {
-            if (it.second.isExpired())
-                continue;
+    unsigned getTotalMemoryUsage();
 
-            totalMem += Util::getMemoryUsage(it.second.getPid());
-        }
+    void subscribe(int nSessionId, std::shared_ptr<Poco::Net::WebSocket>& ws);
+    void subscribe(int nSessionId, const std::string& command);
 
-        return totalMem;
-    }
+    void unsubscribe(int nSessionId, const std::string& command);
 
-    void subscribe(int nSessionId, std::shared_ptr<Poco::Net::WebSocket>& ws)
-    {
-        const auto ret = _subscribers.emplace(nSessionId, Subscriber(nSessionId, ws));
-        if (!ret.second)
-        {
-            Log::warn() << "Subscriber already exists" << Log::end;
-        }
-    }
+    void clearMemStats() { _memStats.clear(); }
 
-    void subscribe(int nSessionId, const std::string& command)
-    {
-        auto subscriber = _subscribers.find(nSessionId);
-        if (subscriber == _subscribers.end() )
-            return;
+    void clearCpuStats() { _cpuStats.clear(); }
 
-        subscriber->second.subscribe(command);
-    }
+    void addMemStats(unsigned memUsage);
 
-    void unsubscribe(int nSessionId, const std::string& command)
-    {
-        auto subscriber = _subscribers.find(nSessionId);
-        if (subscriber == _subscribers.end())
-            return;
-
-        subscriber->second.unsubscribe(command);
-    }
+    void addCpuStats(unsigned cpuUsage);
 
-    void clearMemStats()
-    {
-        _memStats.clear();
-    }
+    void setCpuStatsSize(unsigned size);
 
-    void clearCpuStats()
-    {
-        _cpuStats.clear();
-    }
+    void setMemStatsSize(unsigned size);
 
-    void addMemStats(unsigned memUsage)
-    {
-        _memStats.push_back(memUsage);
-        if (_memStats.size() > _memStatsSize)
-        {
-            _memStats.pop_front();
-        }
-
-        std::ostringstream oss;
-        oss << "mem_stats "
-            << std::to_string(memUsage);
-        notify(oss.str());
-    }
-
-    void addCpuStats(unsigned cpuUsage)
-    {
-        _cpuStats.push_back(cpuUsage);
-        if (_cpuStats.size() > _cpuStatsSize)
-        {
-            _cpuStats.pop_front();
-        }
-
-        std::ostringstream oss;
-        oss << "cpu_stats "
-            << std::to_string(cpuUsage);
-        notify(oss.str());
-    }
-
-    void setCpuStatsSize(unsigned size)
-    {
-        int wasteValuesLen = _cpuStats.size() - size;
-        while (wasteValuesLen-- > 0)
-        {
-            _cpuStats.pop_front();
-        }
-        _cpuStatsSize = size;
-
-        std::ostringstream oss;
-        oss << "settings "
-            << "cpu_stats_size="
-            << std::to_string(_cpuStatsSize);
-        notify(oss.str());
-    }
-
-    void setMemStatsSize(unsigned size)
-    {
-        int wasteValuesLen = _memStats.size() - size;
-        while (wasteValuesLen-- > 0)
-        {
-            _memStats.pop_front();
-        }
-        _memStatsSize = size;
-
-        std::ostringstream oss;
-        oss << "settings "
-            << "mem_stats_size="
-            << std::to_string(_memStatsSize);
-        notify(oss.str());
-    }
-
-    void notify(const std::string& message)
-    {
-        auto it = std::begin(_subscribers);
-        while (it != std::end(_subscribers))
-        {
-            if (!it->second.notify(message))
-            {
-                it = _subscribers.erase(it);
-            }
-            else
-            {
-                it++;
-            }
-        }
-    }
+    void notify(const std::string& message);
 
 private:
-    void addDocument(Poco::Process::PID pid, std::string url)
-    {
-        const auto ret = _documents.emplace(pid, Document(pid, url));
-        if (!ret.second)
-        {
-            Log::warn() << "Document with PID [" + std::to_string(pid) + "] already exists." << Log::end;
-        }
-    }
-
-    void removeDocument(Poco::Process::PID pid)
-    {
-        auto it = _documents.find(pid);
-        if (it != _documents.end() && !it->second.isExpired())
-        {
-            // TODO: The idea is to only expire the document and keep the history
-            // of documents open and close, to be able to give a detailed summary
-            // to the admin console with views. For now, just remove the document.
-            it->second.expire();
-            _documents.erase(it);
-        }
-    }
-
-    std::string getMemStats()
-    {
-        std::string response;
-        for (auto& i: _memStats)
-        {
-            response += std::to_string(i) + ",";
-        }
+    void addDocument(Poco::Process::PID pid, std::string url);
 
-        return response;
-    }
+    void removeDocument(Poco::Process::PID pid);
 
-    std::string getCpuStats()
-    {
-        std::string response;
-        for (auto& i: _cpuStats)
-        {
-            response += std::to_string(i) + ",";
-        }
+    std::string getMemStats();
 
-        return response;
-    }
-
-    unsigned getTotalActiveViews()
-    {
-        unsigned nTotalViews = 0;
-        for (auto& it: _documents)
-        {
-            if (it.second.isExpired())
-                continue;
+    std::string getCpuStats();
 
-            nTotalViews += it.second.getActiveViews();
-        }
+    unsigned getTotalActiveViews();
 
-        return nTotalViews;
-    }
-
-    std::string getDocuments()
-    {
-        std::ostringstream oss;
-        for (auto& it: _documents)
-        {
-            if (it.second.isExpired())
-                continue;
-
-            std::string sPid = std::to_string(it.second.getPid());
-            std::string sUrl = it.second.getUrl();
-            std::string sViews = std::to_string(it.second.getActiveViews());
-            std::string sMem = std::to_string(Util::getMemoryUsage(it.second.getPid()));
-
-            oss << sPid << " "
-                << sUrl << " "
-                << sViews << " "
-                << sMem << " \n ";
-        }
-
-        return oss.str();
-    }
+    std::string getDocuments();
 
 private:
     std::map<int, Subscriber> _subscribers;
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index 53e952a..f3f5662 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -17,6 +17,7 @@ shared_sources = IoUtil.cpp \
                  Util.cpp
 
 loolwsd_SOURCES = Admin.cpp \
+		  AdminModel.cpp \
                   Auth.cpp \
                   ChildProcessSession.cpp \
                   DocumentBroker.cpp \
commit 939388c6e6362d9977a460139e55587de0be47d4
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu Mar 31 12:31:05 2016 +0530

    loolwsd: Arrange sources/header in makefile alphabetically
    
    Change-Id: I0bc70b34a590d84ac9c15f0d9d0000d02cadba74

diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index 7428229..53e952a 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -10,34 +10,80 @@ AM_LDFLAGS = -pthread
 AM_ETAGSFLAGS = --c++-kinds=+p --fields=+iaS --extra=+q -R --totals=yes *
 AM_CTAGSFLAGS = $(AM_ETAGSFLAGS)
 
-shared_sources = LOOLProtocol.cpp LOOLSession.cpp MessageQueue.cpp IoUtil.cpp Util.cpp
-
-loolwsd_SOURCES = LOOLWSD.cpp ChildProcessSession.cpp MasterProcessSession.cpp TileCache.cpp Admin.cpp DocumentBroker.cpp Auth.cpp Storage.cpp $(shared_sources)
-
-noinst_PROGRAMS = loadtest connect lokitclient
-
-loadtest_SOURCES = LoadTest.cpp Util.cpp LOOLProtocol.cpp
-
-connect_SOURCES = Connect.cpp Util.cpp LOOLProtocol.cpp
-
-lokitclient_SOURCES = LOKitClient.cpp LOOLProtocol.cpp IoUtil.cpp Util.cpp
-
-broker_shared_sources = ChildProcessSession.cpp $(shared_sources)
-
-loolkit_SOURCES = LOOLKit.cpp $(broker_shared_sources)
-
-loolbroker_SOURCES = LOOLBroker.cpp $(broker_shared_sources)
+shared_sources = IoUtil.cpp \
+                 LOOLProtocol.cpp \
+                 LOOLSession.cpp \
+                 MessageQueue.cpp \
+                 Util.cpp
+
+loolwsd_SOURCES = Admin.cpp \
+                  Auth.cpp \
+                  ChildProcessSession.cpp \
+                  DocumentBroker.cpp \
+                  LOOLWSD.cpp \
+                  MasterProcessSession.cpp \
+                  Storage.cpp \
+                  TileCache.cpp \
+                  $(shared_sources)
+
+noinst_PROGRAMS = connect \
+                  loadtest \
+                  lokitclient
+
+loadtest_SOURCES = LoadTest.cpp \
+                   LOOLProtocol.cpp \
+                   Util.cpp
+
+connect_SOURCES = Connect.cpp \
+                  LOOLProtocol.cpp \
+                  Util.cpp
+
+lokitclient_SOURCES = IoUtil.cpp \
+                      LOKitClient.cpp \
+                      LOOLProtocol.cpp \
+                      Util.cpp
+
+broker_shared_sources = ChildProcessSession.cpp \
+                        $(shared_sources)
+
+loolkit_SOURCES = LOOLKit.cpp \
+                  $(broker_shared_sources)
+
+loolbroker_SOURCES = LOOLBroker.cpp \
+                     $(broker_shared_sources)
 
 loolmap_SOURCES = loolmap.c
 
-noinst_HEADERS = LOKitHelper.hpp LOOLProtocol.hpp LOOLSession.hpp MasterProcessSession.hpp ChildProcessSession.hpp \
-                 LOOLWSD.hpp LoadTest.hpp MessageQueue.hpp TileCache.hpp Util.hpp Png.hpp Common.hpp Capabilities.hpp \
-                 Rectangle.hpp QueueHandler.hpp Admin.hpp Auth.hpp Storage.hpp AdminModel.hpp DocumentBroker.hpp \
-                 FileServer.hpp IoUtil.hpp \
-                 bundled/include/LibreOfficeKit/LibreOfficeKit.h bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h \
-                 bundled/include/LibreOfficeKit/LibreOfficeKitInit.h bundled/include/LibreOfficeKit/LibreOfficeKitTypes.h
-
-EXTRA_DIST = loolwsd.service sysconfig.loolwsd discovery.xml
+noinst_HEADERS = Admin.hpp \
+                 AdminModel.hpp \
+                 Auth.hpp \
+                 Capabilities.hpp \
+                 ChildProcessSession.hpp \
+                 Common.hpp \
+                 DocumentBroker.hpp \
+                 FileServer.hpp \
+                 IoUtil.hpp \
+                 LoadTest.hpp \
+                 LOKitHelper.hpp \
+                 LOOLProtocol.hpp \
+                 LOOLSession.hpp \
+                 LOOLWSD.hpp \
+                 MasterProcessSession.hpp \
+                 MessageQueue.hpp \
+                 Png.hpp \
+                 QueueHandler.hpp \
+                 Rectangle.hpp \
+                 Storage.hpp \
+                 TileCache.hpp \
+                 Util.hpp \
+                 bundled/include/LibreOfficeKit/LibreOfficeKit.h \
+                 bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h \
+                 bundled/include/LibreOfficeKit/LibreOfficeKitInit.h \
+                 bundled/include/LibreOfficeKit/LibreOfficeKitTypes.h
+
+EXTRA_DIST = discovery.xml \
+             loolwsd.service \
+             sysconfig.loolwsd
 
 clean-cache:
 # Intentionally don't use "*" below... Avoid risk of accidentally running rm -rf /*
commit f1ede0c4baa0dc77050e11f4283e3ddb4e256fb9
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu Mar 31 12:18:34 2016 +0530

    loolwsd: Split Storage, Auth classes into header/impl files
    
    Change-Id: I5d8990db8f8f4aa7a88bbb0cc84b97149cf4f8c0

diff --git a/loolwsd/Auth.cpp b/loolwsd/Auth.cpp
new file mode 100644
index 0000000..5d079d4
--- /dev/null
+++ b/loolwsd/Auth.cpp
@@ -0,0 +1,211 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <cstdlib>
+#include <string>
+
+#include <Poco/Base64Encoder.h>
+#include <Poco/Base64Decoder.h>
+#include <Poco/Crypto/RSADigestEngine.h>
+#include <Poco/Crypto/RSAKey.h>
+#include <Poco/JSON/Object.h>
+#include <Poco/LineEndingConverter.h>
+#include <Poco/Net/HTTPClientSession.h>
+#include <Poco/Net/HTTPRequest.h>
+#include <Poco/Net/HTTPResponse.h>
+#include <Poco/StringTokenizer.h>
+#include <Poco/Timestamp.h>
+#include <Poco/URI.h>
+
+#include "Auth.hpp"
+#include "Util.hpp"
+
+
+//////////////
+// OAuth Impl
+//////////////
+const std::string JWTAuth::getAccessToken()
+{
+    std::string encodedHeader = createHeader();
+    std::string encodedPayload = createPayload();
+
+    // trim '=' from end of encoded header
+    encodedHeader.erase(std::find_if(encodedHeader.rbegin(), encodedHeader.rend(),
+                                     [](char& ch)->bool {return ch != '='; }).base(), encodedHeader.end());
+    // trim '=' from end of encoded payload
+    encodedPayload.erase(std::find_if(encodedPayload.rbegin(), encodedPayload.rend(),
+                                      [](char& ch)->bool { return ch != '='; }).base(), encodedPayload.end());
+    Log::info("Encoded JWT header: " + encodedHeader);
+    Log::info("Encoded JWT payload: " + encodedPayload);
+
+    // Convert to a URL and filename safe variant:
+    // Replace '+' with '-' && '/' with '_'
+    std::replace(encodedHeader.begin(), encodedHeader.end(), '+','-');
+    std::replace(encodedHeader.begin(), encodedHeader.end(), '/','_');
+
+    std::replace(encodedPayload.begin(), encodedPayload.end(), '+','-');
+    std::replace(encodedPayload.begin(), encodedPayload.end(), '/','_');
+
+    std::string encodedBody = encodedHeader  + "." +  encodedPayload;
+
+    // sign the encoded body
+    _digestEngine.update(encodedBody.c_str(), static_cast<unsigned>(encodedBody.length()));
+    Poco::Crypto::DigestEngine::Digest digest = _digestEngine.signature();
+
+    // The signature generated contains CRLF line endings.
+    // Use a line ending converter to remove these CRLF
+    std::ostringstream ostr;
+    Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
+    Poco::Base64Encoder encoder(lineEndingConv);
+    encoder << std::string(digest.begin(), digest.end());
+    encoder.close();
+    std::string encodedSig = ostr.str();
+
+    // trim '=' from end of encoded signature
+    encodedSig.erase(std::find_if(encodedSig.rbegin(), encodedSig.rend(),
+                                  [](char& ch)->bool { return ch != '='; }).base(), encodedSig.end());
+
+    // Be URL and filename safe
+    std::replace(encodedSig.begin(), encodedSig.end(), '+','-');
+    std::replace(encodedSig.begin(), encodedSig.end(), '/','_');
+
+    Log::info("Sig generated is : " + encodedSig);
+
+    const std::string jwtToken = encodedBody + "." + encodedSig;
+    Log::info("JWT token generated: " + jwtToken);
+
+    return jwtToken;
+}
+
+bool JWTAuth::verify(const std::string& accessToken)
+{
+    Poco::StringTokenizer tokens(accessToken, ".", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
+
+    std::string encodedBody = tokens[0] + "." + tokens[1];
+    _digestEngine.update(encodedBody.c_str(), static_cast<unsigned>(encodedBody.length()));
+    Poco::Crypto::DigestEngine::Digest digest = _digestEngine.signature();
+
+    std::ostringstream ostr;
+    Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
+    Poco::Base64Encoder encoder(lineEndingConv);
+
+    encoder << std::string(digest.begin(), digest.end());
+    encoder.close();
+    std::string encodedSig = ostr.str();
+
+    // trim '=' from end of encoded signature.
+    encodedSig.erase(std::find_if(encodedSig.rbegin(), encodedSig.rend(),
+                                  [](char& ch)->bool { return ch != '='; }).base(), encodedSig.end());
+
+    // Make the encoded sig URL and filename safe
+    std::replace(encodedSig.begin(), encodedSig.end(), '+', '-');
+    std::replace(encodedSig.begin(), encodedSig.end(), '/', '_');
+
+    if (encodedSig != tokens[2])
+    {
+        Log::info("JWTAuth::Token verification failed; Expected: " + encodedSig + ", Received: " + tokens[2]);
+        return false;
+    }
+
+    // TODO: Check for expiry etc.
+
+    return true;
+}
+
+const std::string JWTAuth::createHeader()
+{
+    // TODO: Some sane code to represent JSON objects
+    std::string header = "{\"alg\":\""+_alg+"\",\"typ\":\""+_typ+"\"}";
+
+    Log::info("JWT Header: " + header);
+    std::ostringstream ostr;
+    Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
+    Poco::Base64Encoder encoder(lineEndingConv);
+    encoder << header;
+    encoder.close();
+
+    return ostr.str();
+}
+
+const std::string JWTAuth::createPayload()
+{
+    std::time_t curtime = Poco::Timestamp().epochTime();
+    std::string exptime = std::to_string(curtime + 3600);
+
+    // TODO: Some sane code to represent JSON objects
+    std::string payload = "{\"iss\":\""+_iss+"\",\"sub\":\""+_sub+"\",\"aud\":\""+_aud+"\",\"nme\":\""+_name+"\",\"exp\":\""+exptime+"\"}";
+
+    Log::info("JWT Payload: " + payload);
+    std::ostringstream ostr;
+    Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
+    Poco::Base64Encoder encoder(lineEndingConv);
+    encoder << payload;
+    encoder.close();
+
+    return ostr.str();
+}
+
+
+//////////////
+// OAuth Impl
+//////////////
+
+//TODO: This MUST be done over TLS to protect the token.
+const std::string OAuth::getAccessToken()
+{
+    std::string url = _tokenEndPoint
+        + "?client_id=" + _clientId
+        + "&client_secret=" + _clientSecret
+        + "&grant_type=authorization_code"
+        + "&code=" + _authorizationCode;
+    // + "&redirect_uri="
+
+    Poco::URI uri(url);
+    Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
+    Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, url, Poco::Net::HTTPMessage::HTTP_1_1);
+    Poco::Net::HTTPResponse response;
+    session.sendRequest(request);
+    std::istream& rs = session.receiveResponse(response);
+    Log::info() << "Status: " <<  response.getStatus() << " " << response.getReason() << Log::end;
+    std::string reply(std::istreambuf_iterator<char>(rs), {});
+    Log::info("Response: " + reply);
+    //TODO: Parse the token.
+
+    return std::string();
+}
+
+bool OAuth::verify(const std::string& token)
+{
+    const std::string url = _authVerifyUrl + token;
+    Log::debug("Verifying authorization token from: " + url);
+    Poco::URI uri(url);
+    Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
+    Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, url, Poco::Net::HTTPMessage::HTTP_1_1);
+    Poco::Net::HTTPResponse response;
+    session.sendRequest(request);
+    std::istream& rs = session.receiveResponse(response);
+    Log::info() << "Status: " <<  response.getStatus() << " " << response.getReason() << Log::end;
+    std::string reply(std::istreambuf_iterator<char>(rs), {});
+    Log::info("Response: " + reply);
+
+    //TODO: Parse the response.
+    /*
+    // This is used for the demo site.
+    const auto lastLogTime = std::strtoul(reply.c_str(), nullptr, 0);
+    if (lastLogTime < 1)
+    {
+    //TODO: Redirect to login page.
+    return;
+    }
+    */
+
+    return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/Auth.hpp b/loolwsd/Auth.hpp
index fdc2fc1..f4e10a1 100644
--- a/loolwsd/Auth.hpp
+++ b/loolwsd/Auth.hpp
@@ -11,24 +11,10 @@
 #ifndef INCLUDED_AUTH_HPP
 #define INCLUDED_AUTH_HPP
 
-#include <cstdlib>
 #include <string>
 
-#include <Poco/Base64Encoder.h>
-#include <Poco/Base64Decoder.h>
 #include <Poco/Crypto/RSADigestEngine.h>
 #include <Poco/Crypto/RSAKey.h>
-#include <Poco/DigestEngine.h>
-#include <Poco/JSON/Object.h>
-#include <Poco/LineEndingConverter.h>
-#include <Poco/Net/HTTPClientSession.h>
-#include <Poco/Net/HTTPRequest.h>
-#include <Poco/Net/HTTPResponse.h>
-#include <Poco/StringTokenizer.h>
-#include <Poco/Timestamp.h>
-#include <Poco/URI.h>
-
-#include "Util.hpp"
 
 /// Base class of all Authentication/Authorization implementations.
 class AuthBase
@@ -53,127 +39,14 @@ public:
           _digestEngine(_key, "SHA256")
     {    }
 
-    const std::string getAccessToken()
-    {
-        std::string encodedHeader = createHeader();
-        std::string encodedPayload = createPayload();
-
-        // trim '=' from end of encoded header
-        encodedHeader.erase(std::find_if(encodedHeader.rbegin(), encodedHeader.rend(),
-                                         [](char& ch)->bool {return ch != '='; }).base(), encodedHeader.end());
-        // trim '=' from end of encoded payload
-        encodedPayload.erase(std::find_if(encodedPayload.rbegin(), encodedPayload.rend(),
-                                          [](char& ch)->bool { return ch != '='; }).base(), encodedPayload.end());
-        Log::info("Encoded JWT header: " + encodedHeader);
-        Log::info("Encoded JWT payload: " + encodedPayload);
-
-        // Convert to a URL and filename safe variant:
-        // Replace '+' with '-' && '/' with '_'
-        std::replace(encodedHeader.begin(), encodedHeader.end(), '+','-');
-        std::replace(encodedHeader.begin(), encodedHeader.end(), '/','_');
-
-        std::replace(encodedPayload.begin(), encodedPayload.end(), '+','-');
-        std::replace(encodedPayload.begin(), encodedPayload.end(), '/','_');
-
-        std::string encodedBody = encodedHeader  + "." +  encodedPayload;
-
-        // sign the encoded body
-        _digestEngine.update(encodedBody.c_str(), static_cast<unsigned>(encodedBody.length()));
-        Poco::Crypto::DigestEngine::Digest digest = _digestEngine.signature();
-
-        // The signature generated contains CRLF line endings.
-        // Use a line ending converter to remove these CRLF
-        std::ostringstream ostr;
-        Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
-        Poco::Base64Encoder encoder(lineEndingConv);
-        encoder << std::string(digest.begin(), digest.end());
-        encoder.close();
-        std::string encodedSig = ostr.str();
-
-        // trim '=' from end of encoded signature
-        encodedSig.erase(std::find_if(encodedSig.rbegin(), encodedSig.rend(),
-                                      [](char& ch)->bool { return ch != '='; }).base(), encodedSig.end());
-
-        // Be URL and filename safe
-        std::replace(encodedSig.begin(), encodedSig.end(), '+','-');
-        std::replace(encodedSig.begin(), encodedSig.end(), '/','_');
-
-        Log::info("Sig generated is : " + encodedSig);
-
-        const std::string jwtToken = encodedBody + "." + encodedSig;
-        Log::info("JWT token generated: " + jwtToken);
-
-        return jwtToken;
-    }
-
-    bool verify(const std::string& accessToken)
-    {
-        Poco::StringTokenizer tokens(accessToken, ".", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
-
-        std::string encodedBody = tokens[0] + "." + tokens[1];
-        _digestEngine.update(encodedBody.c_str(), static_cast<unsigned>(encodedBody.length()));
-        Poco::Crypto::DigestEngine::Digest digest = _digestEngine.signature();
-
-        std::ostringstream ostr;
-        Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
-        Poco::Base64Encoder encoder(lineEndingConv);
-
-        encoder << std::string(digest.begin(), digest.end());
-        encoder.close();
-        std::string encodedSig = ostr.str();
-
-        // trim '=' from end of encoded signature.
-        encodedSig.erase(std::find_if(encodedSig.rbegin(), encodedSig.rend(),
-                                      [](char& ch)->bool { return ch != '='; }).base(), encodedSig.end());
-
-        // Make the encoded sig URL and filename safe
-        std::replace(encodedSig.begin(), encodedSig.end(), '+', '-');
-        std::replace(encodedSig.begin(), encodedSig.end(), '/', '_');
+    const std::string getAccessToken() override;
 
-        if (encodedSig != tokens[2])
-        {
-            Log::info("JWTAuth::Token verification failed; Expected: " + encodedSig + ", Received: " + tokens[2]);
-            return false;
-        }
-
-        // TODO: Check for expiry etc.
-
-        return true;
-    }
+    bool verify(const std::string& accessToken) override;
 
 private:
-    const std::string createHeader()
-    {
-        // TODO: Some sane code to represent JSON objects
-        std::string header = "{\"alg\":\""+_alg+"\",\"typ\":\""+_typ+"\"}";
-
-        Log::info("JWT Header: " + header);
-        std::ostringstream ostr;
-        Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
-        Poco::Base64Encoder encoder(lineEndingConv);
-        encoder << header;
-        encoder.close();
-
-        return ostr.str();
-    }
-
-    const std::string createPayload()
-    {
-        std::time_t curtime = Poco::Timestamp().epochTime();
-        std::string exptime = std::to_string(curtime + 3600);
-
-        // TODO: Some sane code to represent JSON objects
-        std::string payload = "{\"iss\":\""+_iss+"\",\"sub\":\""+_sub+"\",\"aud\":\""+_aud+"\",\"nme\":\""+_name+"\",\"exp\":\""+exptime+"\"}";
+    const std::string createHeader();
 
-        Log::info("JWT Payload: " + payload);
-        std::ostringstream ostr;
-        Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
-        Poco::Base64Encoder encoder(lineEndingConv);
-        encoder << payload;
-        encoder.close();
-
-        return ostr.str();
-    }
+    const std::string createPayload();
 
 private:
     const std::string _alg = "RS256";
@@ -204,57 +77,9 @@ public:
     {
     }
 
-    //TODO: This MUST be done over TLS to protect the token.
-    const std::string getAccessToken() override
-    {
-        std::string url = _tokenEndPoint
-                        + "?client_id=" + _clientId
-                        + "&client_secret=" + _clientSecret
-                        + "&grant_type=authorization_code"
-                        + "&code=" + _authorizationCode;
-                        // + "&redirect_uri="
-
-        Poco::URI uri(url);
-        Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
-        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, url, Poco::Net::HTTPMessage::HTTP_1_1);
-        Poco::Net::HTTPResponse response;
-        session.sendRequest(request);
-        std::istream& rs = session.receiveResponse(response);
-        Log::info() << "Status: " <<  response.getStatus() << " " << response.getReason() << Log::end;
-        std::string reply(std::istreambuf_iterator<char>(rs), {});
-        Log::info("Response: " + reply);
-        //TODO: Parse the token.
-
-        return std::string();
-    }
-
-    bool verify(const std::string& token) override
-    {
-        const std::string url = _authVerifyUrl + token;
-        Log::debug("Verifying authorization token from: " + url);
-        Poco::URI uri(url);
-        Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
-        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, url, Poco::Net::HTTPMessage::HTTP_1_1);
-        Poco::Net::HTTPResponse response;
-        session.sendRequest(request);
-        std::istream& rs = session.receiveResponse(response);
-        Log::info() << "Status: " <<  response.getStatus() << " " << response.getReason() << Log::end;
-        std::string reply(std::istreambuf_iterator<char>(rs), {});
-        Log::info("Response: " + reply);
+    const std::string getAccessToken() override;
 
-        //TODO: Parse the response.
-        /*
-        // This is used for the demo site.
-        const auto lastLogTime = std::strtoul(reply.c_str(), nullptr, 0);
-        if (lastLogTime < 1)
-        {
-            //TODO: Redirect to login page.
-            return;
-        }
-        */
-
-        return true;
-    }
+    bool verify(const std::string& token) override;
 
 private:
     const std::string _clientId;
diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp
index 5390f67..5e35a86 100644
--- a/loolwsd/DocumentBroker.cpp
+++ b/loolwsd/DocumentBroker.cpp
@@ -7,6 +7,8 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include <cassert>
+
 #include <Poco/Path.h>
 #include <Poco/SHA1Engine.h>
 
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index 458ea85..7428229 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -12,7 +12,7 @@ AM_CTAGSFLAGS = $(AM_ETAGSFLAGS)
 
 shared_sources = LOOLProtocol.cpp LOOLSession.cpp MessageQueue.cpp IoUtil.cpp Util.cpp
 
-loolwsd_SOURCES = LOOLWSD.cpp ChildProcessSession.cpp MasterProcessSession.cpp TileCache.cpp Admin.cpp DocumentBroker.cpp $(shared_sources)
+loolwsd_SOURCES = LOOLWSD.cpp ChildProcessSession.cpp MasterProcessSession.cpp TileCache.cpp Admin.cpp DocumentBroker.cpp Auth.cpp Storage.cpp $(shared_sources)
 
 noinst_PROGRAMS = loadtest connect lokitclient
 
diff --git a/loolwsd/Storage.cpp b/loolwsd/Storage.cpp
new file mode 100644
index 0000000..f649a79
--- /dev/null
+++ b/loolwsd/Storage.cpp
@@ -0,0 +1,275 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <cassert>
+#include <string>
+#include <fstream>
+
+#include <Poco/Net/HTTPResponse.h>
+#include <Poco/Net/HTTPRequest.h>
+#include <Poco/Net/HTTPSClientSession.h>
+#include <Poco/Net/SSLManager.h>
+#include <Poco/StreamCopier.h>
+#include <Poco/JSON/Object.h>
+#include <Poco/JSON/Parser.h>
+
+#include "Common.hpp"
+#include "Auth.hpp"
+#include "Storage.hpp"
+#include "Util.hpp"
+
+///////////////////
+// StorageBase Impl
+///////////////////
+std::string StorageBase::getLocalRootPath() const
+{
+    auto localPath = _jailPath;
+    if (localPath[0] == '/')
+    {
+        // Remove the leading /
+        localPath.erase(0, 1);
+    }
+
+    // /chroot/jailId/user/doc/childId
+    const auto rootPath = Poco::Path(_localStorePath, localPath);
+    Poco::File(rootPath).createDirectories();
+
+    return rootPath.toString();
+}
+
+size_t StorageBase::getFileSize(const std::string& filename)
+{
+    return std::ifstream(filename, std::ifstream::ate | std::ifstream::binary).tellg();
+}
+
+////////////////////
+// LocalStorage Impl
+/////////////////////
+StorageBase::FileInfo LocalStorage::getFileInfo(const Poco::URI& uri)
+{
+    const auto path = uri.getPath();
+    Log::debug("Getting info for local uri [" + uri.toString() + "], path [" + path + "].");
+    const auto filename = Poco::Path(path).getFileName();
+    const auto lastModified = Poco::File(path).getLastModified();
+    const auto size = Poco::File(path).getSize();
+    return FileInfo({filename, lastModified, size});
+}
+
+std::string LocalStorage::loadStorageFileToLocal()
+{
+    const auto rootPath = getLocalRootPath();
+
+    // /chroot/jailId/user/doc/childId/file.ext
+    const auto filename = Poco::Path(_uri).getFileName();
+    _jailedFilePath = Poco::Path(rootPath, filename).toString();
+
+    Log::info("Public URI [" + _uri +
+              "] jailed to [" + _jailedFilePath + "].");
+
+    const auto publicFilePath = _uri;
+    Log::info("Linking " + publicFilePath + " to " + _jailedFilePath);
+    if (!Poco::File(_jailedFilePath).exists() && link(publicFilePath.c_str(), _jailedFilePath.c_str()) == -1)
+    {
+        // Failed
+        Log::warn("link(\"" + publicFilePath + "\", \"" + _jailedFilePath + "\") failed. Will copy.");
+    }
+
+    try
+    {
+        // Fallback to copying.
+        if (!Poco::File(_jailedFilePath).exists())
+        {
+            Log::info("Copying " + publicFilePath + " to " + _jailedFilePath);
+            Poco::File(publicFilePath).copyTo(_jailedFilePath);
+            _isCopy = true;
+        }
+    }
+    catch (const Poco::Exception& exc)
+    {
+        Log::error("copyTo(\"" + publicFilePath + "\", \"" + _jailedFilePath + "\") failed: " + exc.displayText());
+        throw;
+    }
+
+    // Now return the jailed path.
+    return Poco::Path(_jailPath, filename).toString();
+}
+
+bool LocalStorage::saveLocalFileToStorage()
+{
+    try
+    {
+        // Copy the file back.
+        if (_isCopy && Poco::File(_jailedFilePath).exists())
+        {
+            Log::info("Copying " + _jailedFilePath + " to " + _uri);
+            Poco::File(_jailedFilePath).copyTo(_uri);
+        }
+    }
+    catch (const Poco::Exception& exc)
+    {
+        Log::error("copyTo(\"" + _jailedFilePath + "\", \"" + _uri + "\") failed: " + exc.displayText());
+        throw;
+    }
+
+    return true;
+}
+
+///////////////////
+// WopiStorage Impl
+///////////////////
+StorageBase::FileInfo WopiStorage::getFileInfo(const Poco::URI& uri)
+{
+    Log::debug("Getting info for wopi uri [" + uri.toString() + "].");
+
+    Poco::URI uriObject(uri);
+    Poco::Net::HTTPSClientSession session(uriObject.getHost(), uriObject.getPort(), Poco::Net::SSLManager::instance().defaultClientContext());
+    Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
+    request.set("User-Agent", "LOOLWSD WOPI Agent");
+    session.sendRequest(request);
+
+    Poco::Net::HTTPResponse response;
+    std::istream& rs = session.receiveResponse(response);
+
+    auto logger = Log::trace();
+    logger << "WOPI::CheckFileInfo header for URI [" << uri.toString() << "]:\n";
+    for (auto& pair : response)
+    {
+        logger << '\t' + pair.first + ": " + pair.second << " / ";
+    }
+
+    logger << Log::end;
+
+    // Parse the response.
+    std::string filename;
+    size_t size = 0;
+    std::string resMsg;
+    Poco::StreamCopier::copyToString(rs, resMsg);
+    Log::debug("WOPI::CheckFileInfo returned: " + resMsg);
+    const auto index = resMsg.find_first_of("{");
+    if (index != std::string::npos)
+    {
+        const std::string stringJSON = resMsg.substr(index);
+        Poco::JSON::Parser parser;
+        const auto result = parser.parse(stringJSON);
+        const auto object = result.extract<Poco::JSON::Object::Ptr>();
+        filename = object->get("BaseFileName").toString();
+        size = std::stoul (object->get("Size").toString(), nullptr, 0);
+    }
+
+    // WOPI doesn't support file last modified time.
+    return FileInfo({filename, Poco::Timestamp(), size});
+}
+
+/// uri format: http://server/<...>/wopi*/files/<id>/content
+std::string WopiStorage::loadStorageFileToLocal()
+{
+    Log::info("Downloading URI [" + _uri + "].");
+
+    _fileInfo = getFileInfo(Poco::URI(_uri));
+    if (_fileInfo.Size == 0 && _fileInfo.Filename.empty())
+    {
+        //TODO: Should throw a more appropriate exception.
+        throw std::runtime_error("Failed to load file from storage.");
+    }
+
+    // WOPI URI to download files ends in '/contents'.
+    // Add it here to get the payload instead of file info.
+    Poco::URI uriObject(_uri);
+    const auto url = uriObject.getPath() + "/contents?" + uriObject.getQuery();
+    Log::debug("Wopi requesting: " + url);
+
+    Poco::Net::HTTPSClientSession session(uriObject.getHost(), uriObject.getPort(), Poco::Net::SSLManager::instance().defaultClientContext());
+    Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, url, Poco::Net::HTTPMessage::HTTP_1_1);
+    request.set("User-Agent", "LOOLWSD WOPI Agent");
+    session.sendRequest(request);
+
+    Poco::Net::HTTPResponse response;
+    std::istream& rs = session.receiveResponse(response);
+
+    auto logger = Log::trace();
+    logger << "WOPI::GetFile header for URI [" << _uri << "]:\n";
+    for (auto& pair : response)
+    {
+        logger << '\t' + pair.first + ": " + pair.second << " / ";
+    }
+
+    logger << Log::end;
+
+    _jailedFilePath = Poco::Path(getLocalRootPath(), _fileInfo.Filename).toString();
+    std::ofstream ofs(_jailedFilePath);
+    std::copy(std::istreambuf_iterator<char>(rs),
+              std::istreambuf_iterator<char>(),
+              std::ostreambuf_iterator<char>(ofs));
+    const auto size = getFileSize(_jailedFilePath);
+
+    Log::info() << "WOPI::GetFile downloaded " << size << " bytes from [" << _uri
+                << "] -> " << _jailedFilePath << ": "
+                << response.getStatus() << " " << response.getReason() << Log::end;
+
+    // Now return the jailed path.
+    return Poco::Path(_jailPath, _fileInfo.Filename).toString();
+}
+
+bool WopiStorage::saveLocalFileToStorage()
+{
+    Log::info("Uploading URI [" + _uri + "] from [" + _jailedFilePath + "].");
+    const auto size = getFileSize(_jailedFilePath);
+
+    Poco::URI uriObject(_uri);
+    const auto url = uriObject.getPath() + "/contents?" + uriObject.getQuery();
+    Log::debug("Wopi posting: " + url);
+
+    Poco::Net::HTTPSClientSession session(uriObject.getHost(), uriObject.getPort(), Poco::Net::SSLManager::instance().defaultClientContext());
+    Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, url, Poco::Net::HTTPMessage::HTTP_1_1);
+    request.set("X-WOPIOverride", "PUT");
+    request.setContentType("application/octet-stream");
+    request.setContentLength(size);
+
+    std::ostream& os = session.sendRequest(request);
+    std::ifstream ifs(_jailedFilePath);
+    Poco::StreamCopier::copyStream(ifs, os);
+
+    Poco::Net::HTTPResponse response;
+    std::istream& rs = session.receiveResponse(response);
+    std::ostringstream oss;
+    Poco::StreamCopier::copyStream(rs, oss);
+
+    Log::info("WOPI::PutFile response: " + oss.str());
+    const auto success = (response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK);
+    Log::info() << "WOPI::PutFile uploaded " << size << " bytes from [" << _jailedFilePath  << "]:"
+                << "] -> [" << _uri << "]: "
+                <<  response.getStatus() << " " << response.getReason() << Log::end;
+
+    return success;
+}
+
+//////////////////////
+// WebDAVStorage Impl
+///////////////////////
+StorageBase::FileInfo WebDAVStorage::getFileInfo(const Poco::URI& uri)
+{
+    Log::debug("Getting info for webdav uri [" + uri.toString() + "].");
+    (void)uri;
+    assert(!"Not Implemented!");
+    return FileInfo({"bazinga", Poco::Timestamp(), 0});
+}
+
+std::string WebDAVStorage::loadStorageFileToLocal()
+{
+    // TODO: implement webdav GET.
+    return _uri;
+}
+
+bool WebDAVStorage::saveLocalFileToStorage()
+{
+    // TODO: implement webdav PUT.
+    return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/Storage.hpp b/loolwsd/Storage.hpp
index 08bec04..9e46f3d 100644
--- a/loolwsd/Storage.hpp
+++ b/loolwsd/Storage.hpp
@@ -11,18 +11,10 @@
 #ifndef INCLUDED_STORAGE_HPP
 #define INCLUDED_STORAGE_HPP
 
-#include <cassert>
 #include <string>
-#include <fstream>
 
-#include <Poco/Net/HTTPResponse.h>
-#include <Poco/Net/HTTPSClientSession.h>
-#include <Poco/Net/SSLManager.h>
-#include <Poco/StreamCopier.h>
-#include <Poco/JSON/Object.h>
-#include <Poco/JSON/Parser.h>
+#include <Poco/URI.h>
 
-#include "Common.hpp"
 #include "Auth.hpp"
 #include "Util.hpp"
 
@@ -51,21 +43,7 @@ public:
         Log::debug("Storage ctor: " + uri);
     }
 
-    std::string getLocalRootPath() const
-    {
-        auto localPath = _jailPath;
-        if (localPath[0] == '/')
-        {
-            // Remove the leading /
-            localPath.erase(0, 1);
-        }
-
-        // /chroot/jailId/user/doc/childId
-        const auto rootPath = Poco::Path(_localStorePath, localPath);
-        Poco::File(rootPath).createDirectories();
-
-        return rootPath.toString();
-    }
+    std::string getLocalRootPath() const;
 
     const std::string& getUri() const { return _uri; }
 
@@ -83,10 +61,7 @@ public:
     virtual bool saveLocalFileToStorage() = 0;
 
     static
-    size_t getFileSize(const std::string& filename)
-    {
-        return std::ifstream(filename, std::ifstream::ate | std::ifstream::binary).tellg();
-    }
+    size_t getFileSize(const std::string& filename);
 
 protected:
     const std::string _localStorePath;
@@ -108,74 +83,11 @@ public:
     {
     }
 
-    FileInfo getFileInfo(const Poco::URI& uri) override
-    {
-        const auto path = uri.getPath();
-        Log::debug("Getting info for local uri [" + uri.toString() + "], path [" + path + "].");
-        const auto filename = Poco::Path(path).getFileName();
-        const auto lastModified = Poco::File(path).getLastModified();
-        const auto size = Poco::File(path).getSize();
-        return FileInfo({filename, lastModified, size});
-    }
-
-    std::string loadStorageFileToLocal() override
-    {
-        const auto rootPath = getLocalRootPath();
-
-        // /chroot/jailId/user/doc/childId/file.ext
-        const auto filename = Poco::Path(_uri).getFileName();
-        _jailedFilePath = Poco::Path(rootPath, filename).toString();
-
-        Log::info("Public URI [" + _uri +
-                  "] jailed to [" + _jailedFilePath + "].");
-
-        const auto publicFilePath = _uri;
-        Log::info("Linking " + publicFilePath + " to " + _jailedFilePath);
-        if (!Poco::File(_jailedFilePath).exists() && link(publicFilePath.c_str(), _jailedFilePath.c_str()) == -1)
-        {
-            // Failed
-            Log::warn("link(\"" + publicFilePath + "\", \"" + _jailedFilePath + "\") failed. Will copy.");
-        }
+    FileInfo getFileInfo(const Poco::URI& uri) override;
 
-        try
-        {
-            // Fallback to copying.
-            if (!Poco::File(_jailedFilePath).exists())
-            {
-                Log::info("Copying " + publicFilePath + " to " + _jailedFilePath);
-                Poco::File(publicFilePath).copyTo(_jailedFilePath);
-                _isCopy = true;
-            }
-        }
-        catch (const Poco::Exception& exc)
-        {
-            Log::error("copyTo(\"" + publicFilePath + "\", \"" + _jailedFilePath + "\") failed: " + exc.displayText());
-            throw;
-        }
+    std::string loadStorageFileToLocal() override;
 
-        // Now return the jailed path.
-        return Poco::Path(_jailPath, filename).toString();
-    }
-
-    bool saveLocalFileToStorage() override
-    {
-        try
-        {
-            // Copy the file back.
-            if (_isCopy && Poco::File(_jailedFilePath).exists())
-            {
-                Log::info("Copying " + _jailedFilePath + " to " + _uri);
-                Poco::File(_jailedFilePath).copyTo(_uri);
-            }
-        }
-        catch (const Poco::Exception& exc)
-        {
-            Log::error("copyTo(\"" + _jailedFilePath + "\", \"" + _uri + "\") failed: " + exc.displayText());
-            throw;
-        }
-
-        return true;
-    }
+    bool saveLocalFileToStorage() override;
 
 private:
     /// True if the jailed file is not linked but copied.
@@ -192,131 +104,12 @@ public:
     {
     }
 
-    FileInfo getFileInfo(const Poco::URI& uri) override
-    {
-        Log::debug("Getting info for wopi uri [" + uri.toString() + "].");
-
-        Poco::URI uriObject(uri);
-        Poco::Net::HTTPSClientSession session(uriObject.getHost(), uriObject.getPort(), Poco::Net::SSLManager::instance().defaultClientContext());
-        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
-        request.set("User-Agent", "LOOLWSD WOPI Agent");
-        session.sendRequest(request);
-
-        Poco::Net::HTTPResponse response;
-        std::istream& rs = session.receiveResponse(response);
-
-        auto logger = Log::trace();
-        logger << "WOPI::CheckFileInfo header for URI [" << uri.toString() << "]:\n";
-        for (auto& pair : response)
-        {
-            logger << '\t' + pair.first + ": " + pair.second << " / ";
-        }
-
-        logger << Log::end;
-
-        // Parse the response.
-        std::string filename;
-        size_t size = 0;
-        std::string resMsg;
-        Poco::StreamCopier::copyToString(rs, resMsg);
-        Log::debug("WOPI::CheckFileInfo returned: " + resMsg);
-        const auto index = resMsg.find_first_of("{");
-        if (index != std::string::npos)
-        {
-            const std::string stringJSON = resMsg.substr(index);
-            Poco::JSON::Parser parser;
-            const auto result = parser.parse(stringJSON);
-            const auto object = result.extract<Poco::JSON::Object::Ptr>();
-            filename = object->get("BaseFileName").toString();
-            size = std::stoul (object->get("Size").toString(), nullptr, 0);
-        }
-
-        // WOPI doesn't support file last modified time.
-        return FileInfo({filename, Poco::Timestamp(), size});
-    }
+    FileInfo getFileInfo(const Poco::URI& uri) override;
 
     /// uri format: http://server/<...>/wopi*/files/<id>/content
-    std::string loadStorageFileToLocal() override
-    {
-        Log::info("Downloading URI [" + _uri + "].");
-
-        _fileInfo = getFileInfo(Poco::URI(_uri));
-        if (_fileInfo.Size == 0 && _fileInfo.Filename.empty())
-        {
-            //TODO: Should throw a more appropriate exception.
-            throw std::runtime_error("Failed to load file from storage.");
-        }
-
-        // WOPI URI to download files ends in '/contents'.
-        // Add it here to get the payload instead of file info.
-        Poco::URI uriObject(_uri);
-        const auto url = uriObject.getPath() + "/contents?" + uriObject.getQuery();
-        Log::debug("Wopi requesting: " + url);
-
-        Poco::Net::HTTPSClientSession session(uriObject.getHost(), uriObject.getPort(), Poco::Net::SSLManager::instance().defaultClientContext());
-        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, url, Poco::Net::HTTPMessage::HTTP_1_1);
-        request.set("User-Agent", "LOOLWSD WOPI Agent");
-        session.sendRequest(request);
-
-        Poco::Net::HTTPResponse response;
-        std::istream& rs = session.receiveResponse(response);
-
-        auto logger = Log::trace();
-        logger << "WOPI::GetFile header for URI [" << _uri << "]:\n";
-        for (auto& pair : response)
-        {
-            logger << '\t' + pair.first + ": " + pair.second << " / ";
-        }
-
-        logger << Log::end;
-
-        _jailedFilePath = Poco::Path(getLocalRootPath(), _fileInfo.Filename).toString();
-        std::ofstream ofs(_jailedFilePath);
-        std::copy(std::istreambuf_iterator<char>(rs),
-                  std::istreambuf_iterator<char>(),
-                  std::ostreambuf_iterator<char>(ofs));
-        const auto size = getFileSize(_jailedFilePath);
-
-        Log::info() << "WOPI::GetFile downloaded " << size << " bytes from [" << _uri
-                    << "] -> " << _jailedFilePath << ": "
-                    << response.getStatus() << " " << response.getReason() << Log::end;
-
-        // Now return the jailed path.
-        return Poco::Path(_jailPath, _fileInfo.Filename).toString();
-    }
-
-    bool saveLocalFileToStorage() override
-    {
-        Log::info("Uploading URI [" + _uri + "] from [" + _jailedFilePath + "].");
-        const auto size = getFileSize(_jailedFilePath);
+    std::string loadStorageFileToLocal() override;
 
-        Poco::URI uriObject(_uri);
-        const auto url = uriObject.getPath() + "/contents?" + uriObject.getQuery();
-        Log::debug("Wopi posting: " + url);
-
-        Poco::Net::HTTPSClientSession session(uriObject.getHost(), uriObject.getPort(), Poco::Net::SSLManager::instance().defaultClientContext());
-        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, url, Poco::Net::HTTPMessage::HTTP_1_1);
-        request.set("X-WOPIOverride", "PUT");
-        request.setContentType("application/octet-stream");
-        request.setContentLength(size);
-
-        std::ostream& os = session.sendRequest(request);
-        std::ifstream ifs(_jailedFilePath);
-        Poco::StreamCopier::copyStream(ifs, os);
-
-        Poco::Net::HTTPResponse response;
-        std::istream& rs = session.receiveResponse(response);
-        std::ostringstream oss;
-        Poco::StreamCopier::copyStream(rs, oss);
-
-        Log::info("WOPI::PutFile response: " + oss.str());
-        const auto success = (response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK);
-        Log::info() << "WOPI::PutFile uploaded " << size << " bytes from [" << _jailedFilePath  << "]:"
-                    << "] -> [" << _uri << "]: "
-                    <<  response.getStatus() << " " << response.getReason() << Log::end;
-
-        return success;
-    }
+    bool saveLocalFileToStorage() override;
 };
 
 class WebDAVStorage : public StorageBase
@@ -331,25 +124,11 @@ public:
     {
     }
 
-    FileInfo getFileInfo(const Poco::URI& uri) override
-    {
-        Log::debug("Getting info for webdav uri [" + uri.toString() + "].");
-        (void)uri;
-        assert(!"Not Implemented!");
-        return FileInfo({"bazinga", Poco::Timestamp(), 0});
-    }
+    FileInfo getFileInfo(const Poco::URI& uri) override;
 
-    std::string loadStorageFileToLocal() override
-    {
-        // TODO: implement webdav GET.
-        return _uri;
-    }
+    std::string loadStorageFileToLocal() override;
 
-    bool saveLocalFileToStorage() override
-    {
-        // TODO: implement webdav PUT.
-        return false;
-    }
+    bool saveLocalFileToStorage() override;
 
 private:
     std::unique_ptr<AuthBase> _authAgent;


More information about the Libreoffice-commits mailing list