Rebased ref, commits from common ancestor:
commit 0a196e5f6494111a71038c2525510b30248f60eb
Author:     Michael Meeks <[email protected]>
AuthorDate: Wed Mar 4 13:54:04 2020 +0000
Commit:     Michael Meeks <[email protected]>
CommitDate: Wed Mar 4 14:57:07 2020 +0000

    Proxy websocket prototype.
    
    Try to read/write avoiding a websocket.
    
    Change-Id: I382039fa88f1030a63df1e47f687df2ee5a6055b

diff --git a/loleaflet/js/global.js b/loleaflet/js/global.js
index f98450fb0..d60f73f7b 100644
--- a/loleaflet/js/global.js
+++ b/loleaflet/js/global.js
@@ -166,16 +166,90 @@
                };
                this.onopen = function() {
                };
+               this.close = function() {
+               };
        };
-
-       global.FakeWebSocket.prototype.close = function() {
-       };
-
        global.FakeWebSocket.prototype.send = function(data) {
                this.sendCounter++;
                window.postMobileMessage(data);
        };
 
+       global.proxySocketCounter = 0;
+       global.ProxySocket = function (uri) {
+               this.uri = uri;
+               this.binaryType = 'arraybuffer';
+               this.bufferedAmount = 0;
+               this.extensions = '';
+               this.protocol = '';
+               this.connected = true;
+               this.readyState = 0; // connecting
+               this.sessionId = 'fetchsession';
+               this.id = window.proxySocketCounter++;
+               this.sendCounter = 0;
+               this.readWaiting = false;
+               this.onclose = function() {
+               };
+               this.onerror = function() {
+               };
+               this.onmessage = function() {
+               };
+               this.send = function(msg) {
+                       console.debug('send msg "' + msg + '"');
+                       var req = new XMLHttpRequest();
+                       req.open("POST", this.getEndPoint('write'));
+                       req.send(this.sessionId + '\r\n' + msg);
+               },
+               this.close = function() {
+                       console.debug('close socket');
+                       this.readyState = 3;
+                       this.onclose();
+               };
+               this.getEndPoint = function(type) {
+                       var base = this.uri;
+                       return base.replace(/^ws/, 'http') + '/' + type;
+               };
+               console.debug('New proxy socket ' + this.id + ' ' + this.uri);
+
+               var that = this;
+
+               // horrors ...
+               this.readInterval = setInterval(function(){
+                       if (this.readWaiting) // one at a time for now
+                               return;
+                       var req = new XMLHttpRequest();
+                       // fetch session id:
+                       req.addEventListener('load', function(){
+                               console.debug('read: ' + this.responseText);
+                               if (that.sessionId === 'fetchsession')
+                               {
+                                       that.sessionId = this.responseText;
+                                       that.readyState = 1;
+                                       that.onopen();
+                               }
+                               else if (this.status == 200)
+                               {
+                                       that.onmessage({ data: this.response });
+                               }
+                               else
+                               {
+                                       console.debug('Handle error ' + 
this.status);
+                               }
+                               that.readWaiting = false;
+                       });
+                       req.open("GET", that.getEndPoint('read'));
+                       req.send(that.sessionId);
+                       that.readWaiting = true;
+               }, 250);
+       };
+
+       global.createWebSocket = function(uri) {
+               if (global.socketProxy) {
+                       return new global.ProxySocket(uri);
+               } else {
+                       return new WebSocket(uri);
+               }
+       };
+
        // If not debug, don't print anything on the console
        // except in tile debug mode (Ctrl-Shift-Alt-d)
        console.log2 = console.log;
@@ -275,7 +349,7 @@
                var websocketURI = global.host + global.serviceRoot + '/lool/' 
+ encodeURIComponent(global.docURL + (docParams ? '?' + docParams : '')) + 
'/ws' + wopiSrc;
 
                try {
-                       global.socket = new WebSocket(websocketURI);
+                       global.socket = global.createWebSocket(websocketURI);
                } catch (err) {
                        console.log(err);
                }
diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js
index a173ef784..0d74b9bd8 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -49,7 +49,7 @@ L.Socket = L.Class.extend({
                        }
 
                        try {
-                               this.socket = new 
WebSocket(this.getWebSocketBaseURI(map) + wopiSrc);
+                               this.socket = 
window.createWebSocket(this.getWebSocketBaseURI(map) + wopiSrc);
                        } catch (e) {
                                // On IE 11 there is a limitation on the number 
of WebSockets open to a single domain (6 by default and can go to 128).
                                // Detect this and hint the user.
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 61b9d8f09..1bff34c1e 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -2247,6 +2247,13 @@ private:
 //                    Util::dumpHex(std::cerr, "clipboard:\n", "", 
socket->getInBuffer()); // lots of data ...
                     handleClipboardRequest(request, message, disposition);
                 }
+                else if (request.has("ProxyPrefix") && reqPathTokens.count() > 
2 &&
+                         (reqPathTokens[reqPathTokens.count()-2] == "ws"))
+                {
+                    std::string decodedUri; // WOPISrc
+                    Poco::URI::decode(reqPathTokens[1], decodedUri);
+                    handleClientProxyRequest(request, decodedUri, message, 
disposition);
+                }
                 else if (!(request.find("Upgrade") != request.end() && 
Poco::icompare(request["Upgrade"], "websocket") == 0) &&
                     reqPathTokens.count() > 0 && reqPathTokens[0] == "lool")
                 {
@@ -2780,6 +2787,23 @@ private:
     }
 #endif
 
+    void handleClientProxyRequest(const Poco::Net::HTTPRequest& request,
+                                  std::string url,
+                                  Poco::MemoryInputStream& message,
+                                  SocketDisposition &disposition)
+    {
+        LOG_INF("URL [" << url << "].");
+        const auto uriPublic = DocumentBroker::sanitizeURI(url);
+        LOG_INF("URI [" << uriPublic.getPath() << "].");
+        const auto docKey = DocumentBroker::getDocKey(uriPublic);
+        LOG_INF("DocKey [" << docKey << "].");
+        const std::string fileId = Util::getFilenameFromURL(docKey);
+        Util::mapAnonymized(fileId, fileId); // Identity mapping, since fileId 
is already obfuscated
+
+        LOG_INF("Starting Proxy request handler for session [" << _id << "] on 
url [" << LOOLWSD::anonymizeUrl(url) << "].");
+        (void)request; (void) message; (void) disposition;
+    }
+
     void handleClientWsUpgrade(const Poco::Net::HTTPRequest& request, const 
std::string& url,
                                SocketDisposition &disposition)
     {
_______________________________________________
Libreoffice-commits mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to