[Libreoffice-commits] online.git: loolwsd/DocumentBroker.hpp loolwsd/LOOLWSD.cpp loolwsd/Storage.hpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Wed Mar 23 00:05:16 UTC 2016
loolwsd/DocumentBroker.hpp | 8 +++
loolwsd/LOOLWSD.cpp | 3 +
loolwsd/Storage.hpp | 95 +++++++++++++++++++++++++++++++++++++++++----
3 files changed, 99 insertions(+), 7 deletions(-)
New commits:
commit ef95d51b672b336772d832aad4c0c899955d1786
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Mon Mar 21 19:12:00 2016 -0400
loolwsd: FileInfo used to authenticate and store with original name
Change-Id: I94105441134ded2146736affba7b763eb3d54791
Reviewed-on: https://gerrit.libreoffice.org/23452
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp
index 3f7c75e..471df0c 100644
--- a/loolwsd/DocumentBroker.hpp
+++ b/loolwsd/DocumentBroker.hpp
@@ -77,6 +77,13 @@ public:
Log::info("~DocumentBroker [" + _uriPublic.toString() + "] destroyed.");
}
+ void validate(const Poco::URI& uri)
+ {
+ Log::info("validating: " + uri.toString());
+ auto storage = createStorage("", "", uri);
+ storage->getFileInfo(uri.toString());
+ }
+
/// Loads a document from the public URI into the jail.
bool load(const std::string& jailId)
{
@@ -136,6 +143,7 @@ private:
const std::string _childRoot;
Poco::URI _uriJailed;
std::string _jailId;
+ std::string _filename;
std::unique_ptr<StorageBase> _storage;
std::mutex _mutex;
std::atomic<unsigned> _sessionsCount;
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 2d3dd66..8c518fc 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -577,6 +577,9 @@ private:
docBrokers.emplace(docKey, docBroker);
}
+ // Validate the URI and Storage before moving on.
+ docBroker->validate(uriPublic);
+
auto ws = std::make_shared<WebSocket>(request, response);
auto session = std::make_shared<MasterProcessSession>(id, LOOLSession::Kind::ToClient, ws, docBroker);
docBroker->incSessions();
diff --git a/loolwsd/Storage.hpp b/loolwsd/Storage.hpp
index edc8569..574c844 100644
--- a/loolwsd/Storage.hpp
+++ b/loolwsd/Storage.hpp
@@ -16,6 +16,8 @@
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
+#include <Poco/JSON/Object.h>
+#include <Poco/JSON/Parser.h>
#include "Common.hpp"
#include "Auth.hpp"
@@ -26,6 +28,13 @@ class StorageBase
{
public:
+ class FileInfo
+ {
+ public:
+ std::string Filename;
+ size_t Size;
+ };
+
/// localStorePath the absolute root path of the chroot.
/// jailPath the path within the jail that the child uses.
StorageBase(const std::string& localStorePath,
@@ -56,11 +65,17 @@ public:
const std::string& getUri() const { return _uri; }
- /// Returns a local file path given a URI or ID.
+ /// Returns information about the file.
+ virtual FileInfo getFileInfo(const std::string& uri) = 0;
+
+ /// Returns a local file path for the given URI.
/// If necessary copies the file locally first.
virtual std::string loadStorageFileToLocal() = 0;
/// Writes the contents of the file back to the source.
+ /// TODO: Should we save to the specific client's URI?
+ /// The advantage is that subseqent views (to the first)
+ /// will not depend on the token of the first.
virtual bool saveLocalFileToStorage() = 0;
static
@@ -74,7 +89,7 @@ protected:
const std::string _jailPath;
const std::string _uri;
std::string _jailedFilePath;
- std::string _filename;
+ FileInfo _fileInfo;
};
/// Trivial implementation of local storage that does not need do anything.
@@ -89,6 +104,13 @@ public:
{
}
+ FileInfo getFileInfo(const std::string& uri)
+ {
+ const auto filename = Poco::Path(uri).getFileName();
+ const auto size = Poco::File(uri).getSize();
+ return FileInfo({filename, size});
+ }
+
std::string loadStorageFileToLocal() override
{
const auto rootPath = getLocalRootPath();
@@ -163,14 +185,68 @@ public:
{
}
+ FileInfo getFileInfo(const std::string& uri)
+ {
+ Log::info("FileInfo for URI [" + uri + "].");
+
+ Poco::URI uriObject(uri);
+ Poco::Net::HTTPClientSession session(uriObject.getHost(), uriObject.getPort());
+ Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
+ request.set("User-Agent", "LOOLWSD WOPI Agent");
+ session.sendRequest(request);
+
+ Poco::Net::HTTPResponse response;
+ std::istream& rs = session.receiveResponse(response);
+
+ auto logger = Log::trace();
+ logger << "WOPI::CheckFileInfo header for URI [" << uri << "]:\n";
+ for (auto& pair : response)
+ {
+ logger << '\t' + pair.first + ": " + pair.second << " / ";
+ }
+
+ logger << Log::end;
+
+ // Parse the response.
+ std::string filename;
+ size_t size = 0;
+ std::string resMsg;
+ Poco::StreamCopier::copyToString(rs, resMsg);
+ Log::debug("WOPI::CheckFileInfo returned: " + resMsg);
+ const auto index = resMsg.find_first_of("{");
+ if (index != std::string::npos)
+ {
+ const std::string stringJSON = resMsg.substr(index);
+ Poco::JSON::Parser parser;
+ const auto result = parser.parse(stringJSON);
+ const auto object = result.extract<Poco::JSON::Object::Ptr>();
+ filename = object->get("BaseFileName").toString();
+ size = std::stoul (object->get("Size").toString(), nullptr, 0);
+ }
+
+ return FileInfo({filename, size});
+ }
+
/// uri format: http://server/<...>/wopi*/files/<id>/content
std::string loadStorageFileToLocal() override
{
Log::info("Downloading URI [" + _uri + "].");
+ _fileInfo = getFileInfo(_uri);
+ if (_fileInfo.Size == 0 && _fileInfo.Filename.empty())
+ {
+ //TODO: Should throw a more appropriate exception.
+ throw std::runtime_error("Failed to load file from storage.");
+ }
+
+ // WOPI URI to download files ends in '/contents'.
+ // Add it here to get the payload instead of file info.
Poco::URI uriObject(_uri);
+ const auto url = uriObject.getPath() + "/contents?" + uriObject.getQuery();
+ Log::info("Requesting: " + url);
+
Poco::Net::HTTPClientSession session(uriObject.getHost(), uriObject.getPort());
- Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
+ Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, url, Poco::Net::HTTPMessage::HTTP_1_1);
request.set("User-Agent", "LOOLWSD WOPI Agent");
session.sendRequest(request);
@@ -186,9 +262,7 @@ public:
logger << Log::end;
- //TODO: Get proper filename.
- _filename = "filename";
- _jailedFilePath = Poco::Path(getLocalRootPath(), _filename).toString();
+ _jailedFilePath = Poco::Path(getLocalRootPath(), _fileInfo.Filename).toString();
std::ofstream ofs(_jailedFilePath);
std::copy(std::istreambuf_iterator<char>(rs),
std::istreambuf_iterator<char>(),
@@ -200,7 +274,7 @@ public:
<< response.getStatus() << " " << response.getReason() << Log::end;
// Now return the jailed path.
- return Poco::Path(_jailPath, _filename).toString();
+ return Poco::Path(_jailPath, _fileInfo.Filename).toString();
}
bool saveLocalFileToStorage() override
@@ -246,6 +320,13 @@ public:
{
}
+ FileInfo getFileInfo(const std::string& uri)
+ {
+ (void)uri;
+ assert(!"Not Implemented!");
+ return FileInfo({"bazinga", 0});
+ }
+
std::string loadStorageFileToLocal() override
{
// TODO: implement webdav GET.
More information about the Libreoffice-commits
mailing list