diff options
author | Kari Oikarinen <kari.oikarinen@qt.io> | 2016-12-08 16:22:58 +0200 |
---|---|---|
committer | Kari Oikarinen <kari.oikarinen@qt.io> | 2016-12-22 13:02:19 +0000 |
commit | 2c7380bb4e934b309ee66d8dbc233dc76b4d68a3 (patch) | |
tree | a049c8108ac8e4d92bf1bd6a1dc9dc07ee51b1cb /qdb | |
parent | b9bef380a60b17d5fb686581bde20819e4492ead (diff) |
Add version field to JSON messages on the host
This allows proper errors if mismatching versions of client and
hostserver are running.
Change-Id: I4b13e52d6b410cedc8a2a99ae94be77082b113da
Reviewed-by: Samuli Piippo <samuli.piippo@qt.io>
Diffstat (limited to 'qdb')
-rw-r--r-- | qdb/hostmessages.cpp | 124 | ||||
-rw-r--r-- | qdb/hostmessages.h | 115 | ||||
-rw-r--r-- | qdb/qdb.pro | 1 | ||||
-rw-r--r-- | qdb/server/hostservlet.cpp | 11 |
4 files changed, 150 insertions, 101 deletions
diff --git a/qdb/hostmessages.cpp b/qdb/hostmessages.cpp new file mode 100644 index 0000000..9fda389 --- /dev/null +++ b/qdb/hostmessages.cpp @@ -0,0 +1,124 @@ +/****************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Debug Bridge. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ +#include "hostmessages.h" + +const QString responseField = "response"; +const QString requestField = "request"; +const QString versionField = "_version"; + +void setVersionField(QJsonObject &obj) +{ + obj[versionField] = qdbHostMessageVersion; +} + +bool checkHostMessageVersion(const QJsonObject &obj) +{ + return obj[versionField].toInt() == qdbHostMessageVersion; +} + +QByteArray createRequest(const RequestType &type) +{ + QJsonObject obj; + setVersionField(obj); + obj[requestField] = requestTypeString(type); + return QJsonDocument{obj}.toJson(QJsonDocument::Compact).append('\n'); +} + +RequestType requestType(const QJsonObject &obj) +{ + const auto fieldValue = obj[requestField]; + if (fieldValue == requestTypeString(RequestType::Devices)) + return RequestType::Devices; + if (fieldValue == requestTypeString(RequestType::WatchDevices)) + return RequestType::WatchDevices; + if (fieldValue == requestTypeString(RequestType::StopServer)) + return RequestType::StopServer; + + return RequestType::Unknown; +} + +QString requestTypeString(const RequestType &type) +{ + switch (type) { + case RequestType::Devices: + return "devices"; + case RequestType::WatchDevices: + return "watch-devices"; + case RequestType::StopServer: + return "stop-server"; + case RequestType::Unknown: + break; + } + qFatal("Tried to use unknown request type as a value in requestTypeString"); +} + +QJsonObject initializeResponse(const ResponseType &type) +{ + QJsonObject obj; + setVersionField(obj); + obj[responseField] = responseTypeString(type); + return obj; +} + +ResponseType responseType(const QJsonObject &obj) +{ + const auto fieldValue = obj[responseField]; + if (fieldValue == responseTypeString(ResponseType::Devices)) + return ResponseType::Devices; + if (fieldValue == responseTypeString(ResponseType::NewDevice)) + return ResponseType::NewDevice; + if (fieldValue == responseTypeString(ResponseType::DisconnectedDevice)) + return ResponseType::DisconnectedDevice; + if (fieldValue == responseTypeString(ResponseType::Stopping)) + return ResponseType::Stopping; + if (fieldValue == responseTypeString(ResponseType::InvalidRequest)) + return ResponseType::InvalidRequest; + if (fieldValue == responseTypeString(ResponseType::UnsupportedVersion)) + return ResponseType::UnsupportedVersion; + + return ResponseType::Unknown; +} + +QString responseTypeString(const ResponseType &type) +{ + switch (type) { + case ResponseType::Devices: + return "devices"; + case ResponseType::NewDevice: + return "new-device"; + case ResponseType::DisconnectedDevice: + return "disconnected-device"; + case ResponseType::Stopping: + return "stopping"; + case ResponseType::InvalidRequest: + return "invalid-request"; + case ResponseType::UnsupportedVersion: + return "unsupported-version"; + case ResponseType::Unknown: + break; + } + qFatal("Tried to use unknown response type as a value in responseTypeString"); +} + +QByteArray serialiseResponse(const QJsonObject &obj) +{ + return QJsonDocument{obj}.toJson(QJsonDocument::Compact).append('\n'); +} diff --git a/qdb/hostmessages.h b/qdb/hostmessages.h index daf4620..beb6c3e 100644 --- a/qdb/hostmessages.h +++ b/qdb/hostmessages.h @@ -25,122 +25,35 @@ #include <QtCore/qjsondocument.h> #include <QtCore/qjsonobject.h> +const int qdbHostMessageVersion = 1; +bool checkHostMessageVersion(const QJsonObject &obj); + enum class RequestType { + Unknown = 0, Devices, WatchDevices, StopServer, - Unknown }; +QByteArray createRequest(const RequestType &type); +RequestType requestType(const QJsonObject &obj); +QString requestTypeString(const RequestType &type); + enum class ResponseType { + Unknown = 0, Devices, NewDevice, DisconnectedDevice, Stopping, InvalidRequest, - Unknown + UnsupportedVersion, }; -inline -QString responseTypeString(const ResponseType &type) -{ - const QString devicesValue = "devices"; - const QString newDeviceValue = "new-device"; - const QString disconnectedDeviceValue = "disconnected-device"; - const QString stoppingValue = "stopping"; - const QString invalidRequestValue = "invalid-request"; - - switch (type) { - case ResponseType::Devices: - return devicesValue; - case ResponseType::NewDevice: - return newDeviceValue; - case ResponseType::DisconnectedDevice: - return disconnectedDeviceValue; - case ResponseType::Stopping: - return stoppingValue; - case ResponseType::InvalidRequest: - return invalidRequestValue; - case ResponseType::Unknown: - break; - } - qFatal("Tried to use unknown response type as a value in responseTypeString"); -} - -inline -QString requestTypeString(const RequestType &type) -{ - const QString devicesValue = "devices"; - const QString watchDevicesValue = "watch-devices"; - const QString stopServerValue = "stop-server"; - - switch (type) { - case RequestType::Devices: - return devicesValue; - case RequestType::WatchDevices: - return watchDevicesValue; - case RequestType::StopServer: - return stopServerValue; - case RequestType::Unknown: - break; - } - qFatal("Tried to use unknown request type as a value in requestTypeString"); -} - -inline -ResponseType responseType(const QJsonObject &obj) -{ - const auto fieldValue = obj["response"]; - if (fieldValue == responseTypeString(ResponseType::Devices)) - return ResponseType::Devices; - if (fieldValue == responseTypeString(ResponseType::NewDevice)) - return ResponseType::NewDevice; - if (fieldValue == responseTypeString(ResponseType::DisconnectedDevice)) - return ResponseType::DisconnectedDevice; - if (fieldValue == responseTypeString(ResponseType::Stopping)) - return ResponseType::Stopping; - if (fieldValue == responseTypeString(ResponseType::InvalidRequest)) - return ResponseType::InvalidRequest; - - return ResponseType::Unknown; -} - -inline -RequestType requestType(const QJsonObject &obj) -{ - const auto fieldValue = obj["request"]; - if (fieldValue == requestTypeString(RequestType::Devices)) - return RequestType::Devices; - if (fieldValue == requestTypeString(RequestType::WatchDevices)) - return RequestType::WatchDevices; - if (fieldValue == requestTypeString(RequestType::StopServer)) - return RequestType::StopServer; - - return RequestType::Unknown; -} - -inline -QByteArray createRequest(const RequestType &type) -{ - QJsonObject obj; - obj["request"] = requestTypeString(type); - return QJsonDocument{obj}.toJson(QJsonDocument::Compact).append('\n'); -} - -inline -QJsonObject initializeResponse(const ResponseType &type) -{ - QJsonObject obj; - obj["response"] = responseTypeString(type); - return obj; -} - -inline -QByteArray serialiseResponse(const QJsonObject &obj) -{ - return QJsonDocument{obj}.toJson(QJsonDocument::Compact).append('\n'); -} +QJsonObject initializeResponse(const ResponseType &type); +ResponseType responseType(const QJsonObject &obj); +QString responseTypeString(const ResponseType &type); +QByteArray serialiseResponse(const QJsonObject &obj); #endif // HOSTMESSAGES_H diff --git a/qdb/qdb.pro b/qdb/qdb.pro index 20ba110..efbc9a5 100644 --- a/qdb/qdb.pro +++ b/qdb/qdb.pro @@ -40,6 +40,7 @@ HEADERS += \ SOURCES += \ client/client.cpp \ + hostmessages.cpp \ main.cpp \ server/connection.cpp \ server/deviceinformationfetcher.cpp \ diff --git a/qdb/server/hostservlet.cpp b/qdb/server/hostservlet.cpp index ac9f86e..d173919 100644 --- a/qdb/server/hostservlet.cpp +++ b/qdb/server/hostservlet.cpp @@ -80,6 +80,17 @@ void HostServlet::handleRequest() const auto request = QJsonDocument::fromJson(requestBytes); const auto type = requestType(request.object()); + // Skip version check for requests to stop the server, to allow mismatching + // client to still stop the server + if (!checkHostMessageVersion(request.object()) && type != RequestType::StopServer) { + qCWarning(hostServerC) << "Request from client" << m_id << "was of an unsupported version"; + QJsonObject response = initializeResponse(ResponseType::UnsupportedVersion); + response["supported-version"] = qdbHostMessageVersion; + m_socket->write(serialiseResponse(response)); + close(); + return; + } + switch (type) { case RequestType::Devices: replyDevices(); |