[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