[Libreoffice-commits] online.git: 5 commits - Makefile.am test/Makefile.am test/UnitOAuth.cpp test/UnitWOPI.cpp test/WopiTestServer.hpp wsd/ClientSession.cpp wsd/DocumentBroker.cpp wsd/reference.txt wsd/Storage.cpp wsd/Storage.hpp
Andras Timar
andras.timar at collabora.com
Wed Sep 27 14:44:06 UTC 2017
Makefile.am | 1
test/Makefile.am | 7 +-
test/UnitOAuth.cpp | 115 +++++++++---------------------------------
test/UnitWOPI.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++++++++
test/WopiTestServer.hpp | 129 ++++++++++++++++++++++++++++++++++++++++++++++++
wsd/ClientSession.cpp | 20 +++++--
wsd/DocumentBroker.cpp | 3 +
wsd/Storage.cpp | 1
wsd/Storage.hpp | 9 ++-
wsd/reference.txt | 11 ++++
10 files changed, 328 insertions(+), 97 deletions(-)
New commits:
commit 67ebb9a48ed3131749858b070ec4d3c81906530a
Author: Andras Timar <andras.timar at collabora.com>
Date: Wed Sep 27 15:55:44 2017 +0200
add test/WopiTestServer.hpp to Makefile.am
Change-Id: I9a4b10f0d1f12ed85d31f3dbbc1deb747ff35a2d
diff --git a/Makefile.am b/Makefile.am
index f83fb463..5e0d64b2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -187,6 +187,7 @@ noinst_HEADERS = $(wsd_headers) $(shared_headers) $(kit_headers) \
bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h \
bundled/include/LibreOfficeKit/LibreOfficeKitInit.h \
bundled/include/LibreOfficeKit/LibreOfficeKitTypes.h \
+ test/WopiTestServer.hpp \
test/countloolkits.hpp \
test/test.hpp \
test/helpers.hpp
commit 3141cfc99ba2e2fb3878e95373a2fa48a76205a5
Author: Jan Holesovsky <kendy at collabora.com>
Date: Wed Sep 27 14:13:43 2017 +0200
PutFile ext: X-LOOL-WOPI-IsModifiedByUser unit test.
Change-Id: I0b1ffc74dbbc771f0dcb68f87d46af3ba469ae9e
Reviewed-on: https://gerrit.libreoffice.org/42855
Reviewed-by: pranavk <pranavk at collabora.co.uk>
Tested-by: pranavk <pranavk at collabora.co.uk>
diff --git a/test/Makefile.am b/test/Makefile.am
index 57094967..7ee4bcf2 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -16,7 +16,8 @@ noinst_LTLIBRARIES = \
unit-timeout.la unit-prefork.la \
unit-storage.la unit-client.la \
unit-admin.la unit-tilecache.la \
- unit-fuzz.la unit-oob.la unit-oauth.la
+ unit-fuzz.la unit-oob.la unit-oauth.la \
+ unit-wopi.la
MAGIC_TO_FORCE_SHLIB_CREATION = -rpath /dummy
AM_LDFLAGS = -pthread -module $(MAGIC_TO_FORCE_SHLIB_CREATION) $(ZLIB_LIBS)
@@ -77,6 +78,8 @@ unit_storage_la_SOURCES = UnitStorage.cpp
unit_tilecache_la_SOURCES = UnitTileCache.cpp
unit_oauth_la_SOURCES = UnitOAuth.cpp
unit_oauth_la_LIBADD = $(CPPUNIT_LIBS)
+unit_wopi_la_SOURCES = UnitWOPI.cpp
+unit_wopi_la_LIBADD = $(CPPUNIT_LIBS)
if HAVE_LO_PATH
SYSTEM_STAMP = @SYSTEMPLATE_PATH@/system_stamp
@@ -90,7 +93,7 @@ check-local:
./run_unit.sh --log-file test.log --trs-file test.trs
# FIXME 2: unit-oob.la fails with symbol undefined:
# UnitWSD::testHandleRequest(UnitWSD::TestRequest, UnitHTTPServerRequest&, UnitHTTPServerResponse&) ,
-TESTS = unit-prefork.la unit-tilecache.la unit-timeout.la unit-oauth.la
+TESTS = unit-prefork.la unit-tilecache.la unit-timeout.la unit-oauth.la unit-wopi.la
# TESTS = unit-client.la
# TESTS += unit-admin.la
# TESTS += unit-storage.la
diff --git a/test/UnitOAuth.cpp b/test/UnitOAuth.cpp
index baf05c0e..dfba4aa1 100644
--- a/test/UnitOAuth.cpp
+++ b/test/UnitOAuth.cpp
@@ -26,7 +26,7 @@ class UnitOAuth : public WopiTestServer
{
LoadToken, // loading the document with Bearer token
LoadHeader, // loading the document with Basic auth
- Polling // let the loading progress, and when it succeeds, finish
+ Finish // assert all went fine and finish
} _phase;
bool _finishedToken;
@@ -84,9 +84,9 @@ public:
}
}
- bool wopiServerFinish() override
+ void assertPutFileRequest(const Poco::Net::HTTPRequest& /*request*/) override
{
- return _finishedToken && _finishedHeader;
+ // nothing to assert
}
void invokeTest() override
@@ -116,12 +116,13 @@ public:
if (_phase == Phase::LoadToken)
_phase = Phase::LoadHeader;
else
- _phase = Phase::Polling;
+ _phase = Phase::Finish;
break;
}
- case Phase::Polling:
+ case Phase::Finish:
{
- // let handleHttpRequest() perform the checks...
+ CPPUNIT_ASSERT(_finishedToken && _finishedHeader);
+ exitTest(TestResult::Ok);
break;
}
}
diff --git a/test/UnitWOPI.cpp b/test/UnitWOPI.cpp
new file mode 100644
index 00000000..fade8d0f
--- /dev/null
+++ b/test/UnitWOPI.cpp
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "config.h"
+
+#include "WopiTestServer.hpp"
+#include "Log.hpp"
+#include "Unit.hpp"
+#include "UnitHTTP.hpp"
+#include "helpers.hpp"
+#include <Poco/Net/HTTPRequest.h>
+#include <Poco/Util/LayeredConfiguration.h>
+
+class UnitWOPI : public WopiTestServer
+{
+ enum class Phase
+ {
+ LoadAndSave,
+ Modify,
+ SaveModified,
+ Finish
+ } _phase;
+
+ enum class SavingPhase
+ {
+ Unmodified,
+ Modified
+ } _savingPhase;
+
+ bool _finishedSaveUnmodified;
+ bool _finishedSaveModified;
+
+ std::unique_ptr<UnitWebSocket> _ws;
+
+public:
+ UnitWOPI() :
+ _phase(Phase::LoadAndSave),
+ _finishedSaveUnmodified(false),
+ _finishedSaveModified(false)
+ {
+ }
+
+ void assertCheckFileInfoRequest(const Poco::Net::HTTPRequest& /*request*/) override
+ {
+ // nothing to assert in CheckFileInfo
+ }
+
+ void assertGetFileRequest(const Poco::Net::HTTPRequest& /*request*/) override
+ {
+ // nothing to assert in GetFile
+ }
+
+ void assertPutFileRequest(const Poco::Net::HTTPRequest& request) override
+ {
+ if (_savingPhase == SavingPhase::Unmodified)
+ {
+ CPPUNIT_ASSERT_EQUAL(std::string("false"), request.get("X-LOOL-WOPI-IsModifiedByUser"));
+ _finishedSaveUnmodified = true;
+ }
+ else if (_savingPhase == SavingPhase::Modified)
+ {
+ CPPUNIT_ASSERT_EQUAL(std::string("true"), request.get("X-LOOL-WOPI-IsModifiedByUser"));
+ _finishedSaveModified = true;
+ }
+ }
+
+ void invokeTest() override
+ {
+ constexpr char testName[] = "UnitWOPI";
+
+ switch (_phase)
+ {
+ case Phase::LoadAndSave:
+ {
+ Poco::URI wopiURL(helpers::getTestServerURI() + "/wopi/files/0?access_token=anything");
+ std::string wopiSrc;
+ Poco::URI::encode(wopiURL.toString(), ":/?", wopiSrc);
+ Poco::URI loolUri(helpers::getTestServerURI());
+
+ LOG_INF("Connecting to the fake WOPI server: /lool/" << wopiSrc << "/ws");
+
+ _ws.reset(new UnitWebSocket("/lool/" + wopiSrc + "/ws"));
+ assert(_ws.get());
+
+ helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "load url=" + wopiSrc, testName);
+ helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "save dontTerminateEdit=1 dontSaveIfUnmodified=0", testName);
+
+ _phase = Phase::Modify;
+ _savingPhase = SavingPhase::Unmodified;
+ break;
+ }
+ case Phase::Modify:
+ {
+ helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "key type=input char=97 key=0", testName);
+ helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "key type=up char=0 key=512", testName);
+
+ _phase = Phase::SaveModified;
+ break;
+ }
+ case Phase::SaveModified:
+ {
+ helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "save dontTerminateEdit=0 dontSaveIfUnmodified=0", testName);
+
+ _phase = Phase::Finish;
+ _savingPhase = SavingPhase::Modified;
+ break;
+ }
+ case Phase::Finish:
+ {
+ CPPUNIT_ASSERT(_finishedSaveUnmodified && _finishedSaveModified);
+ exitTest(TestResult::Ok);
+ break;
+ }
+ }
+ }
+};
+
+UnitBase *unit_create_wsd(void)
+{
+ return new UnitWOPI();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/WopiTestServer.hpp b/test/WopiTestServer.hpp
index 63cf4c7f..5ac79e81 100644
--- a/test/WopiTestServer.hpp
+++ b/test/WopiTestServer.hpp
@@ -29,7 +29,7 @@ public:
virtual void assertGetFileRequest(const Poco::Net::HTTPRequest& request) = 0;
- virtual bool wopiServerFinish() = 0;
+ virtual void assertPutFileRequest(const Poco::Net::HTTPRequest& request) = 0;
protected:
/// Here we act as a WOPI server, so that we have a server that responds to
@@ -81,7 +81,7 @@ protected:
return true;
}
// GetFile
- else if (uriReq.getPath() == "/wopi/files/0/contents" || uriReq.getPath() == "/wopi/files/1/contents")
+ else if (request.getMethod() == "GET" && (uriReq.getPath() == "/wopi/files/0/contents" || uriReq.getPath() == "/wopi/files/1/contents"))
{
LOG_INF("Fake wopi host request, handling GetFile: " << uriReq.getPath());
@@ -101,8 +101,22 @@ protected:
socket->send(oss.str());
socket->shutdown();
- if (wopiServerFinish())
- exitTest(TestResult::Ok);
+ return true;
+ }
+ else if (request.getMethod() == "POST" && (uriReq.getPath() == "/wopi/files/0/contents" || uriReq.getPath() == "/wopi/files/1/contents"))
+ {
+ LOG_INF("Fake wopi host request, handling PutFile: " << uriReq.getPath());
+
+ assertPutFileRequest(request);
+
+ std::ostringstream oss;
+ oss << "HTTP/1.1 200 OK\r\n"
+ << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
+ << "User-Agent: " << WOPI_AGENT_STRING << "\r\n"
+ << "\r\n";
+
+ socket->send(oss.str());
+ socket->shutdown();
return true;
}
commit a711d5b60c65042585ff85b574a526bac4ae0647
Author: Jan Holesovsky <kendy at collabora.com>
Date: Tue Sep 26 16:12:58 2017 +0200
Separate the fake wopi server to an own class.
Change-Id: Ibb1b06c491be0065aa12a05a43959165d6c86398
Reviewed-on: https://gerrit.libreoffice.org/42853
Reviewed-by: pranavk <pranavk at collabora.co.uk>
Tested-by: pranavk <pranavk at collabora.co.uk>
diff --git a/test/UnitOAuth.cpp b/test/UnitOAuth.cpp
index 7a52c1ee..baf05c0e 100644
--- a/test/UnitOAuth.cpp
+++ b/test/UnitOAuth.cpp
@@ -9,24 +9,18 @@
#include "config.h"
-//#include "Exceptions.hpp"
+#include "WopiTestServer.hpp"
#include "Log.hpp"
#include "Unit.hpp"
#include "UnitHTTP.hpp"
#include "helpers.hpp"
-#include <Poco/JSON/Object.h>
-#include <Poco/LocalDateTime.h>
-#include <Poco/DateTimeFormat.h>
-#include <Poco/DateTimeFormatter.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/OAuth20Credentials.h>
#include <Poco/Util/LayeredConfiguration.h>
-using Poco::DateTimeFormatter;
-using Poco::DateTimeFormat;
using Poco::Net::OAuth20Credentials;
-class UnitOAuth : public UnitWSD
+class UnitOAuth : public WopiTestServer
{
enum class Phase
{
@@ -46,6 +40,7 @@ public:
{
}
+ /// The actual assert of the authentication.
void assertRequest(const Poco::Net::HTTPRequest& request, int fileIndex)
{
// check that the request contains the Authorization: header
@@ -68,91 +63,30 @@ public:
}
}
- /// Here we act as a WOPI server, so that we have a server that responds to
- /// the wopi requests without additional expensive setup.
- virtual bool handleHttpRequest(const Poco::Net::HTTPRequest& request, std::shared_ptr<StreamSocket>& socket) override
+ void assertCheckFileInfoRequest(const Poco::Net::HTTPRequest& request) override
{
- static const std::string hello("Hello, world");
-
- Poco::URI uriReq(request.getURI());
- LOG_INF("Fake wopi host request: " << uriReq.toString());
+ std::string path = Poco::URI(request.getURI()).getPath();
+ assertRequest(request, (path == "/wopi/files/0")? 0: 1);
+ }
- // CheckFileInfo
- if (uriReq.getPath() == "/wopi/files/0" || uriReq.getPath() == "/wopi/files/1")
+ void assertGetFileRequest(const Poco::Net::HTTPRequest& request) override
+ {
+ std::string path = Poco::URI(request.getURI()).getPath();
+ if (path == "/wopi/files/0/contents")
{
- LOG_INF("Fake wopi host request, handling CheckFileInfo: " << uriReq.getPath());
-
- assertRequest(request, (uriReq.getPath() == "/wopi/files/0")? 0: 1);
-
- Poco::LocalDateTime now;
- Poco::JSON::Object::Ptr fileInfo = new Poco::JSON::Object();
- fileInfo->set("BaseFileName", "hello.txt");
- fileInfo->set("Size", hello.size());
- fileInfo->set("Version", "1.0");
- fileInfo->set("OwnerId", "test");
- fileInfo->set("UserId", "test");
- fileInfo->set("UserFriendlyName", "test");
- fileInfo->set("UserCanWrite", "true");
- fileInfo->set("PostMessageOrigin", "localhost");
- fileInfo->set("LastModifiedTime", DateTimeFormatter::format(now, DateTimeFormat::ISO8601_FORMAT));
-
- std::ostringstream jsonStream;
- fileInfo->stringify(jsonStream);
- std::string responseString = jsonStream.str();
-
- const std::string mimeType = "application/json; charset=utf-8";
-
- std::ostringstream oss;
- oss << "HTTP/1.1 200 OK\r\n"
- << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
- << "User-Agent: " << WOPI_AGENT_STRING << "\r\n"
- << "Content-Length: " << responseString.size() << "\r\n"
- << "Content-Type: " << mimeType << "\r\n"
- << "\r\n"
- << responseString;
-
- socket->send(oss.str());
- socket->shutdown();
-
- return true;
+ assertRequest(request, 0);
+ _finishedToken = true;
}
- // GetFile
- else if (uriReq.getPath() == "/wopi/files/0/contents" || uriReq.getPath() == "/wopi/files/1/contents")
+ else
{
- LOG_INF("Fake wopi host request, handling GetFile: " << uriReq.getPath());
-
- if (uriReq.getPath() == "/wopi/files/0/contents")
- {
- assertRequest(request, 0);
- _finishedToken = true;
- }
- else
- {
- assertRequest(request, 1);
- _finishedHeader = true;
- }
-
- const std::string mimeType = "text/plain; charset=utf-8";
-
- std::ostringstream oss;
- oss << "HTTP/1.1 200 OK\r\n"
- << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
- << "User-Agent: " << WOPI_AGENT_STRING << "\r\n"
- << "Content-Length: " << hello.size() << "\r\n"
- << "Content-Type: " << mimeType << "\r\n"
- << "\r\n"
- << hello;
-
- socket->send(oss.str());
- socket->shutdown();
-
- if (_finishedToken && _finishedHeader)
- exitTest(TestResult::Ok);
-
- return true;
+ assertRequest(request, 1);
+ _finishedHeader = true;
}
+ }
- return false;
+ bool wopiServerFinish() override
+ {
+ return _finishedToken && _finishedHeader;
}
void invokeTest() override
diff --git a/test/WopiTestServer.hpp b/test/WopiTestServer.hpp
new file mode 100644
index 00000000..63cf4c7f
--- /dev/null
+++ b/test/WopiTestServer.hpp
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "config.h"
+
+#include "Log.hpp"
+#include "Unit.hpp"
+#include "UnitHTTP.hpp"
+#include <Poco/DateTimeFormat.h>
+#include <Poco/DateTimeFormatter.h>
+#include <Poco/JSON/Object.h>
+#include <Poco/Net/HTTPRequest.h>
+#include <Poco/URI.h>
+
+class WopiTestServer : public UnitWSD
+{
+public:
+ WopiTestServer() : UnitWSD()
+ {
+ }
+
+ virtual void assertCheckFileInfoRequest(const Poco::Net::HTTPRequest& request) = 0;
+
+ virtual void assertGetFileRequest(const Poco::Net::HTTPRequest& request) = 0;
+
+ virtual bool wopiServerFinish() = 0;
+
+protected:
+ /// Here we act as a WOPI server, so that we have a server that responds to
+ /// the wopi requests without additional expensive setup.
+ virtual bool handleHttpRequest(const Poco::Net::HTTPRequest& request, std::shared_ptr<StreamSocket>& socket) override
+ {
+ static const std::string hello("Hello, world");
+
+ Poco::URI uriReq(request.getURI());
+ LOG_INF("Fake wopi host request: " << uriReq.toString());
+
+ // CheckFileInfo
+ if (uriReq.getPath() == "/wopi/files/0" || uriReq.getPath() == "/wopi/files/1")
+ {
+ LOG_INF("Fake wopi host request, handling CheckFileInfo: " << uriReq.getPath());
+
+ assertCheckFileInfoRequest(request);
+
+ Poco::LocalDateTime now;
+ Poco::JSON::Object::Ptr fileInfo = new Poco::JSON::Object();
+ fileInfo->set("BaseFileName", "hello.txt");
+ fileInfo->set("Size", hello.size());
+ fileInfo->set("Version", "1.0");
+ fileInfo->set("OwnerId", "test");
+ fileInfo->set("UserId", "test");
+ fileInfo->set("UserFriendlyName", "test");
+ fileInfo->set("UserCanWrite", "true");
+ fileInfo->set("PostMessageOrigin", "localhost");
+ fileInfo->set("LastModifiedTime", Poco::DateTimeFormatter::format(now, Poco::DateTimeFormat::ISO8601_FORMAT));
+
+ std::ostringstream jsonStream;
+ fileInfo->stringify(jsonStream);
+ std::string responseString = jsonStream.str();
+
+ const std::string mimeType = "application/json; charset=utf-8";
+
+ std::ostringstream oss;
+ oss << "HTTP/1.1 200 OK\r\n"
+ << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
+ << "User-Agent: " << WOPI_AGENT_STRING << "\r\n"
+ << "Content-Length: " << responseString.size() << "\r\n"
+ << "Content-Type: " << mimeType << "\r\n"
+ << "\r\n"
+ << responseString;
+
+ socket->send(oss.str());
+ socket->shutdown();
+
+ return true;
+ }
+ // GetFile
+ else if (uriReq.getPath() == "/wopi/files/0/contents" || uriReq.getPath() == "/wopi/files/1/contents")
+ {
+ LOG_INF("Fake wopi host request, handling GetFile: " << uriReq.getPath());
+
+ assertGetFileRequest(request);
+
+ const std::string mimeType = "text/plain; charset=utf-8";
+
+ std::ostringstream oss;
+ oss << "HTTP/1.1 200 OK\r\n"
+ << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
+ << "User-Agent: " << WOPI_AGENT_STRING << "\r\n"
+ << "Content-Length: " << hello.size() << "\r\n"
+ << "Content-Type: " << mimeType << "\r\n"
+ << "\r\n"
+ << hello;
+
+ socket->send(oss.str());
+ socket->shutdown();
+
+ if (wopiServerFinish())
+ exitTest(TestResult::Ok);
+
+ return true;
+ }
+
+ return false;
+ }
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit f658067eaa49b55b634615da157a107582e6fbd0
Author: Jan Holesovsky <kendy at collabora.com>
Date: Wed Sep 27 10:15:30 2017 +0200
Don't crash when the parameters are missing.
Change-Id: I96ace7ad7757e7e0c74dd9f361c78ecff6171a96
Reviewed-on: https://gerrit.libreoffice.org/42854
Reviewed-by: pranavk <pranavk at collabora.co.uk>
Tested-by: pranavk <pranavk at collabora.co.uk>
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index c96a8542..cc152e25 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -66,7 +66,7 @@ bool ClientSession::_handleInput(const char *buffer, int length)
{
LOG_TRC(getName() << ": handling incoming [" << getAbbreviatedMessage(buffer, length) << "].");
const std::string firstLine = getFirstLine(buffer, length);
- const auto tokens = LOOLProtocol::tokenize(firstLine.data(), firstLine.size());
+ const std::vector<std::string> tokens = LOOLProtocol::tokenize(firstLine.data(), firstLine.size());
auto docBroker = getDocumentBroker();
if (!docBroker)
@@ -85,6 +85,12 @@ bool ClientSession::_handleInput(const char *buffer, int length)
}
if (tokens[0] == "loolclient")
{
+ if (tokens.size() < 1)
+ {
+ sendTextFrame("error: cmd=loolclient kind=badprotocolversion");
+ return false;
+ }
+
const auto versionTuple = ParseVersion(tokens[1]);
if (std::get<0>(versionTuple) != ProtocolMajorVersionNumber ||
std::get<1>(versionTuple) != ProtocolMinorVersionNumber)
@@ -225,14 +231,20 @@ bool ClientSession::_handleInput(const char *buffer, int length)
{
int dontTerminateEdit = 1;
int dontSaveIfUnmodified = 1;
- getTokenInteger(tokens[1], "dontTerminateEdit", dontTerminateEdit);
- getTokenInteger(tokens[2], "dontSaveIfUnmodified", dontSaveIfUnmodified);
+ if (tokens.size() > 1)
+ getTokenInteger(tokens[1], "dontTerminateEdit", dontTerminateEdit);
+
+ if (tokens.size() > 2)
+ getTokenInteger(tokens[2], "dontSaveIfUnmodified", dontSaveIfUnmodified);
+
docBroker->sendUnoSave(getId(), dontTerminateEdit != 0, dontSaveIfUnmodified != 0);
}
else if (tokens[0] == "savetostorage")
{
int force = 0;
- getTokenInteger(tokens[1], "force", force);
+ if (tokens.size() > 1)
+ getTokenInteger(tokens[1], "force", force);
+
if (docBroker->saveToStorage(getId(), true, "" /* This is irrelevant when success is true*/, true))
{
docBroker->broadcastMessage("commandresult: { \"command\": \"savetostorage\", \"success\": true }");
commit 5c604e9f789fa7d7bf077e35aa7b2c909ac9c9d1
Author: Jan Holesovsky <kendy at collabora.com>
Date: Mon Sep 25 19:16:48 2017 +0200
PutFile ext: X-LOOL-WOPI-IsModifiedByUser header to indicate modifications.
Change-Id: I5d69903211045969d678df695717eae7452e7f04
Reviewed-on: https://gerrit.libreoffice.org/42852
Reviewed-by: pranavk <pranavk at collabora.co.uk>
Tested-by: pranavk <pranavk at collabora.co.uk>
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 91d61c57..ed76b2a6 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -854,6 +854,9 @@ bool DocumentBroker::sendUnoSave(const std::string& sessionId, bool dontTerminat
// arguments end
oss << "}";
+ assert(_storage);
+ _storage->setUserModified(_isModified);
+
const auto saveArgs = oss.str();
LOG_TRC(".uno:Save arguments: " << saveArgs);
const auto command = "uno .uno:Save " + saveArgs;
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index c6b4339f..9003c75c 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -764,6 +764,7 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization&
Poco::DateTimeFormatter::format(Poco::DateTime(_fileInfo._modifiedTime),
Poco::DateTimeFormat::ISO8601_FRAC_FORMAT));
}
+ request.set("X-LOOL-WOPI-IsModifiedByUser", _isUserModified? "true": "false");
request.setContentType("application/octet-stream");
request.setContentLength(size);
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index 389c228d..31ab6c2f 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -78,7 +78,8 @@ public:
_jailPath(jailPath),
_fileInfo("", "lool", Poco::Timestamp::fromEpochTime(0), 0),
_isLoaded(false),
- _forceSave(false)
+ _forceSave(false),
+ _isUserModified(false)
{
LOG_DBG("Storage ctor: " << uri.toString());
}
@@ -96,6 +97,9 @@ public:
/// even if document turned out to be changed in storage
void forceSave() { _forceSave = true; }
+ /// To be able to set the WOPI extension header appropriately.
+ void setUserModified(bool isUserModified) { _isUserModified = isUserModified; }
+
/// Returns the basic information about the file.
const FileInfo& getFileInfo() const { return _fileInfo; }
@@ -131,6 +135,9 @@ protected:
bool _isLoaded;
bool _forceSave;
+ /// The document has been modified by the user.
+ bool _isUserModified;
+
static bool FilesystemEnabled;
static bool WopiEnabled;
/// Allowed/denied WOPI hosts, if any and if WOPI is enabled.
diff --git a/wsd/reference.txt b/wsd/reference.txt
index 3d633f99..90eedfc3 100644
--- a/wsd/reference.txt
+++ b/wsd/reference.txt
@@ -92,3 +92,14 @@ The 'access_header' can be eg. of a form
This header is then used in all the WOPI calls like PutFile, GetFile or
CheckFileInfo, allowing Basic authentication to work.
+
+PutFile headers
+---------------
+
+PutFile additionally indicates whether the user has modified the document
+before the save, or if they just pressed the Save button without any
+modification. The following header:
+
+ X-LOOL-WOPI-IsModifiedByUser
+
+will have the value 'true' or 'false' accordingly.
More information about the Libreoffice-commits
mailing list