wsd/LOOLWSD.cpp |   92 +++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 61 insertions(+), 31 deletions(-)

New commits:
commit 44f4ba27304387476cfd30f7531007a2fb5affb7
Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk>
Date:   Tue Jun 6 22:33:21 2017 -0400

    wsd: discovery.xml now preprocessed and cached
    
    Change-Id: Ie2f274452e9bd3a65061e24582a7280646162cdf
    Reviewed-on: https://gerrit.libreoffice.org/38479
    Reviewed-by: Ashod Nakashian <ashnak...@gmail.com>
    Tested-by: Ashod Nakashian <ashnak...@gmail.com>

diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 7c188f17..445027e2 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1538,6 +1538,11 @@ public:
     {
     }
 
+    static void InitStaticFileContentCache()
+    {
+        StaticFileContentCache["discovery.xml"] = getDiscoveryXML();
+    }
+
 private:
 
     /// Set the socket associated with this ResponseClient.
@@ -1752,36 +1757,9 @@ private:
     {
         LOG_DBG("Wopi discovery request: " << request.getURI());
 
-        // http://server/hosting/discovery
-        std::string discoveryPath = 
Path(Application::instance().commandPath()).parent().toString() + 
"discovery.xml";
-        if (!File(discoveryPath).exists())
-        {
-            discoveryPath = LOOLWSD::FileServerRoot + "/discovery.xml";
-        }
-
-        const std::string mediaType = "text/xml";
-        const std::string action = "action";
-        const std::string urlsrc = "urlsrc";
-        const auto& config = Application::instance().config();
-        const std::string loleafletHtml = config.getString("loleaflet_html", 
"loleaflet.html");
-        const std::string uriValue = ((LOOLWSD::isSSLEnabled() || 
LOOLWSD::isSSLTermination()) ? "https://"; : "http://";)
-                                   + (LOOLWSD::ServerName.empty() ? 
request.getHost() : LOOLWSD::ServerName)
-                                   + "/loleaflet/" LOOLWSD_VERSION_HASH "/" + 
loleafletHtml + '?';
-
-        InputSource inputSrc(discoveryPath);
-        DOMParser parser;
-        AutoPtr<Poco::XML::Document> docXML = parser.parse(&inputSrc);
-        AutoPtr<NodeList> listNodes = docXML->getElementsByTagName(action);
-
-        for (unsigned long it = 0; it < listNodes->length(); ++it)
-        {
-            static_cast<Element*>(listNodes->item(it))->setAttribute(urlsrc, 
uriValue);
-        }
-
-        std::ostringstream ostrXML;
-        DOMWriter writer;
-        writer.writeNode(ostrXML, docXML);
-        const std::string xml = ostrXML.str();
+        std::string xml = getFileContent("discovery.xml");
+        const std::string hostname = (LOOLWSD::ServerName.empty() ? 
request.getHost() : LOOLWSD::ServerName);
+        Poco::replaceInPlace(xml, std::string("%SERVER_HOST%"), hostname);
 
         // TODO: Refactor this to some common handler.
         std::ostringstream oss;
@@ -1789,7 +1767,7 @@ private:
             << "Last-Modified: " << 
Poco::DateTimeFormatter::format(Poco::Timestamp(), 
Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
             << "User-Agent: " << WOPI_AGENT_STRING << "\r\n"
             << "Content-Length: " << xml.size() << "\r\n"
-            << "Content-Type: " << mediaType << "\r\n"
+            << "Content-Type: text/xml\r\n"
             << "X-Content-Type-Options: nosniff\r\n"
             << "\r\n"
             << xml;
@@ -2161,12 +2139,62 @@ private:
         }
     }
 
+    /// Lookup cached file content.
+    const std::string& getFileContent(const std::string& filename)
+    {
+        const auto it = StaticFileContentCache.find(filename);
+        if (it == StaticFileContentCache.end())
+        {
+            throw Poco::FileAccessDeniedException("Invalid or forbidden file 
path: [" + filename + "].");
+        }
+
+        return it->second;
+    }
+
+    /// Process the discovery.xml file and return as string.
+    static std::string getDiscoveryXML()
+    {
+        // http://server/hosting/discovery
+        std::string discoveryPath = 
Path(Application::instance().commandPath()).parent().toString() + 
"discovery.xml";
+        if (!File(discoveryPath).exists())
+        {
+            discoveryPath = LOOLWSD::FileServerRoot + "/discovery.xml";
+        }
+
+        const std::string action = "action";
+        const std::string urlsrc = "urlsrc";
+        const auto& config = Application::instance().config();
+        const std::string loleafletHtml = config.getString("loleaflet_html", 
"loleaflet.html");
+        const std::string uriValue = ((LOOLWSD::isSSLEnabled() || 
LOOLWSD::isSSLTermination()) ? "https://"; : "http://";)
+                                   + std::string("%SERVER_HOST%")
+                                   + "/loleaflet/" LOOLWSD_VERSION_HASH "/" + 
loleafletHtml + '?';
+
+        InputSource inputSrc(discoveryPath);
+        DOMParser parser;
+        AutoPtr<Poco::XML::Document> docXML = parser.parse(&inputSrc);
+        AutoPtr<NodeList> listNodes = docXML->getElementsByTagName(action);
+
+        for (unsigned long it = 0; it < listNodes->length(); ++it)
+        {
+            static_cast<Element*>(listNodes->item(it))->setAttribute(urlsrc, 
uriValue);
+        }
+
+        std::ostringstream ostrXML;
+        DOMWriter writer;
+        writer.writeNode(ostrXML, docXML);
+        return ostrXML.str();
+    }
+
 private:
     // The socket that owns us (we can't own it).
     std::weak_ptr<StreamSocket> _socket;
     std::string _id;
+
+    /// Cache for static files, to avoid reading and processing from disk.
+    static std::map<std::string, std::string> StaticFileContentCache;
 };
 
+std::map<std::string, std::string> 
ClientRequestDispatcher::StaticFileContentCache;
 
 class PlainSocketFactory : public SocketFactory
 {
@@ -2469,6 +2497,8 @@ int LOOLWSD::innerMain()
     if (ClientPortNumber == MasterPortNumber)
         throw IncompatibleOptionsException("port");
 
+    ClientRequestDispatcher::InitStaticFileContentCache();
+
     // Start the internal prisoner server and spawn forkit,
     // which in turn forks first child.
     srv.startPrisoners(MasterPortNumber);
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to