diff --git a/loleaflet/dist/errormessages.js b/loleaflet/dist/errormessages.js
index fa6a99979..edda0764e 100644
--- a/loleaflet/dist/errormessages.js
+++ b/loleaflet/dist/errormessages.js
@@ -1,6 +1,6 @@
exports.diskfull = _('No disk space left on server, please contact the server administrator to continue.');
exports.emptyhosturl = _('The host URL is empty. The loolwsd server is probably misconfigured, please contact the administrator.');
-exports.limitreached = _('This development build is limited to %0 documents, and %1 connections - to avoid the impression that it is suitable for deployment in large enterprises. To find out more about deploying and scaling %2 check out:
%3.');
+exports.limitreached = _('This is an unsupported version of {productname}. To avoid the impression that it is suitable for deployment in enterprises, this version is limited to {docs} documents, and {connections} connections.
{a}More information and support{/a}');
exports.limitreachedprod = _('This service is limited to %0 documents, and %1 connections total by the admin. This limit has been reached. Please try again later.');
exports.serviceunavailable = _('Service is unavailable. Please try again later and report to your administrator if the issue persists.');
exports.unauthorized = _('Unauthorized WOPI host. Please try again later and report to your administrator if the issue persists.');
diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js
index 9cb99c236..3e33a88de 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -7,6 +7,7 @@
L.Socket = L.Class.extend({
ProtocolVersionNumber: '0.1',
ReconnectCount: 0,
+ WasShownLimitDialog: false,
getParameterValue: function (s) {
var i = s.indexOf('=');
@@ -550,31 +551,34 @@ L.Socket = L.Class.extend({
}
else if (textMsg.startsWith('error:') && !this._map._docLayer) {
textMsg = textMsg.substring(6);
- if (command.errorKind === 'limitreached') {
- this._map._fatal = true;
- this._map._active = false; // Practically disconnected.
+ if (command.errorKind === 'hardlimitreached') {
- // Servers configured for 50 documents are not demo/development.
- if (parseInt(command.params[0]) >= 50) {
- textMsg = errorMessages.limitreachedprod;
- textMsg = textMsg.replace(/%0/g, command.params[0]);
- textMsg = textMsg.replace(/%1/g, command.params[1]);
- }
- else {
- textMsg = errorMessages.limitreached;
- textMsg = textMsg.replace(/%0/g, command.params[0]);
- textMsg = textMsg.replace(/%1/g, command.params[1]);
- textMsg = textMsg.replace(/%2/g, (typeof brandProductName !== 'undefined' ? brandProductName : 'LibreOffice Online'));
- textMsg = textMsg.replace(/%3/g, (typeof brandProductFAQURL !== 'undefined' ? brandProductFAQURL : 'https://wiki.documentfoundation.org/Development/LibreOffice_Online'));
- }
+ textMsg = errorMessages.limitreachedprod;
+ textMsg = textMsg.replace(/%0/g, command.params[0]);
+ textMsg = textMsg.replace(/%1/g, command.params[1]);
}
else if (command.errorKind === 'serviceunavailable') {
- this._map._fatal = true;
- this._map._active = false; // Practically disconnected.
textMsg = errorMessages.serviceunavailable;
}
+ this._map._fatal = true;
+ this._map._active = false; // Practically disconnected.
this._map.fire('error', {msg: textMsg});
}
+ else if (textMsg.startsWith('info:') && command.errorCmd === 'socket') {
+ if (command.errorKind === 'limitreached' && !this.WasShownLimitDialog) {
+ this.WasShownLimitDialog = true;
+ textMsg = errorMessages.limitreached;
+ textMsg = textMsg.replace(/{docs}/g, command.params[0]);
+ textMsg = textMsg.replace(/{connections}/g, command.params[1]);
+ textMsg = textMsg.replace(/{productname}/g, (typeof brandProductName !== 'undefined' ?
+ brandProductName : 'LibreOffice Online'));
+ brandProductFAQURL = (typeof brandProductFAQURL !== 'undefined') ?
+ brandProductFAQURL : 'https://hub.libreoffice.org/professional-online-support';
+ textMsg = textMsg.replace(/{a}/g, '');
+ textMsg = textMsg.replace(/{\/a}/g, '');
+ this._map.fire('error', {msg: textMsg});
+ }
+ }
else if (textMsg.startsWith('pong ') && this._map._docLayer && this._map._docLayer._debug) {
var times = this._map._docLayer._debugTimePING;
var timeText = this._map._docLayer._debugSetTimes(times, +new Date() - this._map._docLayer._debugPINGQueue.shift());
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index e27266e45..24b5a4aa9 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -196,7 +196,7 @@ namespace
inline void shutdownLimitReached(WebSocketHandler& ws)
{
const std::string error = Poco::format(PAYLOAD_UNAVAILABLE_LIMIT_REACHED, LOOLWSD::MaxDocuments, LOOLWSD::MaxConnections);
- LOG_INF("Sending client limit-reached message: " << error);
+ LOG_INF("Sending client 'hardlimitreached' message: " << error);
try
{
@@ -212,6 +212,22 @@ inline void shutdownLimitReached(WebSocketHandler& ws)
}
}
+inline void infoLimitReached()
+{
+ const std::string info = Poco::format(PAYLOAD_INFO_LIMIT_REACHED, LOOLWSD::MaxDocuments, LOOLWSD::MaxConnections);
+ LOG_INF("Sending client 'limitreached' message: " << info);
+
+ try
+ {
+ Util::alertAllUsers(info);
+ }
+ catch (const std::exception& ex)
+ {
+ LOG_ERR("Error while shuting down socket on reaching limit: " << ex.what());
+ }
+}
+
+
/// Internal implementation to alert all clients
/// connected to any document.
void alertAllUsersInternal(const std::string& msg)
@@ -1454,9 +1470,11 @@ static std::shared_ptr findOrCreateDocBroker(WebSocketHandler& w
if (DocBrokers.size() + 1 > LOOLWSD::MaxDocuments)
{
- LOG_ERR("Maximum number of open documents of " << LOOLWSD::MaxDocuments << " reached.");
+ LOG_INF("Maximum number of open documents of " << LOOLWSD::MaxDocuments << " reached.");
+#if ENABLE_SUPPORT_KEY
shutdownLimitReached(ws);
return nullptr;
+#endif
}
// Set the one we just created.
@@ -1486,6 +1504,13 @@ static std::shared_ptr createNewClientSession(const WebSocketHand
// Alert all other existing sessions also
Util::alertAllUsers(diskfullMsg);
}
+#if !ENABLE_SUPPORT_KEY
+ // Users of development versions get just an info when reaching max documents or connections
+ if (DocBrokers.size() + 1 > LOOLWSD::MaxDocuments || LOOLWSD::NumConnections >= LOOLWSD::MaxConnections)
+ {
+ infoLimitReached();
+ }
+#endif
// Now we have a DocumentBroker and we're ready to process client commands.
if (ws)
@@ -2257,9 +2282,11 @@ private:
{
if (LOOLWSD::NumConnections >= LOOLWSD::MaxConnections)
{
- LOG_ERR("Limit on maximum number of connections of " << LOOLWSD::MaxConnections << " reached.");
+ LOG_INF("Limit on maximum number of connections of " << LOOLWSD::MaxConnections << " reached.");
+#if ENABLE_SUPPORT_KEY
shutdownLimitReached(ws);
return;
+#endif
}
LOG_INF("Starting GET request handler for session [" << _id << "] on url [" << url << "].");
diff --git a/wsd/UserMessages.hpp b/wsd/UserMessages.hpp
index 3efbdf8d9..00ad7875b 100644
--- a/wsd/UserMessages.hpp
+++ b/wsd/UserMessages.hpp
@@ -13,7 +13,8 @@
#define INCLUDED_USERMESSAGES_HPP
constexpr const char* SERVICE_UNAVAILABLE_INTERNAL_ERROR = "error: cmd=socket kind=serviceunavailable";
-constexpr const char* PAYLOAD_UNAVAILABLE_LIMIT_REACHED = "error: cmd=socket kind=limitreached params=%u,%u";
+constexpr const char* PAYLOAD_UNAVAILABLE_LIMIT_REACHED = "error: cmd=socket kind=hardlimitreached params=%u,%u";
+constexpr const char* PAYLOAD_INFO_LIMIT_REACHED = "info: cmd=socket kind=limitreached params=%u,%u";
#endif