[Libreoffice-commits] online.git: loolwsd/LOOLSession.cpp

Henry Castro hcastro at collabora.com
Sat Jul 4 18:00:09 PDT 2015


 loolwsd/LOOLSession.cpp |  113 ++++++++++++++++++++++++++++++------------------
 1 file changed, 71 insertions(+), 42 deletions(-)

New commits:
commit e50e3028399563c0e66855469737ddcd842e8f3d
Author: Henry Castro <hcastro at collabora.com>
Date:   Sat Jul 4 20:46:13 2015 -0400

    loolwsd: Handle file URI schema
    
    In the file:// case, if it is on linux, hard link function is used
    and copy only if hard link fails.

diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp
index f66dbbe..14feb33 100644
--- a/loolwsd/LOOLSession.cpp
+++ b/loolwsd/LOOLSession.cpp
@@ -42,6 +42,7 @@
 #include <Poco/URI.h>
 #include <Poco/URIStreamOpener.h>
 #include <Poco/Util/Application.h>
+#include <Poco/Exception.h>
 
 #include "LOKitHelper.hpp"
 #include "LOOLProtocol.hpp"
@@ -68,6 +69,7 @@ using Poco::UInt64;
 using Poco::URI;
 using Poco::URIStreamOpener;
 using Poco::Util::Application;
+using Poco::Exception;
 
 const std::string LOOLSession::jailDocumentURL = "/user/thedocument";
 
@@ -487,6 +489,16 @@ bool MasterProcessSession::loadDocument(const char *buffer, int length, StringTo
     else
         _docURL = tokens[1];
 
+    try
+    {
+        URI aUri(_docURL);
+    }
+    catch(Poco::SyntaxException&)
+    {
+        sendTextFrame("error: cmd=load kind=URI invalid syntax");
+        return false;
+    }
+
     _tileCache.reset(new TileCache(_docURL));
 
     return true;
@@ -597,48 +609,53 @@ void MasterProcessSession::dispatchChild()
     std::cout << Util::logPrefix() << "_availableChildSessions size=" << _availableChildSessions.size() << std::endl;
     lock.unlock();
 
-    if (_docURL.find("http:"))
+    // Assume a valid URI
+    URI aUri(_docURL);
+
+    if (aUri.isRelative())
+        aUri = URI( URI("file://"), aUri.toString() );
+
+    if (!aUri.empty() && aUri.getScheme() == "file")
     {
-        assert(jailDocumentURL[0] == '/');
-        Path copy(getJailPath(childSession->_childId), jailDocumentURL.substr(1));
-        Application::instance().logger().information(Util::logPrefix() + "Copying " + _docURL + " to " + copy.toString());
+        Path aSrcFile(aUri.getPath());
+        Path aDstFile(Path(getJailPath(childSession->_childId), jailDocumentURL.substr(1)), aSrcFile.getFileName());
+        Path aDstPath(getJailPath(childSession->_childId), jailDocumentURL.substr(1));
+        Path aJailFile(jailDocumentURL, aSrcFile.getFileName());
 
-        URIStreamOpener opener;
-        opener.registerStreamFactory("http", new HTTPStreamFactory());
         try
         {
-            std::istream *input = opener.open(_docURL);
-            std::ofstream output(copy.toString());
-            if (!output)
-            {
-                Application::instance().logger().error(Util::logPrefix() + "Could not open " + copy.toString() + " for writing");
-                sendTextFrame("error: cmd=load kind=internal");
-
-                // We did not use the child session after all
-                // FIXME: Why do we do the same thing both here and then when we catch the IOException that we throw, a dozen line below?
-                lock.lock();
-                _availableChildSessions.insert(childSession);
-                std::cout << Util::logPrefix() << "_availableChildSessions size=" << _availableChildSessions.size() << std::endl;
-                lock.unlock();
-                throw IOException(copy.toString());
-            }
-            StreamCopier::copyStream(*input, output);
-            output.close();
-
-            Application::instance().logger().information(Util::logPrefix() + "Copying done");
+            File(aDstPath).createDirectories();
         }
-        catch (IOException& exc)
+        catch (Exception& exc)
         {
-            Application::instance().logger().error(Util::logPrefix() + "Copying failed: " + exc.message());
-            sendTextFrame("error: cmd=load kind=failed");
+            Application::instance().logger().error( Util::logPrefix() +
+                "createDirectories(\"" + aDstPath.toString() + "\") failed: " + exc.displayText() );
 
-            // FIXME: See above FIXME
-            lock.lock();
-            _availableChildSessions.insert(childSession);
-            std::cout << Util::logPrefix() << "_availableChildSessions size=" << _availableChildSessions.size() << std::endl;
-            lock.unlock();
+        }
+
+#ifdef __linux
+        Application::instance().logger().information(Util::logPrefix() + "Linking " + aSrcFile.toString() + " to " + aDstFile.toString());
+        if (link(aSrcFile.toString().c_str(), aDstFile.toString().c_str()) == -1)
+        {
+            // Failed
+            Application::instance().logger().error( Util::logPrefix() +
+                "link(\"" + aSrcFile.toString() + "\",\"" + aDstFile.toString() + "\") failed: " + strerror(errno) );
+        }
+#endif
 
-            throw;
+        try
+        {
+            //fallback
+            if (!File(aDstFile).exists())
+            {
+                Application::instance().logger().information(Util::logPrefix() + "Copying " + aSrcFile.toString() + " to " + aDstFile.toString());
+                File(aSrcFile).copyTo(aDstFile.toString());
+            }
+        }
+        catch (Exception& exc)
+        {
+            Application::instance().logger().error( Util::logPrefix() +
+                "copyTo(\"" + aSrcFile.toString() + "\",\"" + aDstFile.toString() + "\") failed: " + exc.displayText());
         }
     }
 
@@ -848,25 +865,37 @@ bool ChildProcessSession::loadDocument(const char *buffer, int length, StringTok
     else
         _docURL = tokens[1];
 
+    URI aUri;
+    try
+    {
+        aUri = URI(_docURL);
+    }
+    catch(Poco::SyntaxException&)
+    {
+        sendTextFrame("error: cmd=load kind=URI invalid syntax");
+        return false;
+    }
+
+    if (aUri.empty())
+    {
+        sendTextFrame("error: cmd=load kind=URI empty");
+        return false;
+    }
+
     // The URL in the request is the original one, not visible in the chroot jail.
     // The child process uses the fixed name jailDocumentURL.
 
     if (LIBREOFFICEKIT_HAS(_loKit, registerCallback))
         _loKit->pClass->registerCallback(_loKit, myCallback, this);
 
-    std::string sURL;
-
-    if ( _docURL.find("http:") )
-        sURL = _docURL;
-    else
-        sURL = jailDocumentURL;
+    if (aUri.isRelative() || aUri.getScheme() == "file")
+        aUri = URI( URI("file://"), Path(jailDocumentURL, Path(aUri.getPath()).getFileName()).toString() );
 
-    if ((_loKitDocument = _loKit->pClass->documentLoad(_loKit, sURL.c_str())) == NULL)
+    if ((_loKitDocument = _loKit->pClass->documentLoad(_loKit, aUri.toString().c_str())) == NULL)
     {
         sendTextFrame("error: cmd=load kind=failed");
         return false;
     }
-
     _loKitDocument->pClass->initializeForRendering(_loKitDocument);
 
     if (!getStatus(buffer, length))


More information about the Libreoffice-commits mailing list