[Libreoffice-commits] online.git: loleaflet/js wsd/ProxyProtocol.cpp wsd/ProxyProtocol.hpp
Michael Meeks (via logerrit)
logerrit at kemper.freedesktop.org
Fri Apr 24 18:42:27 UTC 2020
loleaflet/js/global.js | 32 +++++++++++++++++++++++++++++---
wsd/ProxyProtocol.cpp | 25 ++++++++++++++++++++++---
wsd/ProxyProtocol.hpp | 14 ++++++++++----
3 files changed, 61 insertions(+), 10 deletions(-)
New commits:
commit b4feecde2d70a853cdc18edd8816a45ad8c87e29
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Sat Apr 18 18:40:59 2020 +0100
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Fri Apr 24 20:42:05 2020 +0200
Proxy: marshal message serial too.
Change-Id: I23a28fe052062a0b98bbb2828b71ab8de6f1459c
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92816
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Jan Holesovsky <kendy at collabora.com>
diff --git a/loleaflet/js/global.js b/loleaflet/js/global.js
index cc1ab2090..640da1e3f 100644
--- a/loleaflet/js/global.js
+++ b/loleaflet/js/global.js
@@ -208,6 +208,8 @@
this.id = window.proxySocketCounter++;
this.sendCounter = 0;
this.readWaiting = 0;
+ this.inSerial = 0;
+ this.outSerial = 0;
this.onclose = function() {
};
this.onerror = function() {
@@ -231,17 +233,35 @@
console.debug('wrong data type: ' + type);
break;
}
- if (arr[i+1] !== 48 && arr[i+2] !== 120) // '0x'
+ i++;
+
+ // Serial
+ if (arr[i] !== 48 && arr[i+1] !== 120) // '0x'
{
console.debug('missing hex preamble');
break;
}
- i += 3;
+ i += 2;
var numStr = '';
var start = i;
while (arr[i] != 10) // '\n'
i++;
numStr = decoder.decode(arr.slice(start, i)); // FIXME: IE11
+ var serial = parseInt(numStr, 16);
+
+ i++; // skip \n
+
+ // Size:
+ if (arr[i] !== 48 && arr[i+1] !== 120) // '0x'
+ {
+ console.debug('missing hex preamble');
+ break;
+ }
+ i += 2;
+ start = i;
+ while (arr[i] != 10) // '\n'
+ i++;
+ numStr = decoder.decode(arr.slice(start, i)); // FIXME: IE11
var size = parseInt(numStr, 16);
i++; // skip \n
@@ -252,6 +272,10 @@
else
data = arr.slice(i, i + size);
+ if (serial !== that.inSerial + 1) {
+ console.debug('Error: serial mismatch ' + serial + ' vs. ' + (that.inSerial + 1));
+ }
+ that.inSerial = serial;
this.onmessage({ data: data });
i += size; // skip trailing '\n' in loop-increment
@@ -295,7 +319,9 @@
};
this.send = function(msg) {
this.sendQueue = this.sendQueue.concat(
- 'B0x' + msg.length.toString(16) + '\n' + msg + '\n');
+ 'B0x' + this.outSerial.toString(16) + '\n' +
+ '0x' + msg.length.toString(16) + '\n' + msg + '\n');
+ this.outSerial++;
if (this.sessionId !== 'fetchsession' && this.sendTimeout === undefined)
this.sendTimeout = setTimeout(this.doSend, 2 /* ms */);
};
diff --git a/wsd/ProxyProtocol.cpp b/wsd/ProxyProtocol.cpp
index c8a259abe..973d9f3c5 100644
--- a/wsd/ProxyProtocol.cpp
+++ b/wsd/ProxyProtocol.cpp
@@ -97,21 +97,37 @@ bool ProxyProtocolHandler::parseEmitIncoming(
while (in.size() > 0)
{
- if (in[0] != 'T' && in[0] != 'B')
+ // Type
+ if ((in[0] != 'T' && in[0] != 'B') || in.size() < 2)
{
LOG_ERR("Invalid message type " << in[0]);
return false;
}
auto it = in.begin() + 1;
+
+ // Serial
for (; it != in.end() && *it != '\n'; ++it);
*it = '\0';
- uint64_t len = strtoll( &in[1], nullptr, 16 );
+ uint64_t serial = strtoll( &in[1], nullptr, 16 );
+ in.erase(in.begin(), it + 1);
+ if (in.size() < 2)
+ {
+ LOG_ERR("Invalid message framing size " << in.size());
+ return false;
+ }
+
+ // Length
+ it = in.begin();
+ for (; it != in.end() && *it != '\n'; ++it);
+ *it = '\0';
+ uint64_t len = strtoll( &in[0], nullptr, 16 );
in.erase(in.begin(), it + 1);
if (len > in.size())
{
LOG_ERR("Invalid message length " << len << " vs " << in.size());
return false;
}
+
// far from efficient:
std::vector<char> data;
data.insert(data.begin(), in.begin(), in.begin() + len + 1);
@@ -124,6 +140,9 @@ bool ProxyProtocolHandler::parseEmitIncoming(
}
in.erase(in.begin(), in.begin() + 1);
+ if (serial != _inSerial + 1)
+ LOG_ERR("Serial mismatch " << serial << " vs. " << (_inSerial + 1));
+ _inSerial = serial;
_msgHandler->handleMessage(data);
}
return true;
@@ -180,7 +199,7 @@ void ProxyProtocolHandler::handleIncomingMessage(SocketDisposition &disposition)
int ProxyProtocolHandler::sendMessage(const char *msg, const size_t len, bool text, bool flush)
{
- _writeQueue.push_back(std::make_shared<Message>(msg, len, text));
+ _writeQueue.push_back(std::make_shared<Message>(msg, len, text, _outSerial++));
if (flush)
{
auto sock = popOutSocket();
diff --git a/wsd/ProxyProtocol.hpp b/wsd/ProxyProtocol.hpp
index eb15edfdd..7bca66600 100644
--- a/wsd/ProxyProtocol.hpp
+++ b/wsd/ProxyProtocol.hpp
@@ -16,12 +16,16 @@
* Implementation that builds a websocket like protocol from many
* individual proxied HTTP requests back to back.
*
- * we use a trivial framing: <hex-length>\r\n<content>\r\n
+ * we use a trivial framing: [T(ext)|B(inary)]<hex-serial->\n<hex-length>\n<content>\n
*/
class ProxyProtocolHandler : public ProtocolHandlerInterface
{
public:
- ProxyProtocolHandler() { }
+ ProxyProtocolHandler() :
+ _inSerial(0),
+ _outSerial(0)
+ {
+ }
virtual ~ProxyProtocolHandler() { }
@@ -67,12 +71,12 @@ private:
struct Message : public std::vector<char>
{
- Message(const char *msg, const size_t len, bool text)
+ Message(const char *msg, const size_t len, bool text, uint64_t serial)
{
const char *type = text ? "T" : "B";
insert(end(), type, type + 1);
std::ostringstream os;
- os << std::hex << "0x" << len << "\n";
+ os << std::hex << "0x" << serial << "\n" << "0x" << len << "\n";
std::string str = os.str();
insert(end(), str.c_str(), str.c_str() + str.size());
insert(end(), msg, msg + len);
@@ -83,6 +87,8 @@ private:
/// queue things when we have no socket to hand.
std::vector<std::shared_ptr<Message>> _writeQueue;
std::vector<std::weak_ptr<StreamSocket>> _outSockets;
+ uint64_t _inSerial;
+ uint64_t _outSerial;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list