wsd/DocumentBroker.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++- wsd/LOOLWSD.cpp | 31 ++++++++++++++++++++++++++++ wsd/LOOLWSD.hpp | 4 +++ wsd/Storage.hpp | 8 +++++++ 4 files changed, 96 insertions(+), 1 deletion(-)
New commits: commit 7c77a6c3a33fea7810275649465635ebd0fda2bf Author: Tor Lillqvist <t...@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. diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 45396631..69cd515b 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -19,6 +19,7 @@ #include <sstream> #include <Poco/DigestStream.h> +#include <Poco/Exception.h> #include <Poco/JSON/Object.h> #include <Poco/Path.h> #include <Poco/SHA1Engine.h> @@ -559,7 +560,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 52df9d14..c4aff64f 100644 --- a/wsd/Storage.hpp +++ b/wsd/Storage.hpp @@ -131,6 +131,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 commit 0831a942998144b606bea9c75a1cfe1bc165eff3 Author: Tor Lillqvist <t...@collabora.com> Date: Tue Nov 7 15:12:18 2017 +0200 Add a "plug-in" mechanism Look in the directory LOOLWSD_CONFIGDIR/conf.d (or pathname passed with --config-dir option) for extra .xml files containing a Poco configuration tree. These are not merged with the actual configuration but kept separate. This commit does not yet actually use them for anything. diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 83436634..f73f81f3 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -54,6 +54,7 @@ #include <Poco/DOM/Element.h> #include <Poco/DOM/NodeList.h> #include <Poco/DateTimeFormatter.h> +#include <Poco/DirectoryIterator.h> #include <Poco/Environment.h> #include <Poco/Exception.h> #include <Poco/File.h> @@ -78,12 +79,14 @@ #include <Poco/TemporaryFile.h> #include <Poco/ThreadPool.h> #include <Poco/URI.h> +#include <Poco/Util/AbstractConfiguration.h> #include <Poco/Util/HelpFormatter.h> #include <Poco/Util/MapConfiguration.h> #include <Poco/Util/Option.h> #include <Poco/Util/OptionException.h> #include <Poco/Util/OptionSet.h> #include <Poco/Util/ServerApplication.h> +#include <Poco/Util/XMLConfiguration.h> #include "Admin.hpp" #include "Auth.hpp" @@ -121,6 +124,7 @@ using namespace LOOLProtocol; +using Poco::DirectoryIterator; using Poco::Environment; using Poco::Exception; using Poco::File; @@ -153,6 +157,7 @@ using Poco::Util::MissingOptionException; using Poco::Util::Option; using Poco::Util::OptionSet; using Poco::Util::ServerApplication; +using Poco::Util::XMLConfiguration; using Poco::XML::AutoPtr; using Poco::XML::DOMParser; using Poco::XML::DOMWriter; @@ -557,12 +562,14 @@ std::string LOOLWSD::ServerName; std::string LOOLWSD::FileServerRoot; std::string LOOLWSD::LOKitVersion; std::string LOOLWSD::ConfigFile = LOOLWSD_CONFIGDIR "/loolwsd.xml"; +std::string LOOLWSD::ConfigDir = LOOLWSD_CONFIGDIR "/conf.d"; Util::RuntimeConstant<bool> LOOLWSD::SSLEnabled; Util::RuntimeConstant<bool> LOOLWSD::SSLTermination; std::set<std::string> LOOLWSD::EditFileExtensions; unsigned LOOLWSD::MaxConnections; unsigned LOOLWSD::MaxDocuments; std::string LOOLWSD::OverrideWatermark; +std::set<const Poco::Util::AbstractConfiguration*> LOOLWSD::PluginConfigurations; static std::string UnitTestLibrary; @@ -687,6 +694,23 @@ void LOOLWSD::initialize(Application& self) loadConfiguration(ConfigFile, PRIO_DEFAULT); } + // Load extra ("plug-in") configuration files, if present + File dir(ConfigDir); + if (dir.exists() && dir.isDirectory()) + { + for (auto configFileIterator = DirectoryIterator(dir); configFileIterator != DirectoryIterator(); ++configFileIterator) + { + // Only accept configuration files ending in .xml + const std::string configFile = configFileIterator.path().getFileName(); + if (configFile.length() > 4 && strcasecmp(configFile.substr(configFile.length() - 4).data(), ".xml") == 0) + { + const std::string fullFileName = dir.path() + "/" + configFile; + std::cerr << "Trying '" << fullFileName << "'" << std::endl; + PluginConfigurations.insert(new XMLConfiguration(fullFileName)); + } + } + } + // Override any settings passed on the command-line. AutoPtr<AppConfigMap> overrideConfig(new AppConfigMap(_overrideSettings)); conf.addWriteable(overrideConfig, PRIO_APPLICATION); // Highest priority @@ -999,6 +1023,11 @@ void LOOLWSD::defineOptions(OptionSet& optionSet) .repeatable(false) .argument("path")); + optionSet.addOption(Option("config-dir", "", "Override extra configuration directory path.") + .required(false) + .repeatable(false) + .argument("path")); + #if ENABLE_DEBUG optionSet.addOption(Option("unitlib", "", "Unit testing library path.") .required(false) @@ -1051,6 +1080,8 @@ void LOOLWSD::handleOption(const std::string& optionName, } else if (optionName == "config-file") ConfigFile = value; + else if (optionName == "config-dir") + ConfigDir = value; #if ENABLE_DEBUG else if (optionName == "unitlib") UnitTestLibrary = value; diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp index c61956a1..40a32b73 100644 --- a/wsd/LOOLWSD.hpp +++ b/wsd/LOOLWSD.hpp @@ -12,10 +12,12 @@ #include <atomic> #include <map> +#include <set> #include <string> #include <Poco/Path.h> #include <Poco/Process.h> +#include <Poco/Util/AbstractConfiguration.h> #include <Poco/Util/OptionSet.h> #include <Poco/Util/ServerApplication.h> @@ -46,6 +48,7 @@ public: static std::string FuzzFileName; static std::string Cache; static std::string ConfigFile; + static std::string ConfigDir; static std::string SysTemplate; static std::string LoTemplate; static std::string ChildRoot; @@ -59,6 +62,7 @@ public: static unsigned MaxConnections; static unsigned MaxDocuments; static std::string OverrideWatermark; + static std::set<const Poco::Util::AbstractConfiguration*> PluginConfigurations; static std::vector<int> getKitPids(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits