[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - wsd/DocumentBroker.cpp wsd/Storage.hpp

Tor Lillqvist tml at collabora.com
Tue Nov 14 13:10:49 UTC 2017


 wsd/DocumentBroker.cpp |   54 ++++++++++++++++++++++++++++++++++++++++++++++++-
 wsd/Storage.hpp        |    8 +++++++
 2 files changed, 61 insertions(+), 1 deletion(-)

New commits:
commit 2ed9d4c5ce5bfb9d61df157b23457565009d00d7
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Nov 7 15:15:36 2017 +0200

    Add handling of "prefilter" plug-ins
    
    When the name of a document to be edited ends with an extension
    matching that mentioned in a prefilter plug-in's configuration file,
    the command specified is run and it is the output file that is
    actually edited.
    
    Change-Id: I3f107a50bb25a5a93e52932ba3c40a8758a1dc35
    Reviewed-on: https://gerrit.libreoffice.org/44718
    Reviewed-by: Aron Budea <aron.budea at collabora.com>
    Tested-by: Aron Budea <aron.budea at collabora.com>

diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 0d5e7342..93d285f9 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -21,6 +21,7 @@
 #include <Poco/Path.h>
 #include <Poco/SHA1Engine.h>
 #include <Poco/DigestStream.h>
+#include <Poco/Exception.h>
 #include <Poco/StreamCopier.h>
 #include <Poco/StringTokenizer.h>
 
@@ -534,7 +535,58 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
     // Let's load the document now, if not loaded.
     if (!_storage->isLoaded())
     {
-        const auto localPath = _storage->loadStorageFileToLocal(session->getAuthorization());
+        auto localPath = _storage->loadStorageFileToLocal(session->getAuthorization());
+
+        // Check if we have a prefilter "plugin" for this document format
+        for (const auto& plugin : LOOLWSD::PluginConfigurations)
+        {
+            try
+            {
+                std::string extension(plugin->getString("prefilter.extension"));
+                std::string newExtension(plugin->getString("prefilter.newextension"));
+                std::string commandLine(plugin->getString("prefilter.commandline"));
+
+                if (localPath.length() > extension.length()+1 &&
+                    strcasecmp(localPath.substr(localPath.length() - extension.length() -1).data(), (std::string(".") + extension).data()) == 0)
+                {
+                    // Extension matches, try the conversion. We convert the file to another one in
+                    // the same (jail) directory, with just the new extension tacked on.
+
+                    std::string newRootPath = _storage->getRootFilePath() + "." + newExtension;
+
+                    // The commandline must contain the space-separated substring @INPUT@ that is
+                    // replaced with the input file name, and @OUTPUT@ for the output file name.
+
+                    std::vector<std::string>args;
+
+                    Poco::StringTokenizer tokenizer(commandLine, " ");
+                    if (tokenizer.replace("@INPUT@", _storage->getRootFilePath()) != 1 ||
+                        tokenizer.replace("@OUTPUT@", newRootPath) != 1)
+                        throw Poco::NotFoundException();
+
+                    for (std::size_t i = 1; i < tokenizer.count(); i++)
+                        args.push_back(tokenizer[i]);
+
+                    Poco::ProcessHandle process = Poco::Process::launch(tokenizer[0], args);
+                    int rc = process.wait();
+                    if (rc != 0)
+                    {
+                        LOG_ERR("Conversion from " << extension << " to " << newExtension <<" failed");
+                        return false;
+                    }
+                    _storage->setRootFilePath(newRootPath);
+                    localPath += "." + newExtension;
+                }
+
+                // We successfully converted the file to something LO can use; break out of the for
+                // loop.
+                break;
+            }
+            catch (const Poco::NotFoundException&)
+            {
+                // This plugin is not a proper prefilter one
+            }
+        }
 
         std::ifstream istr(localPath, std::ios::binary);
         Poco::SHA1Engine sha1;
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index 90dad874..c15ed130 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -129,6 +129,14 @@ public:
     /// Returns the root path to the jailed file.
     const std::string& getRootFilePath() const { return _jailedFilePath; };
 
+    /// Set the root path of the jailed file, only for use in cases where we actually have converted
+    /// it to another format, in the same directory
+    void setRootFilePath(const std::string& newPath)
+    {
+        // Could assert here that it is in the same directory?
+        _jailedFilePath = newPath;
+    };
+
     bool isLoaded() const { return _isLoaded; }
 
     /// Asks the storage object to force overwrite to storage upon next save


More information about the Libreoffice-commits mailing list