summaryrefslogtreecommitdiff
path: root/wsd
diff options
context:
space:
mode:
Diffstat (limited to 'wsd')
-rw-r--r--wsd/ClientSession.cpp14
-rw-r--r--wsd/ClientSession.hpp7
-rw-r--r--wsd/DocumentBroker.cpp6
-rw-r--r--wsd/Storage.cpp4
-rw-r--r--wsd/Storage.hpp2
-rw-r--r--wsd/TestStubs.cpp2
6 files changed, 30 insertions, 5 deletions
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 0f5a09b2c..6536b08fd 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -977,11 +977,19 @@ bool ClientSession::filterMessage(const std::string& message) const
return allowed;
}
-void ClientSession::setReadOnly()
+void ClientSession::setReadOnly(bool bVal)
{
- Session::setReadOnly();
+ Session::setReadOnly(bVal);
// Also inform the client
- sendTextFrame("perm: readonly");
+ const std::string sPerm = bVal ? "readonly" : "edit";
+ sendTextFrame("perm: " + sPerm);
+}
+
+void ClientSession::setLockFailed(const std::string& sReason)
+{
+ _isLockFailed = true;
+ setReadOnly();
+ sendTextFrame("lockfailed:" + sReason);
}
bool ClientSession::hasQueuedMessages() const
diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp
index 9802e889c..ab3402935 100644
--- a/wsd/ClientSession.hpp
+++ b/wsd/ClientSession.hpp
@@ -38,7 +38,8 @@ public:
void construct();
virtual ~ClientSession();
- void setReadOnly() override;
+ void setReadOnly(bool bVal = true) override;
+ void setLockFailed(const std::string& sReason);
enum SessionState {
DETACHED, // initial
@@ -251,6 +252,10 @@ private:
/// Whether this session is the owner of currently opened document
bool _isDocumentOwner;
+ /// If it is allowed to try to switch from read-only to edit mode,
+ /// because it's read-only just because of transient lock failure.
+ bool _isLockFailed = false;
+
/// The socket to which the converted (saveas) doc is sent.
std::shared_ptr<StreamSocket> _saveAsSocket;
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index c4f80aa61..0de4f15f9 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -782,9 +782,15 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
session->getAuthorization(), session->getCookies(), *_lockCtx, templateSource);
// Only lock the document on storage for editing sessions
+ // FIXME: why not lock before loadStorageFileToLocal? Would also prevent race conditions
if (!session->isReadOnly() &&
!_storage->updateLockState(session->getAuthorization(), session->getCookies(), *_lockCtx, true))
+ {
LOG_ERR("Failed to lock!");
+ session->setLockFailed(_lockCtx->_lockFailureReason);
+ // TODO: make this "read-only" a special one with a notification (infobar? balloon tip?)
+ // and a button to unlock
+ }
#if !MOBILEAPP
// Check if we have a prefilter "plugin" for this document format
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index e67c568ac..08a974d0d 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -770,6 +770,7 @@ WopiStorage::WOPIFileInfo::WOPIFileInfo(const FileInfo &fileInfo,
bool WopiStorage::updateLockState(const Authorization& auth, const std::string& cookies,
LockContext& lockCtx, bool lock)
{
+ lockCtx._lockFailureReason.clear();
if (!lockCtx._supportsLocks)
return true;
@@ -821,7 +822,10 @@ bool WopiStorage::updateLockState(const Authorization& auth, const std::string&
{
std::string sMoreInfo = response.get("X-WOPI-LockFailureReason", "");
if (!sMoreInfo.empty())
+ {
+ lockCtx._lockFailureReason = sMoreInfo;
sMoreInfo = ", failure reason: \"" + sMoreInfo + "\"";
+ }
LOG_WRN("Un-successful " << wopiLog << " with status " << response.getStatus() <<
sMoreInfo << " and response: " << responseString);
}
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index d087fb174..df1b59e5e 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -38,6 +38,8 @@ struct LockContext
std::string _lockToken;
/// Time of last successful lock (re-)acquisition
std::chrono::steady_clock::time_point _lastLockTime;
+ /// Reason for unsuccessful locking request
+ std::string _lockFailureReason;
LockContext() : _supportsLocks(false), _isLocked(false) { }
diff --git a/wsd/TestStubs.cpp b/wsd/TestStubs.cpp
index ad0859a8e..1efd3251f 100644
--- a/wsd/TestStubs.cpp
+++ b/wsd/TestStubs.cpp
@@ -33,7 +33,7 @@ void ClientSession::writeQueuedMessages() {}
void ClientSession::dumpState(std::ostream& /*os*/) {}
-void ClientSession::setReadOnly() {}
+void ClientSession::setReadOnly(bool) {}
bool ClientSession::_handleInput(const char* /*buffer*/, int /*length*/) { return false; }