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

Reply via email to