loleaflet/js/global.js | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-)
New commits: commit 58e5016917e325248fdb01a83030051c3a3df975 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Mon Jun 8 15:46:29 2020 +0100 Commit: Michael Meeks <michael.me...@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.me...@collabora.com> Reviewed-by: Michael Meeks <michael.me...@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); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits