summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKari Oikarinen <kari.oikarinen@qt.io>2016-12-08 16:22:58 +0200
committerKari Oikarinen <kari.oikarinen@qt.io>2016-12-22 13:02:19 +0000
commit2c7380bb4e934b309ee66d8dbc233dc76b4d68a3 (patch)
treea049c8108ac8e4d92bf1bd6a1dc9dc07ee51b1cb
parentb9bef380a60b17d5fb686581bde20819e4492ead (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>
-rw-r--r--qdb/hostmessages.cpp124
-rw-r--r--qdb/hostmessages.h115
-rw-r--r--qdb/qdb.pro1
-rw-r--r--qdb/server/hostservlet.cpp11
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();