wsd: move deprecated logic under legacy_server config

We no longer send LOOL-WOPI headers, unless
the configuration specifically flags for
legacy servers. But we always send COOL-WOPI
even to legacy servers, to help them upgrade
seamlessly.

Change-Id: Ifc919ed8f6665cd8f846117ef4e8b7ef09fbd563
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
This commit is contained in:
Ashod Nakashian 2024-02-29 20:50:36 -05:00 committed by Ashod Nakashian
parent 9cf64b0726
commit 2e8561195c
8 changed files with 39 additions and 17 deletions

View file

@ -254,6 +254,7 @@
<!-- More "group"s possible here -->
</alias_groups>
<is_legacy_server desc="Set to true for legacy server that need deprecated headers." type="bool" default="false"></is_legacy_server>
</wopi>
<ssl desc="SSL settings">
<as_scheme type="bool" default="true" desc="When set we exclusively use the WOPI URI's scheme to enable SSL for storage">true</as_scheme>

View file

@ -44,11 +44,11 @@ public:
{
// The document is modified.
LOK_ASSERT_EQUAL(std::string("true"), request.get("X-COOL-WOPI-IsModifiedByUser"));
LOK_ASSERT_EQUAL(std::string("true"), request.get("X-LOOL-WOPI-IsModifiedByUser"));
LOK_ASSERT_EQUAL(false, request.has("X-LOOL-WOPI-IsModifiedByUser"));
// Triggered manually or during closing, not auto-save.
LOK_ASSERT_EQUAL(std::string("false"), request.get("X-COOL-WOPI-IsAutosave"));
LOK_ASSERT_EQUAL(std::string("false"), request.get("X-LOOL-WOPI-IsAutosave"));
LOK_ASSERT_EQUAL(false, request.has("X-LOOL-WOPI-IsAutosave"));
TRANSITION_STATE(_phase, Phase::WaitDestroy);

View file

@ -483,6 +483,7 @@ public:
// We intentionally fail uploading twice, so need at least 3 tries.
config.setUInt("per_document.limit_store_failures", 3);
config.setBool("per_document.always_save_on_exit", false);
config.setBool("storage.wopi.is_legacy_server", true);
}
std::unique_ptr<http::Response>
@ -653,10 +654,10 @@ public:
assertPutFileRequest(const Poco::Net::HTTPRequest& request) override
{
LOK_ASSERT_EQUAL(std::string("true"), request.get("X-COOL-WOPI-IsModifiedByUser"));
LOK_ASSERT_EQUAL(std::string("true"), request.get("X-LOOL-WOPI-IsModifiedByUser"));
LOK_ASSERT_EQUAL(false, request.has("X-LOOL-WOPI-IsModifiedByUser"));
LOK_ASSERT_EQUAL(std::string("false"), request.get("X-COOL-WOPI-IsAutosave"));
LOK_ASSERT_EQUAL(std::string("false"), request.get("X-LOOL-WOPI-IsAutosave"));
LOK_ASSERT_EQUAL(false, request.has("X-LOOL-WOPI-IsAutosave"));
// We save twice. First right after loading, unmodified.
if (_phase == Phase::WaitFirstPutFile)
@ -665,7 +666,7 @@ public:
// Certainly not exiting yet.
LOK_ASSERT_EQUAL(std::string("false"), request.get("X-COOL-WOPI-IsExitSave"));
LOK_ASSERT_EQUAL(std::string("false"), request.get("X-LOOL-WOPI-IsExitSave"));
LOK_ASSERT_EQUAL(false, request.has("X-LOOL-WOPI-IsExitSave"));
// Fail with error.
LOG_TST("Returning 500 to simulate PutFile failure");
@ -678,7 +679,7 @@ public:
// Triggered while closing.
LOK_ASSERT_EQUAL(std::string("true"), request.get("X-COOL-WOPI-IsExitSave"));
LOK_ASSERT_EQUAL(std::string("true"), request.get("X-LOOL-WOPI-IsExitSave"));
LOK_ASSERT_EQUAL(false, request.has("X-LOOL-WOPI-IsExitSave"));
return nullptr;
}

View file

@ -225,11 +225,11 @@ public:
// The document is modified.
LOK_ASSERT_EQUAL(std::string("true"), request.get("X-COOL-WOPI-IsModifiedByUser"));
LOK_ASSERT_EQUAL(std::string("true"), request.get("X-LOOL-WOPI-IsModifiedByUser"));
LOK_ASSERT_EQUAL(false, request.has("X-LOOL-WOPI-IsModifiedByUser"));
// Triggered manually or during closing, not auto-save.
LOK_ASSERT_EQUAL(std::string("false"), request.get("X-COOL-WOPI-IsAutosave"));
LOK_ASSERT_EQUAL(std::string("false"), request.get("X-LOOL-WOPI-IsAutosave"));
LOK_ASSERT_EQUAL(false, request.has("X-LOOL-WOPI-IsAutosave"));
// The only editor goes away.
// LOK_ASSERT_EQUAL(std::string("true"), request.get("X-COOL-WOPI-IsExitSave"));

View file

@ -246,6 +246,9 @@ protected:
UnitWSD::configure(config);
// we're still internally confused as to https vs. http in places.
config.setBool("storage.ssl.as_scheme", false);
// Reset to default.
config.setBool("storage.wopi.is_legacy_server", false);
}
/// Returns the default CheckFileInfo json.

View file

@ -2052,6 +2052,7 @@ void COOLWSD::innerInitialize(Application& self)
{ "storage.wopi.max_file_size", "0" },
{ "storage.wopi[@allow]", "true" },
{ "storage.wopi.locking.refresh", "900" },
{ "storage.wopi.is_legacy_server", "false" },
{ "sys_template_path", "systemplate" },
{ "trace_event[@enable]", "false" },
{ "trace.path[@compress]", "true" },

View file

@ -835,7 +835,8 @@ StorageBase::LockUpdateResult WopiStorage::updateLockState(const Authorization&
if (!attribs.getExtendedData().empty())
{
request.set("X-COOL-WOPI-ExtendedData", attribs.getExtendedData());
request.set("X-LOOL-WOPI-ExtendedData", attribs.getExtendedData());
if (isLegacyServer())
request.set("X-LOOL-WOPI-ExtendedData", attribs.getExtendedData());
}
// IIS requires content-length for POST requests: see https://forums.iis.net/t/1119456.aspx
@ -1137,25 +1138,33 @@ void WopiStorage::uploadLocalFileToStorageAsync(const Authorization& auth, LockC
{
// normal save
httpHeader.set("X-WOPI-Override", "PUT");
httpHeader.set("X-COOL-WOPI-IsModifiedByUser", attribs.isUserModified() ? "true" : "false");
httpHeader.set("X-LOOL-WOPI-IsModifiedByUser", attribs.isUserModified() ? "true" : "false");
httpHeader.set("X-COOL-WOPI-IsModifiedByUser",
attribs.isUserModified() ? "true" : "false");
httpHeader.set("X-COOL-WOPI-IsAutosave", attribs.isAutosave() ? "true" : "false");
httpHeader.set("X-LOOL-WOPI-IsAutosave", attribs.isAutosave() ? "true" : "false");
httpHeader.set("X-COOL-WOPI-IsExitSave", attribs.isExitSave() ? "true" : "false");
httpHeader.set("X-LOOL-WOPI-IsExitSave", attribs.isExitSave() ? "true" : "false");
if (isLegacyServer())
{
httpHeader.set("X-LOOL-WOPI-IsModifiedByUser",
attribs.isUserModified() ? "true" : "false");
httpHeader.set("X-LOOL-WOPI-IsAutosave", attribs.isAutosave() ? "true" : "false");
httpHeader.set("X-LOOL-WOPI-IsExitSave", attribs.isExitSave() ? "true" : "false");
}
if (attribs.isExitSave())
httpHeader.set("Connection", "close"); // Don't maintain the socket if we are exiting.
if (!attribs.getExtendedData().empty())
{
httpHeader.set("X-COOL-WOPI-ExtendedData", attribs.getExtendedData());
httpHeader.set("X-LOOL-WOPI-ExtendedData", attribs.getExtendedData());
if (isLegacyServer())
httpHeader.set("X-LOOL-WOPI-ExtendedData", attribs.getExtendedData());
}
if (!attribs.isForced() && isLastModifiedTimeSafe())
{
// Request WOPI host to not overwrite if timestamps mismatch
httpHeader.set("X-COOL-WOPI-Timestamp", getLastModifiedTime());
httpHeader.set("X-LOOL-WOPI-Timestamp", getLastModifiedTime());
if (isLegacyServer())
httpHeader.set("X-LOOL-WOPI-Timestamp", getLastModifiedTime());
}
}
else

View file

@ -24,7 +24,6 @@
#include "HttpRequest.hpp"
#include "COOLWSD.hpp"
#include "Log.hpp"
#include "Util.hpp"
#include <common/Authorization.hpp>
#include <net/HttpRequest.hpp>
@ -698,12 +697,17 @@ public:
const std::string& jailPath)
: StorageBase(uri, localStorePath, jailPath)
, _wopiSaveDuration(std::chrono::milliseconds::zero())
, _legacyServer(COOLWSD::getConfigValue<bool>("storage.wopi.is_legacy_server", false))
{
LOG_INF("WopiStorage ctor with localStorePath: ["
<< localStorePath << "], jailPath: [" << jailPath << "], uri: ["
<< COOLWSD::anonymizeUrl(uri.toString()) << ']');
<< COOLWSD::anonymizeUrl(uri.toString()) << "], legacy server: " << _legacyServer);
}
/// Signifies if the server is legacy or not, based on the headers
/// it sent us on first contact.
bool isLegacyServer() const { return _legacyServer; }
/// Handles the response from CheckFileInfo, as converted into WOPIFileInfo.
/// Also extracts the basic file information from the response
/// which can then be obtained using getFileInfo()
@ -774,6 +778,9 @@ private:
/// The http::Session used for uploading asynchronously.
std::shared_ptr<http::Session> _uploadHttpSession;
/// Whether or not this is a legacy server.
const bool _legacyServer;
#endif // !MOBILEAPP
};