[Libreoffice-commits] online.git: loleaflet/js

Michael Meeks (via logerrit) logerrit at kemper.freedesktop.org
Mon Jun 8 19:19:06 UTC 2020


 loleaflet/js/global.js |   46 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 5 deletions(-)

New commits:
commit 58e5016917e325248fdb01a83030051c3a3df975
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Mon Jun 8 15:46:29 2020 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 8 21:18:47 2020 +0200

    Proxy: handle server startup / un-responsive DocumentBroker creation.
    
    If our 'open' request fails - then we could get this loop:
    
    loadDocument (proxy.php?req=/loleaflet/d2d049224/src/map/Map.js:318)
    _activate (proxy.php?req=/loleaflet/d2d049224/src/map/Map.js:1233)
    _onSocketClose (proxy.php?req=/loleaflet/d2d049224/src/core/Socket.js:1045)
    _signalErrorClose (proxy.php?req=/loleaflet/0acb00fc2/loleaflet.html?file_path=file:///tmp/copy.odt:576)
    (anonymous) (proxy.php?req=/loleaflet/0acb00fc2/loleaflet.html?file_path=file:///tmp/copy.odt:688)
    load (async)
    getSessionId (proxy.php?req=/loleaflet/0acb00fc2/loleaflet.html?file_path=file:///tmp/copy.odt:682)
    global.ProxySocket (proxy.php?req=/loleaflet/0acb00fc2/loleaflet.html?file_path=file:///tmp/copy.odt:753)
    global.createWebSocket (proxy.php?req=/loleaflet/0acb00fc2/loleaflet.html?file_path=file:///tmp/copy.odt:798)
    connect (proxy.php?req=/loleaflet/d2d049224/src/core/Socket.js:52)
    loadDocument (proxy.php?req=/loleaflet/d2d049224/src/map/Map.js:318)
    
    Which would hammer the server with large numbers of requests triggering
    DoS protection in some cases, so:
    1. only allow one 'open' in-flight at a time
    2. global time-accounting to not allow >1 new ProxySocket every 250ms
    3. handle error returns from 'open' correctly.
    
    Change-Id: I1692acd72a445ebc70a83c66a2e802a532c66e21
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/95837
    Tested-by: Jenkins
    Tested-by: Michael Meeks <michael.meeks at collabora.com>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/loleaflet/js/global.js b/loleaflet/js/global.js
index 47bc7b648..d50739193 100644
--- a/loleaflet/js/global.js
+++ b/loleaflet/js/global.js
@@ -221,6 +221,7 @@
 		this.id = window.proxySocketCounter++;
 		this.sendCounter = 0;
 		this.msgInflight = 0;
+		this.openInflight = 0;
 		this.inSerial = 0;
 		this.outSerial = 0;
 		this.minPollMs = 25; // Anything less than ~25 ms can overwhelm the HTTP server.
@@ -354,8 +355,13 @@
 				this.onerror();
 				this.onclose();
 				clearInterval(this.waitInterval);
+				clearTimeout(this.delaySession);
 				this.waitInterval = undefined;
 				this.sessionId = 'open';
+				this.inSerial = 0;
+				this.outSerial = 0;
+				this.msgInflight = 0;
+				this.openInflight = 0;
 			}
 			this.readyState = 3; // CLOSED
 		};
@@ -371,9 +377,6 @@
 					console.debug('Session closed, opening a new one.');
 					that.getSessionId();
 				}
-				else
-					console.debug('New session not completed.');
-
 				return;
 			}
 
@@ -448,14 +451,41 @@
 			that.msgInflight++;
 		};
 		this.getSessionId = function() {
+			if (this.openInflight > 0)
+			{
+				console.debug('Waiting for session open');
+				return;
+			}
+
+			if (this.delaySession)
+				return;
+
+			// avoid attempting to re-connect too quickly
+			if (global.lastCreatedProxySocket)
+			{
+				var msSince = performance.now() - global.lastCreatedProxySocket;
+				if (msSince < 250) {
+					var delay = 250 - msSince;
+					console.debug('Wait to re-try session creation for ' + delay + 'ms');
+					this.curPollMs = delay; // ms
+					this.delaySession = setTimeout(function() {
+						that.delaySession = undefined;
+						that.getSessionId();
+					}, delay);
+					return;
+				}
+			}
+			global.lastCreatedProxySocket = performance.now();
+
 			var req = new XMLHttpRequest();
 			req.open('POST', that.getEndPoint('open'));
 			req.responseType = 'text';
 			req.addEventListener('load', function() {
 				console.debug('got session: ' + this.responseText);
-				if (this.responseText.indexOf('\n') >= 0)
+				if (this.status !== 200 || !this.responseText ||
+				    this.responseText.indexOf('\n') >= 0) // multi-line error
 				{
-					console.debug('Error: failed to fetch session id!');
+					console.debug('Error: failed to fetch session id! error: ' + this.status);
 					that._signalErrorClose();
 				}
 				else
@@ -465,7 +495,12 @@
 					that.onopen();
 				}
 			});
+			req.addEventListener('loadend', function() {
+				console.debug('Open completed state: ' + that.readyState);
+				that.openInflight--;
+			});
 			req.send('');
+			this.openInflight++;
 		};
 		this.send = function(msg) {
 			var hadData = this.sendQueue.length > 0;
@@ -503,6 +538,7 @@
 			this.readyState = 3;
 			this.onclose();
 			clearInterval(this.waitInterval);
+			clearTimeout(this.delaySession);
 			this.waitInterval = undefined;
 			if (oldState === 1) // was open
 				this.sendCloseMsg(this.unloading);


More information about the Libreoffice-commits mailing list