Prepare client library for tunnel proxy
This commit is contained in:
parent
56d32bed2b
commit
f0cdb2706b
Binary file not shown.
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 104 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 22 KiB |
@ -1,33 +1,39 @@
|
||||
title Remote tunnel proxy
|
||||
|
||||
nymea->proxy: RegisterProxyTunnelServer(uuid, name)
|
||||
nymea->proxy: TunnelProxy.RegisterServer(serverUuid, serverName)
|
||||
|
||||
note over proxy: Register the server using the uuid
|
||||
|
||||
nymea<-proxy: Success
|
||||
nymea<-proxy: TunnelProxyErrorNoError
|
||||
|
||||
note over nymea, proxy: Protocol from now on SLIP\nThe proxy is client 0x0000
|
||||
|
||||
note over nymea, proxy: SLIP encoded data: 2 Bytes address + data
|
||||
|
||||
proxy<-client: ConnectProxyTunnelClient(uuid, name, serverUuid)
|
||||
proxy<-client: TunnelProxy.RegisterClient(clientUuid, clientName, serverUuid)
|
||||
|
||||
note over proxy: Search server using uuid
|
||||
note over proxy: Search server with given uuid
|
||||
|
||||
note over proxy: Server: Assign address 0x0001 for this client socket
|
||||
note over proxy: Server: Assign address for this client socket (0x0001)
|
||||
|
||||
proxy->nymea: SLIP:0x0000: ProxyTunnelClientConnected (address: 0x0001)
|
||||
proxy->nymea: SLIP:0x0000: ProxyTunnel.ClientConnected (address: 0x0001)
|
||||
|
||||
proxy<-nymea: SLIP:0x0000: AckProxyTunnelClient (address: 0x0001)
|
||||
proxy<-nymea: SLIP:0x0000: ProxyTunnel.AcceptClient (address: 0x0001)
|
||||
|
||||
proxy->client: ProxyTunnelEstablished(uuid, name, serverUuid)
|
||||
proxy->nymea: TunnelProxyErrorNoError
|
||||
|
||||
note over proxy, client: Protocol from now on SLIP encoded\nThe proxy is client 0x0000\nThe connected server is 0xFFFF
|
||||
proxy->client: ProxyTunnel.ConfirmClient(uuid, name, serverUuid)
|
||||
|
||||
note over proxy, client: SLIP encoded data: 2 Bytes address + data
|
||||
note over client: Connected\nAny incomming and outgoing data will\nbe from the connected nymea instance\nuntil disconnected.
|
||||
|
||||
note over nymea, client: Connected: The client can now communicate with nymea directly.
|
||||
note over nymea, client: Connected: The client can now communicate with nymea directly.\nThe proxy will not interpret any data from the client, and from the server only\nthe transmission frame (SLIP + 2 bytes of address)
|
||||
|
||||
note over nymea, client: nymea sends SLIP encoded data with address 0x0001 -> client
|
||||
|
||||
note over nymea, client: client sends SLIP endcoded data with address 0xFFFF -> nymea
|
||||
|
||||
proxy<-client: "data"
|
||||
|
||||
nymea<-proxy: SLIP:0x0001 "data"
|
||||
|
||||
nymea->proxy: SLIP:0x0001 "data"
|
||||
|
||||
proxy->client: "data"
|
||||
|
||||
@ -294,12 +294,34 @@ void Engine::clean()
|
||||
m_proxyServer = nullptr;
|
||||
}
|
||||
|
||||
if (m_tunnelProxyServer) {
|
||||
m_tunnelProxyServer->stopServer();
|
||||
delete m_tunnelProxyServer;
|
||||
m_tunnelProxyServer = nullptr;
|
||||
}
|
||||
|
||||
if (m_tcpSocketServerProxy) {
|
||||
delete m_tcpSocketServerProxy;
|
||||
m_tcpSocketServerProxy = nullptr;
|
||||
}
|
||||
|
||||
if (m_webSocketServerProxy) {
|
||||
delete m_webSocketServerProxy;
|
||||
m_webSocketServerProxy = nullptr;
|
||||
}
|
||||
|
||||
if (m_tcpSocketServerTunnelProxy) {
|
||||
delete m_tcpSocketServerTunnelProxy;
|
||||
m_tcpSocketServerTunnelProxy = nullptr;
|
||||
}
|
||||
|
||||
if (m_webSocketServerTunnelProxy) {
|
||||
delete m_webSocketServerTunnelProxy;
|
||||
m_webSocketServerTunnelProxy = nullptr;
|
||||
}
|
||||
|
||||
if (m_configuration) {
|
||||
delete m_configuration;
|
||||
m_configuration = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +83,6 @@ public:
|
||||
MonitorServer *monitorServer() const;
|
||||
LogEngine *logEngine() const;
|
||||
|
||||
|
||||
private:
|
||||
explicit Engine(QObject *parent = nullptr);
|
||||
~Engine();
|
||||
|
||||
@ -40,6 +40,7 @@ TunnelProxyHandler::TunnelProxyHandler(QObject *parent) : JsonHandler(parent)
|
||||
// Methods
|
||||
QVariantMap params; QVariantMap returns;
|
||||
|
||||
// Server
|
||||
params.clear(); returns.clear();
|
||||
setDescription("RegisterServer", "Register a new TunnelProxy server on this instance. Multiple TunnelProxy clients can be connected to the registered server on success.");
|
||||
params.insert("serverName", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
@ -48,6 +49,7 @@ TunnelProxyHandler::TunnelProxyHandler(QObject *parent) : JsonHandler(parent)
|
||||
returns.insert("tunnelProxyError", JsonTypes::tunnelProxyErrorRef());
|
||||
setReturns("RegisterServer", returns);
|
||||
|
||||
// Client
|
||||
params.clear(); returns.clear();
|
||||
setDescription("RegisterClient", "Register a new TunnelProxy client on TunnelProxy server with the given serverUuid..");
|
||||
params.insert("clientName", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
@ -58,6 +60,8 @@ TunnelProxyHandler::TunnelProxyHandler(QObject *parent) : JsonHandler(parent)
|
||||
setReturns("RegisterClient", returns);
|
||||
|
||||
// Notifications
|
||||
|
||||
// Server
|
||||
params.clear(); returns.clear();
|
||||
setDescription("ClientConnected", "Emitted whenever a new client has been connected to a registered server. "
|
||||
"Only tunnel proxy clients registered as server will receive this notification.");
|
||||
|
||||
@ -247,6 +247,9 @@ void JsonRpcServer::processDataPackage(TransportClient *transportClient, const Q
|
||||
reply->setClientId(transportClient->clientId());
|
||||
reply->setCommandId(commandId);
|
||||
sendResponse(transportClient, commandId, reply->data());
|
||||
|
||||
// TODO: check if the client should be disconnected after this response
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,6 +65,7 @@ void TcpSocketServer::killClientConnection(const QUuid &clientId, const QString
|
||||
return;
|
||||
|
||||
qCWarning(dcTcpSocketServer()) << "Killing client connection" << clientId.toString() << "Reason:" << killReason;
|
||||
client->flush();
|
||||
client->close();
|
||||
}
|
||||
|
||||
@ -139,7 +140,6 @@ SslServer::SslServer(bool sslEnabled, const QSslConfiguration &config, QObject *
|
||||
QTcpServer(parent),
|
||||
m_sslEnabled(sslEnabled),
|
||||
m_config(config)
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@ -77,6 +77,7 @@ void WebSocketServer::killClientConnection(const QUuid &clientId, const QString
|
||||
return;
|
||||
|
||||
qCWarning(dcWebSocketServer()) << "Killing client connection" << clientId.toString() << "Reason:" << killReason;
|
||||
client->flush();
|
||||
client->close(QWebSocketProtocol::CloseCodeBadOperation, killReason);
|
||||
}
|
||||
|
||||
|
||||
@ -23,22 +23,36 @@ void TunnelProxyClient::setType(Type type)
|
||||
emit typeChanged(m_type);
|
||||
}
|
||||
|
||||
bool TunnelProxyClient::slipEnabled() const
|
||||
{
|
||||
return m_slipEnabled;
|
||||
}
|
||||
|
||||
void TunnelProxyClient::setSlipEnabled(bool slipEnabled)
|
||||
{
|
||||
m_slipEnabled = slipEnabled;
|
||||
}
|
||||
|
||||
QList<QByteArray> TunnelProxyClient::processData(const QByteArray &data)
|
||||
{
|
||||
// TODO: unescape if this data is for the json handler
|
||||
QList<QByteArray> packages;
|
||||
|
||||
// Handle packet fragmentation
|
||||
m_dataBuffers.append(data);
|
||||
int splitIndex = m_dataBuffers.indexOf("}\n{");
|
||||
while (splitIndex > -1) {
|
||||
packages.append(m_dataBuffers.left(splitIndex + 1));
|
||||
m_dataBuffers = m_dataBuffers.right(m_dataBuffers.length() - splitIndex - 2);
|
||||
splitIndex = m_dataBuffers.indexOf("}\n{");
|
||||
}
|
||||
if (m_dataBuffers.trimmed().endsWith("}")) {
|
||||
packages.append(m_dataBuffers);
|
||||
m_dataBuffers.clear();
|
||||
if (m_slipEnabled) {
|
||||
|
||||
} else {
|
||||
// Handle json packet fragmentation
|
||||
m_dataBuffers.append(data);
|
||||
int splitIndex = m_dataBuffers.indexOf("}\n{");
|
||||
while (splitIndex > -1) {
|
||||
packages.append(m_dataBuffers.left(splitIndex + 1));
|
||||
m_dataBuffers = m_dataBuffers.right(m_dataBuffers.length() - splitIndex - 2);
|
||||
splitIndex = m_dataBuffers.indexOf("}\n{");
|
||||
}
|
||||
if (m_dataBuffers.trimmed().endsWith("}")) {
|
||||
packages.append(m_dataBuffers);
|
||||
m_dataBuffers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
return packages;
|
||||
@ -47,16 +61,12 @@ QList<QByteArray> TunnelProxyClient::processData(const QByteArray &data)
|
||||
QDebug operator<<(QDebug debug, TunnelProxyClient *tunnelProxyClient)
|
||||
{
|
||||
debug.nospace() << "TunnelProxyClient(";
|
||||
if (!tunnelProxyClient->name().isEmpty()) {
|
||||
debug.nospace() << tunnelProxyClient->name() << ", ";
|
||||
}
|
||||
|
||||
debug.nospace() << tunnelProxyClient->interface()->serverName();
|
||||
debug.nospace() << ", " << tunnelProxyClient->clientId().toString();
|
||||
debug.nospace() << ", " << tunnelProxyClient->peerAddress().toString();
|
||||
debug.nospace() << ", " << tunnelProxyClient->creationTimeString() << ")";
|
||||
debug.nospace() << tunnelProxyClient->name() << ", ";
|
||||
debug.nospace() << tunnelProxyClient->interface()->serverName()<< ", ";
|
||||
debug.nospace() << tunnelProxyClient->clientId().toString()<< ", ";
|
||||
debug.nospace() << tunnelProxyClient->peerAddress().toString() << ", ";
|
||||
debug.nospace() << tunnelProxyClient->creationTimeString() << ")";
|
||||
return debug.space();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,6 +23,9 @@ public:
|
||||
Type type() const;
|
||||
void setType(Type type);
|
||||
|
||||
bool slipEnabled() const;
|
||||
void setSlipEnabled(bool slipEnabled);
|
||||
|
||||
// Json server methods
|
||||
QList<QByteArray> processData(const QByteArray &data) override;
|
||||
|
||||
@ -31,6 +34,7 @@ signals:
|
||||
|
||||
private:
|
||||
Type m_type = TypeNone;
|
||||
bool m_slipEnabled = false;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -30,9 +30,10 @@
|
||||
|
||||
namespace remoteproxy {
|
||||
|
||||
TunnelProxyClientConnection::TunnelProxyClientConnection(TransportClient *transportClient, const QUuid &clientUuid, const QString &clientName, const QUuid &serverUuid, QObject *parent) :
|
||||
TunnelProxyClientConnection::TunnelProxyClientConnection(TransportClient *transportClient, TunnelProxyServerConnection *serverConnection, const QUuid &clientUuid, const QString &clientName, const QUuid &serverUuid, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_transportClient(transportClient),
|
||||
m_serverConnection(serverConnection),
|
||||
m_clientUuid(clientUuid),
|
||||
m_clientName(clientName),
|
||||
m_serverUuid(serverUuid)
|
||||
@ -45,6 +46,11 @@ TransportClient *TunnelProxyClientConnection::transportClient() const
|
||||
return m_transportClient;
|
||||
}
|
||||
|
||||
TunnelProxyServerConnection *TunnelProxyClientConnection::serverConnection() const
|
||||
{
|
||||
return m_serverConnection;
|
||||
}
|
||||
|
||||
QUuid TunnelProxyClientConnection::clientUuid() const
|
||||
{
|
||||
return m_clientUuid;
|
||||
@ -60,4 +66,13 @@ QUuid TunnelProxyClientConnection::serverUuid() const
|
||||
return m_serverUuid;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, TunnelProxyClientConnection *clientConnection)
|
||||
{
|
||||
debug.nospace() << "TunnelProxyClientConnection(";
|
||||
debug.nospace() << clientConnection->clientName() << ", ";
|
||||
debug.nospace() << clientConnection->clientUuid().toString() << ", ";
|
||||
debug.nospace() << clientConnection->transportClient() << ")";
|
||||
return debug.space();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -30,27 +30,30 @@
|
||||
|
||||
#include <QUuid>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace remoteproxy {
|
||||
|
||||
class TransportClient;
|
||||
class TunnelProxyServerConnection;
|
||||
|
||||
class TunnelProxyClientConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TunnelProxyClientConnection(TransportClient *transportClient, const QUuid &clientUuid, const QString &clientName, const QUuid &serverUuid, QObject *parent = nullptr);
|
||||
explicit TunnelProxyClientConnection(TransportClient *transportClient, TunnelProxyServerConnection *serverConnection, const QUuid &clientUuid, const QString &clientName, const QUuid &serverUuid, QObject *parent = nullptr);
|
||||
|
||||
TransportClient *transportClient() const;
|
||||
|
||||
TunnelProxyServerConnection *serverConnection() const;
|
||||
|
||||
QUuid clientUuid() const;
|
||||
QString clientName() const;
|
||||
QUuid serverUuid() const;
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
TransportClient *m_transportClient = nullptr;
|
||||
TunnelProxyServerConnection *m_serverConnection = nullptr;
|
||||
|
||||
QUuid m_clientUuid;
|
||||
QString m_clientName;
|
||||
@ -58,6 +61,8 @@ private:
|
||||
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, TunnelProxyClientConnection *clientConnection);
|
||||
|
||||
}
|
||||
|
||||
#endif // TUNNELPROXYCLIENTCONNECTION_H
|
||||
|
||||
@ -99,6 +99,9 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerServer(const QUui
|
||||
tunnelProxyClient->setUuid(serverUuid);
|
||||
tunnelProxyClient->setName(serverName);
|
||||
|
||||
// Enable SLIP from now on
|
||||
// tunnelProxyClient->setSlipEnabled(true);
|
||||
|
||||
TunnelProxyServerConnection *serverConnection = new TunnelProxyServerConnection(tunnelProxyClient, serverUuid, serverName, this);
|
||||
m_tunnelProxyServerConnections.insert(serverUuid, serverConnection);
|
||||
|
||||
@ -121,6 +124,11 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerClient(const QUui
|
||||
return TunnelProxyServer::TunnelProxyErrorAlreadyRegistered;
|
||||
}
|
||||
|
||||
if (m_tunnelProxyClientConnections.contains(clientUuid)) {
|
||||
qCWarning(dcTunnelProxyServer()) << "There is a client already registered with client uuid" << clientUuid.toString();
|
||||
return TunnelProxyServer::TunnelProxyErrorAlreadyRegistered;
|
||||
}
|
||||
|
||||
// Get the desired server connection
|
||||
TunnelProxyServerConnection *serverConnection = m_tunnelProxyServerConnections.value(serverUuid);
|
||||
if (!serverConnection) {
|
||||
@ -128,20 +136,18 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerClient(const QUui
|
||||
return TunnelProxyServer::TunnelProxyErrorServerNotFound;
|
||||
}
|
||||
|
||||
if (m_tunnelProxyClientConnections.contains(clientUuid)) {
|
||||
qCWarning(dcTunnelProxyServer()) << "There is a client already registered with client uuid" << clientUuid.toString();
|
||||
return TunnelProxyServer::TunnelProxyErrorAlreadyRegistered;
|
||||
}
|
||||
|
||||
// Not registered yet, we have a connected server for the requested server uuid
|
||||
tunnelProxyClient->setType(TunnelProxyClient::TypeClient);
|
||||
tunnelProxyClient->setUuid(clientUuid);
|
||||
tunnelProxyClient->setName(clientName);
|
||||
|
||||
TunnelProxyClientConnection *clientConnection = new TunnelProxyClientConnection(tunnelProxyClient, clientUuid, clientName, serverUuid);
|
||||
TunnelProxyClientConnection *clientConnection = new TunnelProxyClientConnection(tunnelProxyClient, serverConnection, clientUuid, clientName, serverUuid);
|
||||
m_tunnelProxyClientConnections.insert(clientUuid, clientConnection);
|
||||
|
||||
// TODO: register on the server and wait for te aprovement from the server
|
||||
qCDebug(dcTunnelProxyServer()) << "Register client" << clientConnection << "-->" << serverConnection;
|
||||
serverConnection->registerClientConnection(clientConnection);
|
||||
|
||||
// TODO: wait for te aprovement from the server
|
||||
|
||||
return TunnelProxyServer::TunnelProxyErrorNoError;
|
||||
}
|
||||
@ -195,6 +201,8 @@ void TunnelProxyServer::onClientDisconnected(const QUuid &clientId)
|
||||
if (!serverConnection) {
|
||||
qCWarning(dcTunnelProxyServer()) << "Could not find server connection for disconnected tunnel proxy client claiming to be a server.";
|
||||
} else {
|
||||
|
||||
|
||||
// TODO: kill all related clients
|
||||
|
||||
serverConnection->deleteLater();
|
||||
@ -203,11 +211,13 @@ void TunnelProxyServer::onClientDisconnected(const QUuid &clientId)
|
||||
|
||||
if (tunnelProxyClient->type() == TunnelProxyClient::TypeClient) {
|
||||
TunnelProxyClientConnection *clientConnection = m_tunnelProxyClientConnections.take(tunnelProxyClient->uuid());
|
||||
|
||||
if (!clientConnection) {
|
||||
qCWarning(dcTunnelProxyServer()) << "Could not find client connection for disconnected tunnel proxy client claiming to be a client.";
|
||||
} else {
|
||||
// TODO: remove from server
|
||||
if (clientConnection->serverConnection()) {
|
||||
clientConnection->serverConnection()->unregisterClientConnection(clientConnection);
|
||||
// TODO: Send client disconnected to the server
|
||||
}
|
||||
|
||||
clientConnection->deleteLater();
|
||||
}
|
||||
@ -229,10 +239,23 @@ void TunnelProxyServer::onClientDataAvailable(const QUuid &clientId, const QByte
|
||||
}
|
||||
|
||||
qCDebug(dcTunnelProxyServerTraffic()) << "Client data available" << tunnelProxyClient << qUtf8Printable(data);
|
||||
if (tunnelProxyClient->type() == TunnelProxyClient::TypeClient) {
|
||||
// Send the data to the server using slip + frame
|
||||
|
||||
// TODO: verify if encoded and for whom this data is... 0x0000 is for the json rpc handler...
|
||||
|
||||
m_jsonRpcServer->processData(tunnelProxyClient, data);
|
||||
} else if (tunnelProxyClient->type() == TunnelProxyClient::TypeServer) {
|
||||
if (tunnelProxyClient->slipEnabled()) {
|
||||
|
||||
} else {
|
||||
m_jsonRpcServer->processData(tunnelProxyClient, data);
|
||||
}
|
||||
// Unpack SLIP data, get address, pipe to client or give it to the json rpc server if address 0x0000
|
||||
|
||||
} else {
|
||||
// Not registered yet or doing other stuff...let the JSON RPC handle this data
|
||||
m_jsonRpcServer->processData(tunnelProxyClient, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
#include "tunnelproxyserverconnection.h"
|
||||
#include "server/transportclient.h"
|
||||
#include "tunnelproxyclientconnection.h"
|
||||
|
||||
namespace remoteproxy {
|
||||
|
||||
@ -54,4 +55,23 @@ QString TunnelProxyServerConnection::serverName() const
|
||||
return m_serverName;
|
||||
}
|
||||
|
||||
void TunnelProxyServerConnection::registerClientConnection(TunnelProxyClientConnection *clientConnection)
|
||||
{
|
||||
m_clientConnections.insert(clientConnection->clientUuid(), clientConnection);
|
||||
}
|
||||
|
||||
void TunnelProxyServerConnection::unregisterClientConnection(TunnelProxyClientConnection *clientConnection)
|
||||
{
|
||||
m_clientConnections.remove(clientConnection->clientUuid());
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, TunnelProxyServerConnection *serverConnection)
|
||||
{
|
||||
debug.nospace() << "TunnelProxyServerConnection(";
|
||||
debug.nospace() << serverConnection->serverName() << ", ";
|
||||
debug.nospace() << serverConnection->serverUuid().toString() << ", ";
|
||||
debug.nospace() << serverConnection->transportClient() << ")";
|
||||
return debug.space();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -30,10 +30,12 @@
|
||||
|
||||
#include <QUuid>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace remoteproxy {
|
||||
|
||||
class TransportClient;
|
||||
class TunnelProxyClientConnection;
|
||||
|
||||
class TunnelProxyServerConnection : public QObject
|
||||
{
|
||||
@ -46,17 +48,22 @@ public:
|
||||
QUuid serverUuid() const;
|
||||
QString serverName() const;
|
||||
|
||||
|
||||
void registerClientConnection(TunnelProxyClientConnection *clientConnection);
|
||||
void unregisterClientConnection(TunnelProxyClientConnection *clientConnection);
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
TransportClient *m_transportClient = nullptr;
|
||||
|
||||
QUuid m_serverUuid;
|
||||
QString m_serverName;
|
||||
|
||||
QHash<QUuid, TunnelProxyClientConnection *> m_clientConnections;
|
||||
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, TunnelProxyServerConnection *serverConnection);
|
||||
|
||||
}
|
||||
|
||||
#endif // TUNNELPROXYSERVERCONNECTION_H
|
||||
|
||||
@ -1,18 +1,24 @@
|
||||
INCLUDEPATH += $${PWD}
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$${PWD}/tcpsocketconnection.h \
|
||||
$${PWD}/proxyjsonrpcclient.h \
|
||||
$${PWD}/jsonreply.h \
|
||||
$${PWD}/remoteproxyconnection.h \
|
||||
$${PWD}/proxyconnection.h \
|
||||
$${PWD}/websocketconnection.h
|
||||
$$PWD/tunnelproxy/tunnelproxyjsonrpcclient.h \
|
||||
$$PWD/tunnelproxy/tunnelproxysocket.h \
|
||||
$$PWD/tunnelproxy/tunnelproxyserver.h \
|
||||
$$PWD/tcpsocketconnection.h \
|
||||
$$PWD/proxyjsonrpcclient.h \
|
||||
$$PWD/jsonreply.h \
|
||||
$$PWD/remoteproxyconnection.h \
|
||||
$$PWD/proxyconnection.h \
|
||||
$$PWD/websocketconnection.h
|
||||
|
||||
SOURCES += \
|
||||
$${PWD}/tcpsocketconnection.cpp \
|
||||
$${PWD}/proxyjsonrpcclient.cpp \
|
||||
$${PWD}/jsonreply.cpp \
|
||||
$${PWD}/remoteproxyconnection.cpp \
|
||||
$${PWD}/proxyconnection.cpp \
|
||||
$${PWD}/websocketconnection.cpp
|
||||
$$PWD/tunnelproxy/tunnelproxyjsonrpcclient.cpp \
|
||||
$$PWD/tunnelproxy/tunnelproxysocket.cpp \
|
||||
$$PWD/tunnelproxy/tunnelproxyserver.cpp \
|
||||
$$PWD/tcpsocketconnection.cpp \
|
||||
$$PWD/proxyjsonrpcclient.cpp \
|
||||
$$PWD/jsonreply.cpp \
|
||||
$$PWD/remoteproxyconnection.cpp \
|
||||
$$PWD/proxyconnection.cpp \
|
||||
$$PWD/websocketconnection.cpp
|
||||
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "tunnelproxyjsonrpcclient.h"
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
TunnelProxyJsonRpcClient::TunnelProxyJsonRpcClient(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef TUNNELPROXYJSONRPCCLIENT_H
|
||||
#define TUNNELPROXYJSONRPCCLIENT_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
class TunnelProxyJsonRpcClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TunnelProxyJsonRpcClient(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TUNNELPROXYJSONRPCCLIENT_H
|
||||
84
libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.cpp
Normal file
84
libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "tunnelproxyserver.h"
|
||||
#include "proxyconnection.h"
|
||||
#include "tcpsocketconnection.h"
|
||||
#include "websocketconnection.h"
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
TunnelProxyServer::TunnelProxyServer(const QUuid &serverUuid, const QString &serverName, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_serverUuid(serverUuid),
|
||||
m_serverName(serverName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TunnelProxyServer::TunnelProxyServer(const QUuid &serverUuid, const QString &serverName, ConnectionType connectionType, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_serverUuid(serverUuid),
|
||||
m_serverName(serverName),
|
||||
m_connectionType(connectionType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TunnelProxyServer::~TunnelProxyServer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool TunnelProxyServer::running() const
|
||||
{
|
||||
return m_running;
|
||||
}
|
||||
|
||||
void TunnelProxyServer::ignoreSslErrors()
|
||||
{
|
||||
m_connection->ignoreSslErrors();
|
||||
|
||||
}
|
||||
|
||||
void TunnelProxyServer::ignoreSslErrors(const QList<QSslError> &errors)
|
||||
{
|
||||
m_connection->ignoreSslErrors(errors);
|
||||
}
|
||||
|
||||
void remoteproxyclient::TunnelProxyServer::startServer(const QUrl &serverUrl)
|
||||
{
|
||||
// Register as server to the remote proxy
|
||||
m_serverUrl = serverUrl;
|
||||
}
|
||||
|
||||
void remoteproxyclient::TunnelProxyServer::stopServer()
|
||||
{
|
||||
// Close the server connection and all related sockets
|
||||
}
|
||||
|
||||
}
|
||||
90
libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.h
Normal file
90
libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef TUNNELPROXYSERVER_H
|
||||
#define TUNNELPROXYSERVER_H
|
||||
|
||||
#include <QUuid>
|
||||
#include <QObject>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyTunnelProxyServer)
|
||||
|
||||
#include "proxyconnection.h"
|
||||
#include "tunnelproxysocket.h"
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
class ProxyConnection;
|
||||
class TunnelProxyJsonRpcClient;
|
||||
|
||||
class TunnelProxyServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ConnectionType {
|
||||
ConnectionTypeWebSocket,
|
||||
ConnectionTypeTcpSocket
|
||||
};
|
||||
Q_ENUM(ConnectionType)
|
||||
|
||||
explicit TunnelProxyServer(const QUuid &serverUuid, const QString &serverName, QObject *parent = nullptr);
|
||||
explicit TunnelProxyServer(const QUuid &serverUuid, const QString &serverName, ConnectionType connectionType, QObject *parent = nullptr);
|
||||
~TunnelProxyServer();
|
||||
|
||||
bool running() const;
|
||||
|
||||
QAbstractSocket::SocketError error() const;
|
||||
|
||||
void ignoreSslErrors();
|
||||
void ignoreSslErrors(const QList<QSslError> &errors);
|
||||
|
||||
public slots:
|
||||
void startServer(const QUrl &serverUrl);
|
||||
void stopServer();
|
||||
|
||||
signals:
|
||||
void runningChanged(bool running);
|
||||
void sslErrors(const QList<QSslError> &errors);
|
||||
|
||||
private:
|
||||
QUuid m_serverUuid;
|
||||
QString m_serverName;
|
||||
ConnectionType m_connectionType = ConnectionTypeTcpSocket;
|
||||
|
||||
bool m_running = false;
|
||||
QUrl m_serverUrl;
|
||||
QAbstractSocket::SocketError m_error = QAbstractSocket::UnknownSocketError;
|
||||
|
||||
ProxyConnection *m_connection = nullptr;
|
||||
TunnelProxyJsonRpcClient *m_jsonClient = nullptr;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TUNNELPROXYSERVER_H
|
||||
37
libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.cpp
Normal file
37
libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "tunnelproxysocket.h"
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
TunnelProxySocket::TunnelProxySocket(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
47
libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.h
Normal file
47
libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef TUNNELPROXYSOCKET_H
|
||||
#define TUNNELPROXYSOCKET_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
class TunnelProxySocket : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TunnelProxySocket(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TUNNELPROXYSOCKET_H
|
||||
@ -4,7 +4,7 @@ QT -= gui
|
||||
# Define versions
|
||||
SERVER_NAME=nymea-remoteproxy
|
||||
API_VERSION_MAJOR=0
|
||||
API_VERSION_MINOR=3
|
||||
API_VERSION_MINOR=4
|
||||
SERVER_VERSION=0.2.0
|
||||
|
||||
DEFINES += SERVER_NAME_STRING=\\\"$${SERVER_NAME}\\\" \
|
||||
|
||||
@ -45,12 +45,24 @@ RemoteProxyTestsProxy::RemoteProxyTestsProxy(QObject *parent) :
|
||||
|
||||
void RemoteProxyTestsProxy::startStopServer()
|
||||
{
|
||||
resetDebugCategories();
|
||||
addDebugCategory("ProxyServer.debug=true");
|
||||
addDebugCategory("Engine.debug=true");
|
||||
addDebugCategory("JsonRpc.debug=true");
|
||||
addDebugCategory("TcpSocketServer.debug=true");
|
||||
addDebugCategory("WebSocketServer.debug=true");
|
||||
|
||||
startServer();
|
||||
stopServer();
|
||||
|
||||
resetDebugCategories();
|
||||
}
|
||||
|
||||
void RemoteProxyTestsProxy::dummyAuthenticator()
|
||||
{
|
||||
resetDebugCategories();
|
||||
addDebugCategory("ProxyServer.debug=true");
|
||||
|
||||
cleanUpEngine();
|
||||
|
||||
m_configuration = new ProxyConfiguration(this);
|
||||
@ -411,7 +423,7 @@ void RemoteProxyTestsProxy::getHello()
|
||||
|
||||
// WebSocket
|
||||
response = invokeWebSocketProxyApiCall("RemoteProxy.Hello").toMap();
|
||||
//qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented));
|
||||
qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented));
|
||||
|
||||
// Verify data
|
||||
QVERIFY(!response.isEmpty());
|
||||
@ -423,7 +435,7 @@ void RemoteProxyTestsProxy::getHello()
|
||||
// TCP
|
||||
response.clear();
|
||||
response = invokeTcpSocketProxyApiCall("RemoteProxy.Hello").toMap();
|
||||
//qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented));
|
||||
qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented));
|
||||
|
||||
// Verify data
|
||||
QVERIFY(!response.isEmpty());
|
||||
|
||||
@ -122,10 +122,9 @@ void RemoteProxyTestsTunnelProxy::getHello()
|
||||
{
|
||||
// Start the server
|
||||
startServer();
|
||||
QVariantMap response;
|
||||
|
||||
// WebSocket
|
||||
response = invokeWebSocketTunnelProxyApiCall("RemoteProxy.Hello").toMap();
|
||||
QVariantMap response = invokeWebSocketTunnelProxyApiCall("RemoteProxy.Hello").toMap();
|
||||
qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented));
|
||||
|
||||
// Verify data
|
||||
@ -147,7 +146,6 @@ void RemoteProxyTestsTunnelProxy::getHello()
|
||||
QCOMPARE(response.value("params").toMap().value("version").toString(), QString(SERVER_VERSION_STRING));
|
||||
QCOMPARE(response.value("params").toMap().value("apiVersion").toString(), QString(API_VERSION_STRING));
|
||||
|
||||
|
||||
// Clean up
|
||||
stopServer();
|
||||
}
|
||||
@ -250,6 +248,88 @@ void RemoteProxyTestsTunnelProxy::registerServer()
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTestsTunnelProxy::registerClient_data()
|
||||
{
|
||||
QTest::addColumn<QString>("name");
|
||||
QTest::addColumn<QString>("uuid");
|
||||
QTest::addColumn<TunnelProxyServer::TunnelProxyError>("expectedError");
|
||||
QTest::addColumn<bool>("serverExists");
|
||||
QTest::addColumn<QString>("serverUuid");
|
||||
QTest::addColumn<TunnelProxyServer::TunnelProxyError>("expectedServerError");
|
||||
|
||||
QTest::newRow("valid client: valid server") << "Friendly client" << QUuid::createUuid().toString() << TunnelProxyServer::TunnelProxyErrorNoError << true << QUuid::createUuid().toString() << TunnelProxyServer::TunnelProxyErrorNoError;
|
||||
QTest::newRow("valid client: no server") << "Friendly client" << QUuid::createUuid().toString() << TunnelProxyServer::TunnelProxyErrorServerNotFound << false << QUuid::createUuid().toString() << TunnelProxyServer::TunnelProxyErrorNoError;
|
||||
QTest::newRow("valid client: invalid server uuid") << "Friendly client" << QUuid::createUuid().toString() << TunnelProxyServer::TunnelProxyErrorInvalidUuid << true << QUuid().toString() << TunnelProxyServer::TunnelProxyErrorInvalidUuid;
|
||||
QTest::newRow("invalid client uuid: valid server uuid") << "Friendly client" << QUuid().toString() << TunnelProxyServer::TunnelProxyErrorInvalidUuid << true << QUuid::createUuid().toString() << TunnelProxyServer::TunnelProxyErrorNoError;
|
||||
QTest::newRow("invalid client uuid: invalid server uuid") << "Friendly client" << "hello again" << TunnelProxyServer::TunnelProxyErrorInvalidUuid << true << "it's me" << TunnelProxyServer::TunnelProxyErrorInvalidUuid;
|
||||
}
|
||||
|
||||
void RemoteProxyTestsTunnelProxy::registerClient()
|
||||
{
|
||||
QFETCH(QString, name);
|
||||
QFETCH(QString, uuid);
|
||||
QFETCH(TunnelProxyServer::TunnelProxyError, expectedError);
|
||||
QFETCH(bool, serverExists);
|
||||
QFETCH(QString, serverUuid);
|
||||
QFETCH(TunnelProxyServer::TunnelProxyError, expectedServerError);
|
||||
|
||||
// Start the server
|
||||
startServer();
|
||||
|
||||
resetDebugCategories();
|
||||
addDebugCategory("TunnelProxyServer.debug=true");
|
||||
|
||||
QSslSocket *socket = nullptr;
|
||||
if (serverExists) {
|
||||
QVariantMap serverParams;
|
||||
serverParams.insert("serverName", "dummy server");
|
||||
serverParams.insert("serverUuid", serverUuid);
|
||||
|
||||
// TCP socket
|
||||
QPair<QVariant, QSslSocket *> result = invokeTcpSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterServer", serverParams);
|
||||
QVariantMap response = result.first.toMap();
|
||||
socket = result.second;
|
||||
|
||||
QVERIFY(!response.isEmpty());
|
||||
QVERIFY(response.value("status").toString() == "success");
|
||||
QVERIFY(response.value("params").toMap().contains("tunnelProxyError"));
|
||||
verifyTunnelProxyError(response, expectedServerError);
|
||||
}
|
||||
|
||||
// Register a new client
|
||||
QVariantMap params;
|
||||
params.insert("clientName", name);
|
||||
params.insert("clientUuid", uuid);
|
||||
params.insert("serverUuid", serverUuid);
|
||||
|
||||
// Websocket
|
||||
QVariantMap response = invokeWebSocketTunnelProxyApiCall("TunnelProxy.RegisterClient", params).toMap();
|
||||
QVERIFY(!response.isEmpty());
|
||||
QVERIFY(response.value("status").toString() == "success");
|
||||
QVERIFY(response.value("params").toMap().contains("tunnelProxyError"));
|
||||
verifyTunnelProxyError(response, expectedError);
|
||||
|
||||
QTest::qWait(100);
|
||||
|
||||
// TCP Socket
|
||||
response = invokeTcpSocketTunnelProxyApiCall("TunnelProxy.RegisterClient", params).toMap();
|
||||
QVERIFY(!response.isEmpty());
|
||||
QVERIFY(response.value("status").toString() == "success");
|
||||
QVERIFY(response.value("params").toMap().contains("tunnelProxyError"));
|
||||
verifyTunnelProxyError(response, expectedError);
|
||||
|
||||
QTest::qWait(100);
|
||||
|
||||
if (socket) {
|
||||
// Close the tcp socket
|
||||
socket->close();
|
||||
delete socket;
|
||||
}
|
||||
|
||||
// Clean up
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTestsTunnelProxy::registerServerDuplicated()
|
||||
{
|
||||
// Start the server
|
||||
@ -257,6 +337,7 @@ void RemoteProxyTestsTunnelProxy::registerServerDuplicated()
|
||||
|
||||
resetDebugCategories();
|
||||
addDebugCategory("TunnelProxyServer.debug=true");
|
||||
addDebugCategory("JsonRpcTraffic.debug=true");
|
||||
|
||||
// Register a new server
|
||||
QString serverName = "tunnel proxy server awesome nymea installation";
|
||||
@ -334,5 +415,131 @@ void RemoteProxyTestsTunnelProxy::registerServerDuplicated()
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTestsTunnelProxy::registerClientDuplicated()
|
||||
{
|
||||
// Start the server
|
||||
startServer();
|
||||
|
||||
resetDebugCategories();
|
||||
addDebugCategory("TunnelProxyServer.debug=true");
|
||||
addDebugCategory("JsonRpcTraffic.debug=true");
|
||||
|
||||
|
||||
// Create the server and keep it up
|
||||
QString serverName = "creative server name";
|
||||
QUuid serverUuid = QUuid::createUuid();
|
||||
QVariantMap serverParams;
|
||||
serverParams.insert("serverName", serverName);
|
||||
serverParams.insert("serverUuid", serverUuid.toString());
|
||||
|
||||
// TCP socket
|
||||
QPair<QVariant, QSslSocket *> serverResult = invokeTcpSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterServer", serverParams);
|
||||
QVariantMap response = serverResult.first.toMap();
|
||||
QSslSocket *serverSocket = serverResult.second;
|
||||
|
||||
QVERIFY(!response.isEmpty());
|
||||
QVERIFY(response.value("status").toString() == "success");
|
||||
QVERIFY(response.value("params").toMap().contains("tunnelProxyError"));
|
||||
verifyTunnelProxyError(response);
|
||||
|
||||
// Connect a client TCP
|
||||
QString clientName = "creative server name";
|
||||
QUuid clientUuid = QUuid::createUuid();
|
||||
QVariantMap clientParams;
|
||||
clientParams.insert("clientName", serverName);
|
||||
clientParams.insert("clientUuid", clientUuid.toString());
|
||||
clientParams.insert("serverUuid", serverUuid.toString());
|
||||
|
||||
QPair<QVariant, QSslSocket *> clientResult = invokeTcpSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterClient", clientParams);
|
||||
response = clientResult.first.toMap();
|
||||
QSslSocket *clientSocketTcp = clientResult.second;
|
||||
QVERIFY(!response.isEmpty());
|
||||
QVERIFY(response.value("status").toString() == "success");
|
||||
QVERIFY(response.value("params").toMap().contains("tunnelProxyError"));
|
||||
verifyTunnelProxyError(response);
|
||||
|
||||
// Connect another client WebSocket
|
||||
QPair<QVariant, QSslSocket *> clientResultWS = invokeTcpSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterClient", clientParams);
|
||||
response = clientResultWS.first.toMap();
|
||||
QSslSocket *clientSocketWs = clientResultWS.second;
|
||||
QVERIFY(!response.isEmpty());
|
||||
QVERIFY(response.value("status").toString() == "success");
|
||||
QVERIFY(response.value("params").toMap().contains("tunnelProxyError"));
|
||||
verifyTunnelProxyError(response, TunnelProxyServer::TunnelProxyErrorAlreadyRegistered);
|
||||
|
||||
|
||||
// CleanUp
|
||||
if (clientSocketTcp) {
|
||||
// Close the tcp socket
|
||||
clientSocketTcp->close();
|
||||
delete clientSocketTcp;
|
||||
}
|
||||
|
||||
if (clientSocketWs) {
|
||||
// Close the tcp socket
|
||||
clientSocketWs->close();
|
||||
delete clientSocketWs;
|
||||
}
|
||||
|
||||
if (serverSocket) {
|
||||
// Close the tcp socket
|
||||
serverSocket->close();
|
||||
delete serverSocket;
|
||||
}
|
||||
|
||||
resetDebugCategories();
|
||||
|
||||
// Clean up
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTestsTunnelProxy::crossRegisterServerClient()
|
||||
{
|
||||
// Start the server
|
||||
startServer();
|
||||
|
||||
resetDebugCategories();
|
||||
addDebugCategory("TunnelProxyServer.debug=true");
|
||||
addDebugCategory("JsonRpcTraffic.debug=true");
|
||||
|
||||
// Create the server and keep it up
|
||||
QString serverName = "creative server name";
|
||||
QUuid serverUuid = QUuid::createUuid();
|
||||
QVariantMap serverParams;
|
||||
serverParams.insert("serverName", serverName);
|
||||
serverParams.insert("serverUuid", serverUuid.toString());
|
||||
|
||||
// TCP socket
|
||||
QPair<QVariant, QSslSocket *> serverResult = invokeTcpSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterServer", serverParams);
|
||||
QVariantMap response = serverResult.first.toMap();
|
||||
QSslSocket *serverSocket = serverResult.second;
|
||||
QVERIFY(!response.isEmpty());
|
||||
QVERIFY(response.value("status").toString() == "success");
|
||||
QVERIFY(response.value("params").toMap().contains("tunnelProxyError"));
|
||||
verifyTunnelProxyError(response);
|
||||
|
||||
|
||||
// Now try to register as client
|
||||
QVariantMap clientParams;
|
||||
clientParams.insert("clientName", "creative client name");
|
||||
clientParams.insert("clientUuid", QUuid::createUuid().toString());
|
||||
clientParams.insert("serverUuid", serverUuid.toString());
|
||||
|
||||
QPair<QVariant, QSslSocket *> result = invokeTcpSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterClient", clientParams, serverSocket);
|
||||
response = result.first.toMap();
|
||||
QVERIFY(!response.isEmpty());
|
||||
QVERIFY(response.value("status").toString() == "success");
|
||||
QVERIFY(response.value("params").toMap().contains("tunnelProxyError"));
|
||||
verifyTunnelProxyError(response, TunnelProxyServer::TunnelProxyErrorAlreadyRegistered);
|
||||
|
||||
serverSocket->close();
|
||||
delete serverSocket;
|
||||
|
||||
resetDebugCategories();
|
||||
|
||||
// Clean up
|
||||
stopServer();
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(RemoteProxyTestsTunnelProxy)
|
||||
|
||||
@ -57,9 +57,14 @@ private slots:
|
||||
void registerServer_data();
|
||||
void registerServer();
|
||||
|
||||
void registerServerDuplicated();
|
||||
void registerClient_data();
|
||||
void registerClient();
|
||||
|
||||
|
||||
void registerServerDuplicated();
|
||||
void registerClientDuplicated();
|
||||
void crossRegisterServerClient();
|
||||
|
||||
};
|
||||
|
||||
#endif // REMOTEPROXYTESTSTUNNELPROXY_H
|
||||
|
||||
@ -87,7 +87,6 @@ void BaseTest::cleanUpEngine()
|
||||
m_authenticator = nullptr;
|
||||
|
||||
if (m_configuration) {
|
||||
delete m_configuration;
|
||||
m_configuration = nullptr;
|
||||
}
|
||||
}
|
||||
@ -132,6 +131,8 @@ void BaseTest::startServer()
|
||||
QVERIFY(Engine::instance()->tcpSocketServerProxy()->running());
|
||||
QVERIFY(Engine::instance()->webSocketServerTunnelProxy()->running());
|
||||
QVERIFY(Engine::instance()->tcpSocketServerTunnelProxy()->running());
|
||||
QVERIFY(Engine::instance()->proxyServer()->running());
|
||||
QVERIFY(Engine::instance()->tunnelProxyServer()->running());
|
||||
QVERIFY(Engine::instance()->monitorServer()->running());
|
||||
}
|
||||
|
||||
@ -146,10 +147,8 @@ void BaseTest::stopServer()
|
||||
cleanUpEngine();
|
||||
}
|
||||
|
||||
QVariant BaseTest::invokeWebSocketProxyApiCall(const QString &method, const QVariantMap params, bool remainsConnected)
|
||||
QVariant BaseTest::invokeWebSocketProxyApiCall(const QString &method, const QVariantMap params)
|
||||
{
|
||||
Q_UNUSED(remainsConnected)
|
||||
|
||||
QVariantMap request;
|
||||
request.insert("id", m_commandCounter);
|
||||
request.insert("method", method);
|
||||
@ -241,10 +240,8 @@ QVariant BaseTest::injectWebSocketProxyData(const QByteArray &data)
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant BaseTest::invokeTcpSocketProxyApiCall(const QString &method, const QVariantMap params, bool remainsConnected)
|
||||
QVariant BaseTest::invokeTcpSocketProxyApiCall(const QString &method, const QVariantMap params)
|
||||
{
|
||||
Q_UNUSED(remainsConnected)
|
||||
|
||||
QVariantMap request;
|
||||
request.insert("id", m_commandCounter);
|
||||
request.insert("method", method);
|
||||
@ -461,10 +458,8 @@ QVariant BaseTest::injectTcpSocketProxyData(const QByteArray &data)
|
||||
return jsonDoc.toVariant();
|
||||
}
|
||||
|
||||
QVariant BaseTest::invokeWebSocketTunnelProxyApiCall(const QString &method, const QVariantMap params, bool remainsConnected)
|
||||
QVariant BaseTest::invokeWebSocketTunnelProxyApiCall(const QString &method, const QVariantMap params)
|
||||
{
|
||||
Q_UNUSED(remainsConnected)
|
||||
|
||||
QVariantMap request;
|
||||
request.insert("id", m_commandCounter);
|
||||
request.insert("method", method);
|
||||
@ -485,10 +480,8 @@ QVariant BaseTest::invokeWebSocketTunnelProxyApiCall(const QString &method, cons
|
||||
socket->sendTextMessage(QString(jsonDoc.toJson(QJsonDocument::Compact)));
|
||||
dataSpy.wait();
|
||||
|
||||
if (!remainsConnected) {
|
||||
socket->close();
|
||||
socket->deleteLater();
|
||||
}
|
||||
socket->close();
|
||||
socket->deleteLater();
|
||||
|
||||
for (int i = 0; i < dataSpy.count(); i++) {
|
||||
// Make sure the response ends with '}\n'
|
||||
@ -559,10 +552,8 @@ QVariant BaseTest::injectWebSocketTunnelProxyData(const QByteArray &data)
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant BaseTest::invokeTcpSocketTunnelProxyApiCall(const QString &method, const QVariantMap params, bool remainsConnected)
|
||||
QVariant BaseTest::invokeTcpSocketTunnelProxyApiCall(const QString &method, const QVariantMap params)
|
||||
{
|
||||
Q_UNUSED(remainsConnected)
|
||||
|
||||
QVariantMap request;
|
||||
request.insert("id", m_commandCounter);
|
||||
request.insert("method", method);
|
||||
|
||||
@ -85,16 +85,16 @@ protected:
|
||||
void startServer();
|
||||
void stopServer();
|
||||
|
||||
QVariant invokeWebSocketProxyApiCall(const QString &method, const QVariantMap params = QVariantMap(), bool remainsConnected = true);
|
||||
QVariant invokeWebSocketProxyApiCall(const QString &method, const QVariantMap params = QVariantMap());
|
||||
QVariant injectWebSocketProxyData(const QByteArray &data);
|
||||
|
||||
QVariant invokeTcpSocketProxyApiCall(const QString &method, const QVariantMap params = QVariantMap(), bool remainsConnected = true);
|
||||
QVariant invokeTcpSocketProxyApiCall(const QString &method, const QVariantMap params = QVariantMap());
|
||||
QVariant injectTcpSocketProxyData(const QByteArray &data);
|
||||
|
||||
QVariant invokeWebSocketTunnelProxyApiCall(const QString &method, const QVariantMap params = QVariantMap(), bool remainsConnected = true);
|
||||
QVariant invokeWebSocketTunnelProxyApiCall(const QString &method, const QVariantMap params = QVariantMap());
|
||||
QVariant injectWebSocketTunnelProxyData(const QByteArray &data);
|
||||
|
||||
QVariant invokeTcpSocketTunnelProxyApiCall(const QString &method, const QVariantMap params = QVariantMap(), bool remainsConnected = true);
|
||||
QVariant invokeTcpSocketTunnelProxyApiCall(const QString &method, const QVariantMap params = QVariantMap());
|
||||
QVariant injectTcpSocketTunnelProxyData(const QByteArray &data);
|
||||
|
||||
QPair<QVariant, QSslSocket *> invokeTcpSocketTunnelProxyApiCallPersistant(const QString &method, const QVariantMap params = QVariantMap(), QSslSocket *existingSocket = nullptr);
|
||||
|
||||
Reference in New Issue
Block a user