summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--wsd/ClientSession.cpp14
-rw-r--r--wsd/ClientSession.hpp5
-rw-r--r--wsd/DocumentBroker.cpp17
-rw-r--r--wsd/Storage.cpp53
-rw-r--r--wsd/Storage.hpp59
5 files changed, 108 insertions, 40 deletions
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index beed136e51..60ed55c6fd 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -60,7 +60,19 @@ ClientSession::ClientSession(const std::string& id,
_isTextDocument(false)
{
const size_t curConnections = ++LOOLWSD::NumConnections;
- LOG_INF("ClientSession ctor [" << getName() << "], current number of connections: " << curConnections);
+ LOG_INF("ClientSession ctor [" << getName() << "] for URI: [" << _uriPublic.toString()
+ << "], current number of connections: " << curConnections);
+
+ for (const auto& param : _uriPublic.getQueryParameters())
+ {
+ if (param.first == "reuse_cookies")
+ {
+ // Cache the cookies to avoid re-parsing the URI again.
+ _cookies = param.second;
+ LOG_INF("ClientSession [" << getName() << "] has cookies: " << _cookies);
+ break;
+ }
+ }
// populate with random values.
for (auto it : _clipboardKeys)
diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp
index 8ee1846874..d714179ceb 100644
--- a/wsd/ClientSession.hpp
+++ b/wsd/ClientSession.hpp
@@ -123,6 +123,8 @@ public:
/// The access token of this session.
Authorization getAuthorization() const;
+ const std::string& getCookies() const { return _cookies; }
+
/// Set WOPI fileinfo object
void setWopiFileInfo(std::unique_ptr<WopiStorage::WOPIFileInfo>& wopiFileInfo) { _wopiFileInfo = std::move(wopiFileInfo); }
@@ -220,6 +222,9 @@ private:
/// URI with which client made request to us
const Poco::URI _uriPublic;
+ /// The cookies we should pass on to the storage on saving.
+ std::string _cookies;
+
/// Whether this session is the owner of currently opened document
bool _isDocumentOwner;
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 876436abed..1eed16ea04 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -596,8 +596,8 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
WopiStorage* wopiStorage = dynamic_cast<WopiStorage*>(_storage.get());
if (wopiStorage != nullptr)
{
- std::unique_ptr<WopiStorage::WOPIFileInfo> wopifileinfo =
- wopiStorage->getWOPIFileInfo(session->getAuthorization(), *_lockCtx);
+ std::unique_ptr<WopiStorage::WOPIFileInfo> wopifileinfo = wopiStorage->getWOPIFileInfo(
+ session->getAuthorization(), session->getCookies(), *_lockCtx);
userId = wopifileinfo->getUserId();
username = wopifileinfo->getUsername();
userExtraInfo = wopifileinfo->getUserExtraInfo();
@@ -754,9 +754,9 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
if (!_storage->isLoaded())
{
std::string localPath = _storage->loadStorageFileToLocal(
- session->getAuthorization(), *_lockCtx, templateSource);
+ session->getAuthorization(), session->getCookies(), *_lockCtx, templateSource);
- if (!_storage->updateLockState(session->getAuthorization(), *_lockCtx, true))
+ if (!_storage->updateLockState(session->getAuthorization(), session->getCookies(), *_lockCtx, true))
LOG_ERR("Failed to lock!");
#if !MOBILEAPP
@@ -990,8 +990,8 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, bool su
LOG_DBG("Persisting [" << _docKey << "] after saving to URI [" << uriAnonym << "].");
assert(_storage && _tileCache);
- StorageBase::SaveResult storageSaveResult = _storage->saveLocalFileToStorage(
- auth, *_lockCtx, saveAsPath, saveAsFilename, isRename);
+ const StorageBase::SaveResult storageSaveResult = _storage->saveLocalFileToStorage(
+ auth, it->second->getCookies(), *_lockCtx, saveAsPath, saveAsFilename, isRename);
if (storageSaveResult.getResult() == StorageBase::SaveResult::OK)
{
#if !MOBILEAPP
@@ -1146,7 +1146,7 @@ void DocumentBroker::refreshLock()
else
{
std::shared_ptr<ClientSession> session = it->second;
- if (!session || !_storage->updateLockState(session->getAuthorization(), *_lockCtx, true))
+ if (!session || !_storage->updateLockState(session->getAuthorization(), session->getCookies(), *_lockCtx, true))
LOG_ERR("Failed to refresh lock");
}
}
@@ -1418,7 +1418,7 @@ void DocumentBroker::disconnectSessionInternal(const std::string& id)
if (_markToDestroy && // last session to remove; FIXME: Editable?
_lockCtx->_isLocked && _storage)
{
- if (!_storage->updateLockState(it->second->getAuthorization(), *_lockCtx, false))
+ if (!_storage->updateLockState(it->second->getAuthorization(), it->second->getCookies(), *_lockCtx, false))
LOG_ERR("Failed to unlock!");
}
@@ -1782,7 +1782,6 @@ void DocumentBroker::sendRequestedTiles(const std::shared_ptr<ClientSession>& se
float tilesOnFlyUpperLimit = 0;
if (normalizedVisArea.hasSurface() && session->getTileWidthInTwips() != 0 && session->getTileHeightInTwips() != 0)
{
-
const int tilesFitOnWidth = std::ceil(normalizedVisArea.getRight() / session->getTileWidthInTwips()) -
std::ceil(normalizedVisArea.getLeft() / session->getTileWidthInTwips()) + 1;
const int tilesFitOnHeight = std::ceil(normalizedVisArea.getBottom() / session->getTileHeightInTwips()) -
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index ab2ad71c61..f465e0a011 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -300,7 +300,10 @@ std::unique_ptr<LocalStorage::LocalFileInfo> LocalStorage::getLocalFileInfo()
return std::unique_ptr<LocalStorage::LocalFileInfo>(new LocalFileInfo({"localhost" + std::to_string(LastLocalStorageId), "LocalHost#" + std::to_string(LastLocalStorageId++)}));
}
-std::string LocalStorage::loadStorageFileToLocal(const Authorization& /*auth*/, LockContext & /*lockCtx*/, const std::string& /*templateUri*/)
+std::string LocalStorage::loadStorageFileToLocal(const Authorization& /*auth*/,
+ const std::string& /*cookies*/,
+ LockContext& /*lockCtx*/,
+ const std::string& /*templateUri*/)
{
#if !MOBILEAPP
// /chroot/jailId/user/doc/childId/file.ext
@@ -363,7 +366,10 @@ std::string LocalStorage::loadStorageFileToLocal(const Authorization& /*auth*/,
}
-StorageBase::SaveResult LocalStorage::saveLocalFileToStorage(const Authorization& /*auth*/, LockContext &/*lockCtx*/, const std::string& /*saveAsPath*/, const std::string& /*saveAsFilename*/, bool /*isRename*/)
+StorageBase::SaveResult
+LocalStorage::saveLocalFileToStorage(const Authorization& /*auth*/, const std::string& /*cookies*/,
+ LockContext& /*lockCtx*/, const std::string& /*saveAsPath*/,
+ const std::string& /*saveAsFilename*/, bool /*isRename*/)
{
try
{
@@ -428,6 +434,8 @@ static void addStorageReuseCookie(Poco::Net::HTTPRequest& request, const std::st
if (!reuseStorageCookies.empty())
{
Poco::Net::NameValueCollection nvcCookies;
+ request.getCookies(nvcCookies); // Preserve existing cookies.
+
std::vector<std::string> cookies = LOOLProtocol::tokenize(reuseStorageCookies, ':');
for (auto cookie : cookies)
{
@@ -435,9 +443,10 @@ static void addStorageReuseCookie(Poco::Net::HTTPRequest& request, const std::st
if (cookieTokens.size() == 2)
{
nvcCookies.add(cookieTokens[0], cookieTokens[1]);
- LOG_DBG("Added storage reuse cookie [" << cookieTokens[0] << "=" << cookieTokens[1] << "].");
+ LOG_DBG("Added storage reuse cookie [" << cookieTokens[0] << '=' << cookieTokens[1] << "].");
}
}
+
request.setCookies(nvcCookies);
}
}
@@ -494,7 +503,9 @@ void LockContext::dumpState(std::ostream& os) const
#if !MOBILEAPP
-std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Authorization& auth, LockContext &lockCtx)
+std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Authorization& auth,
+ const std::string& cookies,
+ LockContext& lockCtx)
{
// update the access_token to the one matching to the session
Poco::URI uriObject(getUri());
@@ -513,7 +524,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au
auth.authorizeRequest(request);
addStorageDebugCookie(request);
if (_reuseCookies)
- addStorageReuseCookie(request, params["reuse_cookies"]);
+ addStorageReuseCookie(request, cookies);
addWopiProof(request, params["access_token"]);
const auto startTime = std::chrono::steady_clock::now();
@@ -712,7 +723,8 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au
userCanRename, callDuration}));
}
-bool WopiStorage::updateLockState(const Authorization &auth, LockContext &lockCtx, bool lock)
+bool WopiStorage::updateLockState(const Authorization& auth, const std::string& cookies,
+ LockContext& lockCtx, bool lock)
{
if (!lockCtx._supportsLocks)
return true;
@@ -743,7 +755,7 @@ bool WopiStorage::updateLockState(const Authorization &auth, LockContext &lockCt
request.set("X-LOOL-WOPI-ExtendedData", getExtendedData());
addStorageDebugCookie(request);
if (_reuseCookies)
- addStorageReuseCookie(request, params["reuse_cookies"]);
+ addStorageReuseCookie(request, cookies);
addWopiProof(request, params["access_token"]);
psession->sendRequest(request);
@@ -782,7 +794,10 @@ bool WopiStorage::updateLockState(const Authorization &auth, LockContext &lockCt
}
/// uri format: http://server/<...>/wopi*/files/<id>/content
-std::string WopiStorage::loadStorageFileToLocal(const Authorization& auth, LockContext &/* lockCtx */, const std::string& templateUri)
+std::string WopiStorage::loadStorageFileToLocal(const Authorization& auth,
+ const std::string& cookies,
+ LockContext& /*lockCtx*/,
+ const std::string& templateUri)
{
// WOPI URI to download files ends in '/contents'.
// Add it here to get the payload instead of file info.
@@ -819,7 +834,7 @@ std::string WopiStorage::loadStorageFileToLocal(const Authorization& auth, LockC
auth.authorizeRequest(request);
addStorageDebugCookie(request);
if (_reuseCookies)
- addStorageReuseCookie(request, params["reuse_cookies"]);
+ addStorageReuseCookie(request, cookies);
addWopiProof(request, params["access_token"]);
psession->sendRequest(request);
@@ -876,7 +891,10 @@ std::string WopiStorage::loadStorageFileToLocal(const Authorization& auth, LockC
return "";
}
-StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization& auth, LockContext &lockCtx, const std::string& saveAsPath, const std::string& saveAsFilename, const bool isRename)
+StorageBase::SaveResult
+WopiStorage::saveLocalFileToStorage(const Authorization& auth, const std::string& cookies,
+ LockContext& lockCtx, const std::string& saveAsPath,
+ const std::string& saveAsFilename, const bool isRename)
{
// TODO: Check if this URI has write permission (canWrite = true)
@@ -975,7 +993,7 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization&
request.setContentLength(size);
addStorageDebugCookie(request);
if (_reuseCookies)
- addStorageReuseCookie(request, params["reuse_cookies"]);
+ addStorageReuseCookie(request, cookies);
addWopiProof(request, params["access_token"]);
std::ostream& os = psession->sendRequest(request);
@@ -1106,17 +1124,20 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization&
return saveResult;
}
-std::string WebDAVStorage::loadStorageFileToLocal(
- const Authorization& /*auth*/, LockContext &/*lockCtx*/, const std::string& /*templateUri*/)
+std::string WebDAVStorage::loadStorageFileToLocal(const Authorization& /*auth*/,
+ const std::string& /*cookies*/,
+ LockContext& /*lockCtx*/,
+ const std::string& /*templateUri*/)
{
// TODO: implement webdav GET.
setLoaded(true);
return getUri().toString();
}
-StorageBase::SaveResult WebDAVStorage::saveLocalFileToStorage(
- const Authorization& /*auth*/, LockContext &/*lockCtx*/, const std::string& /*saveAsPath*/,
- const std::string& /*saveAsFilename*/, bool /*isRename*/)
+StorageBase::SaveResult
+WebDAVStorage::saveLocalFileToStorage(const Authorization& /*auth*/, const std::string& /*cookies*/,
+ LockContext& /*lockCtx*/, const std::string& /*saveAsPath*/,
+ const std::string& /*saveAsFilename*/, bool /*isRename*/)
{
// TODO: implement webdav PUT.
return StorageBase::SaveResult(StorageBase::SaveResult::OK);
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index 7060cd7a4e..bb678ac8aa 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -53,7 +53,6 @@ struct LockContext
class StorageBase
{
public:
-
/// Represents basic file's attributes.
/// Used for local and network files.
class FileInfo
@@ -217,15 +216,25 @@ public:
std::string getFileExtension() const { return Poco::Path(_fileInfo.getFilename()).getExtension(); }
/// Update the locking state (check-in/out) of the associated file
- virtual bool updateLockState(const Authorization &auth, LockContext &lockCtx, bool lock) = 0;
+ virtual bool updateLockState(const Authorization& auth, const std::string& cookies,
+ LockContext& lockCtx, bool lock)
+ = 0;
/// Returns a local file path for the given URI.
/// If necessary copies the file locally first.
- virtual std::string loadStorageFileToLocal(const Authorization& auth, LockContext &lockCtx, const std::string& templateUri) = 0;
+ virtual std::string loadStorageFileToLocal(const Authorization& auth,
+ const std::string& /*cookies*/, LockContext& lockCtx,
+ const std::string& templateUri)
+ = 0;
/// Writes the contents of the file back to the source.
+ /// @param cookies A string representing key=value pairs that are set as cookies.
/// @param savedFile When the operation was saveAs, this is the path to the file that was saved.
- virtual SaveResult saveLocalFileToStorage(const Authorization& auth, LockContext &lockCtx, const std::string& saveAsPath, const std::string& saveAsFilename, const bool isRename) = 0;
+ virtual SaveResult
+ saveLocalFileToStorage(const Authorization& auth, const std::string& /*cookies*/,
+ LockContext& lockCtx, const std::string& saveAsPath,
+ const std::string& saveAsFilename, const bool isRename)
+ = 0;
static size_t getFileSize(const std::string& filename);
@@ -312,11 +321,19 @@ public:
/// obtained using getFileInfo method
std::unique_ptr<LocalFileInfo> getLocalFileInfo();
- bool updateLockState(const Authorization &, LockContext &, bool) override { return true; }
+ bool updateLockState(const Authorization&, const std::string&, LockContext&, bool) override
+ {
+ return true;
+ }
- std::string loadStorageFileToLocal(const Authorization& auth, LockContext &lockCtx, const std::string& templateUri) override;
+ std::string loadStorageFileToLocal(const Authorization& auth, const std::string& /*cookies*/,
+ LockContext& lockCtx,
+ const std::string& templateUri) override;
- SaveResult saveLocalFileToStorage(const Authorization& auth, LockContext &lockCtx, const std::string& saveAsPath, const std::string& saveAsFilename, const bool isRename) override;
+ SaveResult saveLocalFileToStorage(const Authorization& auth, const std::string& /*cookies*/,
+ LockContext& lockCtx, const std::string& saveAsPath,
+ const std::string& saveAsFilename,
+ const bool isRename) override;
private:
/// True if the jailed file is not linked but copied.
@@ -545,15 +562,21 @@ public:
/// which can then be obtained using getFileInfo()
/// Also sets up the locking context for future operations.
std::unique_ptr<WOPIFileInfo> getWOPIFileInfo(const Authorization& auth,
- LockContext &lockCtx);
+ const std::string& cookies, LockContext& lockCtx);
/// Update the locking state (check-in/out) of the associated file
- bool updateLockState(const Authorization &auth, LockContext &lockCtx, bool lock) override;
+ bool updateLockState(const Authorization& auth, const std::string& cookies,
+ LockContext& lockCtx, bool lock) override;
/// uri format: http://server/<...>/wopi*/files/<id>/content
- std::string loadStorageFileToLocal(const Authorization& auth, LockContext &lockCtx, const std::string& templateUri) override;
+ std::string loadStorageFileToLocal(const Authorization& auth, const std::string& /*cookies*/,
+ LockContext& lockCtx,
+ const std::string& templateUri) override;
- SaveResult saveLocalFileToStorage(const Authorization& auth, LockContext &lockCtx, const std::string& saveAsPath, const std::string& saveAsFilename, const bool isRename) override;
+ SaveResult saveLocalFileToStorage(const Authorization& auth, const std::string& /*cookies*/,
+ LockContext& lockCtx, const std::string& saveAsPath,
+ const std::string& saveAsFilename,
+ const bool isRename) override;
/// Total time taken for making WOPI calls during load
std::chrono::duration<double> getWopiLoadDuration() const { return _wopiLoadDuration; }
@@ -585,11 +608,19 @@ public:
// Implement me
// WebDAVFileInfo getWebDAVFileInfo(const Poco::URI& uriPublic);
- bool updateLockState(const Authorization &, LockContext &, bool) override { return true; }
+ bool updateLockState(const Authorization&, const std::string&, LockContext&, bool) override
+ {
+ return true;
+ }
- std::string loadStorageFileToLocal(const Authorization& auth, LockContext &lockCtx, const std::string& templateUri) override;
+ std::string loadStorageFileToLocal(const Authorization& auth, const std::string& /*cookies*/,
+ LockContext& lockCtx,
+ const std::string& templateUri) override;
- SaveResult saveLocalFileToStorage(const Authorization& auth, LockContext &lockCtx, const std::string& saveAsPath, const std::string& saveAsFilename, const bool isRename) override;
+ SaveResult saveLocalFileToStorage(const Authorization& auth, const std::string& /*cookies*/,
+ LockContext& lockCtx, const std::string& saveAsPath,
+ const std::string& saveAsFilename,
+ const bool isRename) override;
private:
std::unique_ptr<AuthBase> _authAgent;