Protocol versioning added and documented
Change-Id: I6e1df89c7330052bd2d442a42c0b24c8ae4facf6 Reviewed-on: https://gerrit.libreoffice.org/21168 Reviewed-by: Ashod Nakashian <ashnakash@gmail.com> Tested-by: Ashod Nakashian <ashnakash@gmail.com>
This commit is contained in:
parent
9285f50c6b
commit
2d385d697e
6 changed files with 104 additions and 1 deletions
|
@ -3,6 +3,8 @@
|
|||
*/
|
||||
|
||||
L.Socket = {
|
||||
ProtocolVersionNumber: '0.1',
|
||||
|
||||
connect: function (map) {
|
||||
try {
|
||||
this.socket = new WebSocket(map.options.server);
|
||||
|
@ -44,6 +46,10 @@ L.Socket = {
|
|||
},
|
||||
|
||||
_onOpen: function () {
|
||||
// Always send the protocol version number.
|
||||
// TODO: Move the version number somewhere sensible.
|
||||
this.socket.send('loolclient ' + this.ProtocolVersionNumber);
|
||||
|
||||
var msg = 'load url=' + this._map.options.doc;
|
||||
if (this._map._docLayer) {
|
||||
// we are reconnecting after a lost connection
|
||||
|
@ -85,7 +91,17 @@ L.Socket = {
|
|||
textMsg = String.fromCharCode.apply(null, imgBytes.subarray(0, index));
|
||||
}
|
||||
|
||||
if (!textMsg.startsWith('tile:') && !textMsg.startsWith('renderfont:')) {
|
||||
if (textMsg.startsWith('loolserver ')) {
|
||||
// This must be the first message.
|
||||
if (this._map._docLayer) {
|
||||
this.fire('error', {msg: 'Unexpected loolserver message.'});
|
||||
}
|
||||
// TODO: For now we expect perfect match.
|
||||
if (textMsg.substring(11) !== this.ProtocolVersionNumber) {
|
||||
this.fire('error', {msg: 'Unsupported server version.'});
|
||||
}
|
||||
}
|
||||
else if (!textMsg.startsWith('tile:') && !textMsg.startsWith('renderfont:')) {
|
||||
// log the tile msg separately as we need the tile coordinates
|
||||
L.Log.log(textMsg, L.INCOMING);
|
||||
if (imgBytes !== undefined) {
|
||||
|
|
|
@ -23,6 +23,27 @@ using Poco::StringTokenizer;
|
|||
|
||||
namespace LOOLProtocol
|
||||
{
|
||||
std::tuple<signed, signed, std::string> ParseVersion(const std::string& version)
|
||||
{
|
||||
signed major = -1;
|
||||
signed minor = -1;
|
||||
std::string patch;
|
||||
|
||||
StringTokenizer firstTokens(version, ".", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
|
||||
if (firstTokens.count() > 0)
|
||||
{
|
||||
major = std::stoi(firstTokens[0]);
|
||||
|
||||
StringTokenizer secondTokens(firstTokens[1], "-", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
|
||||
minor = std::stoi(secondTokens[0]);
|
||||
|
||||
if (secondTokens.count() > 1)
|
||||
patch = secondTokens[1];
|
||||
}
|
||||
|
||||
return std::make_tuple(major, minor, patch);
|
||||
}
|
||||
|
||||
bool getTokenInteger(const std::string& token, const std::string& name, int& value)
|
||||
{
|
||||
size_t nextIdx;
|
||||
|
|
|
@ -62,6 +62,22 @@ namespace LOOLProtocol
|
|||
TILE,
|
||||
};
|
||||
|
||||
// Protocol Version Number.
|
||||
// See protocol.txt.
|
||||
constexpr unsigned ProtocolMajorVersionNumber = 0;
|
||||
constexpr unsigned ProtocolMinorVersionNumber = 1;
|
||||
|
||||
inline
|
||||
std::string GetProtocolVersion()
|
||||
{
|
||||
return std::to_string(ProtocolMajorVersionNumber) + '.'
|
||||
+ std::to_string(ProtocolMinorVersionNumber);
|
||||
}
|
||||
|
||||
// Parse a string into a version tuple.
|
||||
// Negative numbers for error.
|
||||
std::tuple<signed, signed, std::string> ParseVersion(const std::string& version);
|
||||
|
||||
bool getTokenInteger(const std::string& token, const std::string& name, int& value);
|
||||
bool getTokenString(const std::string& token, const std::string& name, std::string& value);
|
||||
bool getTokenKeyword(const std::string& token, const std::string& name, const std::map<std::string, int>& map, int& value);
|
||||
|
|
|
@ -115,6 +115,20 @@ public:
|
|||
#endif
|
||||
response = getFirstLine(buffer, n);
|
||||
}
|
||||
else if (tokens[0] == "loolclient")
|
||||
{
|
||||
const auto versionTuple = ParseVersion(tokens[1]);
|
||||
if (std::get<0>(versionTuple) != ProtocolMajorVersionNumber ||
|
||||
std::get<1>(versionTuple) != ProtocolMinorVersionNumber)
|
||||
{
|
||||
const std::string error = "error: cmd=loolclient kind=badversion";
|
||||
_ws.sendFrame(error.c_str(), error.size());
|
||||
break;
|
||||
}
|
||||
|
||||
const auto version = "loolserver " + GetProtocolVersion();
|
||||
_ws.sendFrame(version.c_str(), version.size());
|
||||
}
|
||||
if (response.find("status:") == 0)
|
||||
{
|
||||
parseStatus(response, _type, _numParts, _currentPart, _width, _height);
|
||||
|
@ -203,6 +217,8 @@ private:
|
|||
|
||||
thread.start(output);
|
||||
|
||||
sendTextFrame(ws, "loolclient " + GetProtocolVersion());
|
||||
|
||||
if (document[0] == '/')
|
||||
sendTextFrame(ws, "load " + document);
|
||||
else
|
||||
|
|
|
@ -81,6 +81,20 @@ bool MasterProcessSession::_handleInput(const char *buffer, int length)
|
|||
const std::string firstLine = getFirstLine(buffer, length);
|
||||
StringTokenizer tokens(firstLine, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
|
||||
|
||||
if (tokens[0] == "loolclient")
|
||||
{
|
||||
const auto versionTuple = ParseVersion(tokens[1]);
|
||||
if (std::get<0>(versionTuple) != ProtocolMajorVersionNumber ||
|
||||
std::get<1>(versionTuple) != ProtocolMinorVersionNumber)
|
||||
{
|
||||
sendTextFrame("error: cmd=loolclient kind=badversion");
|
||||
return false;
|
||||
}
|
||||
|
||||
sendTextFrame("loolserver " + GetProtocolVersion());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (haveSeparateProcess())
|
||||
{
|
||||
// Note that this handles both forwarding requests from the client to the child process, and
|
||||
|
|
|
@ -11,6 +11,16 @@ tiles proactively (guessing what the client might need). Etc.
|
|||
client -> server
|
||||
================
|
||||
|
||||
loolclient <major.minor[-patch]>
|
||||
|
||||
Upon connection, a client must announce the version number it supports.
|
||||
Major: an integer that must always match between client and server,
|
||||
otherwise there are no guarantees of any sensible
|
||||
compatibility. This is bumped when API changes.
|
||||
Minor: an integer is more flexible and is at the discretion of either party.
|
||||
Security fixes that do not alter the API would bump the minor version number.
|
||||
Patch: an optional string that is informational.
|
||||
|
||||
canceltiles
|
||||
|
||||
All outstanding tile messages from the client to the server are
|
||||
|
@ -109,6 +119,16 @@ partpagerectangles
|
|||
server -> client
|
||||
================
|
||||
|
||||
loolserver <major.minor[-patch]>
|
||||
|
||||
Upon connection, the server must announce the version number it supports.
|
||||
Major: an integer that must always match between client and server,
|
||||
otherwise there are no guarantees of any sensible
|
||||
compatibility. This is bumped when API changes.
|
||||
Minor: an integer is more flexible and is at the discretion of either party.
|
||||
Security fixes that do not alter the API would bump the minor version number.
|
||||
Patch: an optional string that is informational.
|
||||
|
||||
downloadas: jail=<jail directory> dir=<a tmp dir> name=<name> port=<port>
|
||||
|
||||
The client should then request http://server:port/jail/dir/name in order to download
|
||||
|
|
Loading…
Reference in a new issue