First basic version of client connection
This commit is contained in:
parent
de6c757a26
commit
a45e2c9ec4
@ -65,7 +65,7 @@ void Engine::start()
|
||||
qCDebug(dcEngine()) << "Starting proxy server";
|
||||
m_proxyServer->startServer();
|
||||
|
||||
setRunning(true);
|
||||
QTimer::singleShot(0, this, &Engine::run);
|
||||
}
|
||||
|
||||
void Engine::stop()
|
||||
@ -186,4 +186,9 @@ void Engine::setRunning(bool running)
|
||||
emit runningChanged(m_running);
|
||||
}
|
||||
|
||||
void Engine::run()
|
||||
{
|
||||
setRunning(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -59,6 +59,9 @@ private:
|
||||
|
||||
void setRunning(bool running);
|
||||
|
||||
private slots:
|
||||
void run();
|
||||
|
||||
signals:
|
||||
void runningChanged(bool running);
|
||||
|
||||
|
||||
@ -12,7 +12,13 @@ AuthenticationHandler::AuthenticationHandler(QObject *parent) :
|
||||
// Methods
|
||||
QVariantMap params; QVariantMap returns;
|
||||
|
||||
setDescription("Authenticate", "Authenticate this connection. This should always be the first request to the server. The given id is the unique server/client uuid (i.e. the uuid of server/client).");
|
||||
setDescription("Authenticate", "Authenticate this connection. The returned AuthenticationError informs "
|
||||
"about the result. If the authentication was not successfull, the server will close the "
|
||||
"connection immediatly after sending the error response. The given id should be a unique "
|
||||
"id the other tunnel client can understand. Once the authentication was successfull, you "
|
||||
"can wait for the RemoteProxy.TunnelEstablished notification. If you send any data before "
|
||||
"getting this notification, the server will close the connection. If the tunnel client does "
|
||||
"not show up within 10 seconds, the server will close the connection.");
|
||||
params.insert("uuid", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
params.insert("token", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
@ -60,7 +66,9 @@ void AuthenticationHandler::onAuthenticationFinished()
|
||||
if (authenticationReply->error() != Authenticator::AuthenticationErrorNoError) {
|
||||
qCWarning(dcJsonRpc()) << "Authentication error occured" << authenticationReply->error();
|
||||
jsonReply->setSuccess(true);
|
||||
authenticationReply->proxyClient()->setAuthenticated(true);
|
||||
} else {
|
||||
authenticationReply->proxyClient()->setAuthenticated(false);
|
||||
jsonReply->setSuccess(false);
|
||||
}
|
||||
|
||||
|
||||
@ -42,10 +42,8 @@ protected:
|
||||
|
||||
QVariantMap errorToReply(Authenticator::AuthenticationError error) const;
|
||||
|
||||
|
||||
JsonReply *createReply(const QVariantMap &data) const;
|
||||
JsonReply *createAsyncReply(const QString &method) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ JsonRpcServer::JsonRpcServer(QObject *parent) :
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("Hello", "Once connected to this server, a client can get information about the server by saying Hello. "
|
||||
"The response informs the client about the server.");
|
||||
"The response informs the client about this proxy server.");
|
||||
setParams("Hello", params);
|
||||
returns.insert("server", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
returns.insert("name", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
@ -33,6 +33,16 @@ JsonRpcServer::JsonRpcServer(QObject *parent) :
|
||||
returns.insert("notifications", JsonTypes::basicTypeToString(JsonTypes::Object));
|
||||
setReturns("Introspect", returns);
|
||||
|
||||
// Notifications
|
||||
params.clear(); returns.clear();
|
||||
setDescription("TunnelEstablished", "Emitted whenever the tunnel has been established successfully. "
|
||||
"This is the last message from the remote proxy server! Any following data will be from "
|
||||
"the other tunnel client until the connection will be closed. The parameter contain some information "
|
||||
"about the other tunnel client.");
|
||||
params.insert("uuid", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
setParams("TunnelEstablished", params);
|
||||
|
||||
QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
@ -90,6 +100,18 @@ JsonReply *JsonRpcServer::Introspect(const QVariantMap ¶ms, ProxyClient *pro
|
||||
return createReply(data);
|
||||
}
|
||||
|
||||
void JsonRpcServer::sendNotification(const QString &nameSpace, const QString &method, const QVariantMap ¶ms, ProxyClient *proxyClient)
|
||||
{
|
||||
QVariantMap notification;
|
||||
notification.insert("id", m_notificationId++);
|
||||
notification.insert("notification", nameSpace + "." + method);
|
||||
notification.insert("params", params);
|
||||
|
||||
QByteArray data = QJsonDocument::fromVariant(notification).toJson(QJsonDocument::Compact);
|
||||
qCDebug(dcJsonRpcTraffic()) << "Sending notification:" << data;
|
||||
proxyClient->interface()->sendData(proxyClient->clientId(), data);
|
||||
}
|
||||
|
||||
void JsonRpcServer::sendResponse(ProxyClient *client, int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
QVariantMap response;
|
||||
@ -126,27 +148,14 @@ QString JsonRpcServer::formatAssertion(const QString &targetNamespace, const QSt
|
||||
|
||||
void JsonRpcServer::registerHandler(JsonHandler *handler)
|
||||
{
|
||||
m_handlers.insert(handler->name(), handler);
|
||||
qCDebug(dcJsonRpc()) << "Register handler" << handler->name();
|
||||
for (int i = 0; i < handler->metaObject()->methodCount(); ++i) {
|
||||
QMetaMethod method = handler->metaObject()->method(i);
|
||||
if (method.methodType() == QMetaMethod::Signal && QString(method.name()).contains(QRegExp("^[A-Z]"))) {
|
||||
QObject::connect(handler, method, this, metaObject()->method(metaObject()->indexOfSlot("sendNotification(QVariantMap)")));
|
||||
}
|
||||
}
|
||||
m_handlers.insert(handler->name(), handler);
|
||||
}
|
||||
|
||||
void JsonRpcServer::unregisterHandler(JsonHandler *handler)
|
||||
{
|
||||
m_handlers.remove(handler->name());
|
||||
qCDebug(dcJsonRpc()) << "Unregister handler" << handler->name();
|
||||
|
||||
for (int i = 0; i < handler->metaObject()->methodCount(); ++i) {
|
||||
QMetaMethod method = handler->metaObject()->method(i);
|
||||
if (method.methodType() == QMetaMethod::Signal && QString(method.name()).contains(QRegExp("^[A-Z]"))) {
|
||||
QObject::connect(handler, method, this, metaObject()->method(metaObject()->indexOfSlot("sendNotification(QVariantMap)")));
|
||||
}
|
||||
}
|
||||
m_handlers.remove(handler->name());
|
||||
}
|
||||
|
||||
void JsonRpcServer::setup()
|
||||
|
||||
@ -24,8 +24,10 @@ public:
|
||||
Q_INVOKABLE JsonReply *Hello(const QVariantMap ¶ms, ProxyClient *proxyClient = nullptr) const;
|
||||
Q_INVOKABLE JsonReply *Introspect(const QVariantMap ¶ms, ProxyClient *proxyClient = nullptr) const;
|
||||
|
||||
void sendNotification(const QString &nameSpace, const QString &method, const QVariantMap ¶ms, ProxyClient *proxyClient = nullptr);
|
||||
|
||||
signals:
|
||||
void TunnelEstablished(const QVariantMap ¶ms, ProxyClient *proxyClient = nullptr);
|
||||
void TunnelEstablished(const QVariantMap ¶ms);
|
||||
|
||||
private:
|
||||
QHash<QString, JsonHandler *> m_handlers;
|
||||
|
||||
@ -15,32 +15,32 @@ QUuid ProxyClient::clientId() const
|
||||
return m_clientId;
|
||||
}
|
||||
|
||||
bool ProxyClient::authenticated() const
|
||||
bool ProxyClient::isAuthenticated() const
|
||||
{
|
||||
return m_authenticated;
|
||||
}
|
||||
|
||||
void ProxyClient::setAuthenticated(bool authenticated)
|
||||
void ProxyClient::setAuthenticated(bool isAuthenticated)
|
||||
{
|
||||
if (m_authenticated == authenticated)
|
||||
return;
|
||||
|
||||
m_authenticated = authenticated;
|
||||
emit authenticatedChanged(m_authenticated);
|
||||
// TODO: start the timeout counter and disconnect if no tunnel established
|
||||
m_authenticated = isAuthenticated;
|
||||
if (m_authenticated){
|
||||
emit authenticated();
|
||||
}
|
||||
}
|
||||
|
||||
bool ProxyClient::tunnelConnected() const
|
||||
bool ProxyClient::isTunnelConnected() const
|
||||
{
|
||||
return m_tunnelConnected;
|
||||
}
|
||||
|
||||
void ProxyClient::setTunnelConnected(bool tunnelConnected)
|
||||
void ProxyClient::setTunnelConnected(bool isTunnelConnected)
|
||||
{
|
||||
if (m_tunnelConnected == tunnelConnected)
|
||||
return;
|
||||
|
||||
m_tunnelConnected = tunnelConnected;
|
||||
emit tunnelConnectedChanged(m_tunnelConnected);
|
||||
// TODO: reset the timeout counter and disconnect if no tunnel established
|
||||
m_tunnelConnected = isTunnelConnected;
|
||||
if (m_tunnelConnected){
|
||||
emit tunnelConnected();
|
||||
}
|
||||
}
|
||||
|
||||
TransportInterface *ProxyClient::interface() const
|
||||
@ -82,8 +82,8 @@ QDebug operator<<(QDebug debug, ProxyClient *proxyClient)
|
||||
{
|
||||
debug.nospace() << "ProxyClient(" << proxyClient->interface()->serverName();
|
||||
debug.nospace() << ", " << proxyClient->clientId().toString() << ") :" << endl;
|
||||
debug.nospace() << " tunnel: " << proxyClient->tunnelConnected() << endl;
|
||||
debug.nospace() << " authenticated: " << proxyClient->authenticated() << endl;
|
||||
debug.nospace() << " tunnel: " << proxyClient->isTunnelConnected() << endl;
|
||||
debug.nospace() << " authenticated: " << proxyClient->isAuthenticated() << endl;
|
||||
if (!proxyClient->name().isEmpty() && !proxyClient->token().isEmpty() && !proxyClient->uuid().isEmpty()) {
|
||||
debug.nospace() << " name: " << proxyClient->name() << endl;
|
||||
debug.nospace() << " uuid: " << proxyClient->uuid() << endl;
|
||||
|
||||
@ -18,11 +18,11 @@ public:
|
||||
|
||||
QUuid clientId() const;
|
||||
|
||||
bool authenticated() const;
|
||||
void setAuthenticated(bool authenticated);
|
||||
bool isAuthenticated() const;
|
||||
void setAuthenticated(bool isAuthenticated);
|
||||
|
||||
bool tunnelConnected() const;
|
||||
void setTunnelConnected(bool tunnelConnected);
|
||||
bool isTunnelConnected() const;
|
||||
void setTunnelConnected(bool isTunnelConnected);
|
||||
|
||||
TransportInterface *interface() const;
|
||||
|
||||
@ -36,7 +36,6 @@ public:
|
||||
QString token() const;
|
||||
void setToken(const QString &token);
|
||||
|
||||
|
||||
private:
|
||||
TransportInterface *m_interface = nullptr;
|
||||
QUuid m_clientId;
|
||||
@ -47,8 +46,8 @@ private:
|
||||
QString m_token;
|
||||
|
||||
signals:
|
||||
void authenticatedChanged(bool authenticated);
|
||||
void tunnelConnectedChanged(bool tunnelConnected);
|
||||
void authenticated();
|
||||
void tunnelConnected();
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -46,8 +46,10 @@ void ProxyServer::onClientConnected(const QUuid &clientId)
|
||||
qCDebug(dcProxyServer()) << "New client connected" << interface->serverName() << clientId.toString();
|
||||
|
||||
ProxyClient *proxyClient = new ProxyClient(interface, clientId, this);
|
||||
m_proxyClients.insert(clientId, proxyClient);
|
||||
connect(proxyClient, &ProxyClient::authenticated, this, &ProxyServer::onProxyClientAuthenticated);
|
||||
connect(proxyClient, &ProxyClient::tunnelConnected, this, &ProxyServer::onProxyClientTunnelConnected);
|
||||
|
||||
m_proxyClients.insert(clientId, proxyClient);
|
||||
m_jsonRpcServer->registerClient(proxyClient);
|
||||
}
|
||||
|
||||
@ -58,11 +60,19 @@ void ProxyServer::onClientDisconnected(const QUuid &clientId)
|
||||
|
||||
if (m_proxyClients.contains(clientId)) {
|
||||
ProxyClient *proxyClient = m_proxyClients.take(clientId);
|
||||
m_jsonRpcServer->unregisterClient(proxyClient);
|
||||
proxyClient->deleteLater();
|
||||
// Check if client is in tunnel and clean up tunnel
|
||||
// Disconnect also the other tunnel client
|
||||
|
||||
// Clean up client tables
|
||||
if (m_authenticatedClients.values().contains(proxyClient)) {
|
||||
m_authenticatedClients.remove(proxyClient->token());
|
||||
}
|
||||
|
||||
// Unregister from json rpc server
|
||||
m_jsonRpcServer->unregisterClient(proxyClient);
|
||||
|
||||
// Delete the proxy client
|
||||
proxyClient->deleteLater();
|
||||
|
||||
// TODO: Disconnect also the other tunnel client
|
||||
}
|
||||
|
||||
// TODO: Clean up this client since it does not exist any more
|
||||
@ -77,12 +87,38 @@ void ProxyServer::onClientDataAvailable(const QUuid &clientId, const QByteArray
|
||||
}
|
||||
|
||||
qCDebug(dcProxyServer()) << "Client data available" << proxyClient << qUtf8Printable(data);
|
||||
if (proxyClient->tunnelConnected()) {
|
||||
// Pipe the data
|
||||
} else {
|
||||
// Pipe data into json rpc server
|
||||
|
||||
// If this client is not authenticated yet, and not tunnel connected, pipe the traffic into the json rpc server
|
||||
if (!proxyClient->isAuthenticated() && !proxyClient->isTunnelConnected()) {
|
||||
m_jsonRpcServer->processData(proxyClient, data);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the client is authenticated, but no tunnel created yet, kill the connection since no addition call is allowed until
|
||||
// the tunne is fully established.
|
||||
if (proxyClient->isAuthenticated() && !proxyClient->isTunnelConnected()) {
|
||||
qCWarning(dcProxyServer()) << "An authenticated client sent data without tunnel connection. This is not allowed.";
|
||||
m_jsonRpcServer->unregisterClient(proxyClient);
|
||||
// The client is authenticated and tries to send data, this is not allowed.
|
||||
proxyClient->interface()->killClientConnection(proxyClient->clientId());
|
||||
return;
|
||||
}
|
||||
|
||||
if (proxyClient->isAuthenticated() && proxyClient->isTunnelConnected()) {
|
||||
// TODO: Pipe the traffic to the tunnel client
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyServer::onProxyClientAuthenticated()
|
||||
{
|
||||
ProxyClient *proxyClient = static_cast<ProxyClient *>(sender());
|
||||
qCDebug(dcProxyServer()) << "Client authenticated" << proxyClient;
|
||||
m_authenticatedClients.insert(proxyClient->token(), proxyClient);
|
||||
}
|
||||
|
||||
void ProxyServer::onProxyClientTunnelConnected()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ProxyServer::startServer()
|
||||
|
||||
@ -25,7 +25,7 @@ private:
|
||||
QList<TransportInterface *> m_transportInterfaces;
|
||||
|
||||
QHash<QUuid, ProxyClient *> m_proxyClients;
|
||||
QHash<ProxyClient *, ProxyClient *> m_tunnels;
|
||||
QHash<QString, ProxyClient *> m_authenticatedClients;
|
||||
|
||||
void sendResponse(TransportInterface *interface, const QUuid &clientId, const QVariantMap &response = QVariantMap());
|
||||
|
||||
@ -34,6 +34,9 @@ private slots:
|
||||
void onClientDisconnected(const QUuid &clientId);
|
||||
void onClientDataAvailable(const QUuid &clientId, const QByteArray &data);
|
||||
|
||||
void onProxyClientAuthenticated();
|
||||
void onProxyClientTunnelConnected();
|
||||
|
||||
public slots:
|
||||
void startServer();
|
||||
void stopServer();
|
||||
|
||||
@ -29,6 +29,9 @@ void WebSocketServer::setServerUrl(const QUrl &serverUrl)
|
||||
|
||||
bool WebSocketServer::running() const
|
||||
{
|
||||
if (!m_server)
|
||||
return false;
|
||||
|
||||
return m_server->isListening();
|
||||
}
|
||||
|
||||
@ -147,6 +150,8 @@ bool WebSocketServer::startServer()
|
||||
qCDebug(dcWebSocketServer()) << "Starting server" << m_server->serverName() << serverUrl().toString();
|
||||
if (!m_server->listen(QHostAddress(m_serverUrl.host()), static_cast<quint16>(serverUrl().port()))) {
|
||||
qCWarning(dcWebSocketServer()) << "Server" << m_server->serverName() << "could not listen on" << serverUrl().toString();
|
||||
delete m_server;
|
||||
m_server = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
56
libnymea-remoteproxyclient/jsonreply.cpp
Normal file
56
libnymea-remoteproxyclient/jsonreply.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "jsonreply.h"
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
JsonReply::JsonReply(int commandId, QString nameSpace, QString method, QVariantMap params, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_commandId(commandId),
|
||||
m_nameSpace(nameSpace),
|
||||
m_method(method),
|
||||
m_params(params)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int JsonReply::commandId() const
|
||||
{
|
||||
return m_commandId;
|
||||
}
|
||||
|
||||
QString JsonReply::nameSpace() const
|
||||
{
|
||||
return m_nameSpace;
|
||||
}
|
||||
|
||||
QString JsonReply::method() const
|
||||
{
|
||||
return m_method;
|
||||
}
|
||||
|
||||
QVariantMap JsonReply::params() const
|
||||
{
|
||||
return m_params;
|
||||
}
|
||||
|
||||
QVariantMap JsonReply::requestMap()
|
||||
{
|
||||
QVariantMap request;
|
||||
request.insert("id", m_commandId);
|
||||
request.insert("method", m_nameSpace + "." + m_method);
|
||||
if (!m_params.isEmpty())
|
||||
request.insert("params", m_params);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
QVariantMap JsonReply::response() const
|
||||
{
|
||||
return m_response;
|
||||
}
|
||||
|
||||
void JsonReply::setResponse(const QVariantMap &response)
|
||||
{
|
||||
m_response = response;
|
||||
}
|
||||
|
||||
}
|
||||
38
libnymea-remoteproxyclient/jsonreply.h
Normal file
38
libnymea-remoteproxyclient/jsonreply.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef JSONREPLY_H
|
||||
#define JSONREPLY_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
class JsonReply : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit JsonReply(int commandId, QString nameSpace, QString method, QVariantMap params = QVariantMap(), QObject *parent = nullptr);
|
||||
|
||||
int commandId() const;
|
||||
QString nameSpace() const;
|
||||
QString method() const;
|
||||
QVariantMap params() const;
|
||||
QVariantMap requestMap();
|
||||
|
||||
QVariantMap response() const;
|
||||
void setResponse(const QVariantMap &response);
|
||||
|
||||
private:
|
||||
int m_commandId;
|
||||
QString m_nameSpace;
|
||||
QString m_method;
|
||||
QVariantMap m_params;
|
||||
QVariantMap m_response;
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // JSONREPLY_H
|
||||
@ -1,6 +1,81 @@
|
||||
#include "jsonrpcclient.h"
|
||||
#include "proxyconnection.h"
|
||||
|
||||
JsonRpcClient::JsonRpcClient(QObject *parent) : QObject(parent)
|
||||
#include <QJsonDocument>
|
||||
|
||||
Q_LOGGING_CATEGORY(dcRemoteProxyClientJsonRpc, "RemoteProxyClientJsonRpc")
|
||||
Q_LOGGING_CATEGORY(dcRemoteProxyClientJsonRpcTraffic, "RemoteProxyClientJsonRpcTraffic")
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
JsonRpcClient::JsonRpcClient(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JsonReply *JsonRpcClient::callHello()
|
||||
{
|
||||
|
||||
JsonReply *reply = new JsonReply(m_commandId, "RemoteProxy", "Hello", QVariantMap(), this);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
void JsonRpcClient::sendRequest(const QVariantMap &request)
|
||||
{
|
||||
m_connection->sendData(QJsonDocument::fromVariant(request).toJson(QJsonDocument::Compact) + '\n');
|
||||
}
|
||||
|
||||
void JsonRpcClient::onConnectedChanged(bool connected)
|
||||
{
|
||||
if (!connected) {
|
||||
m_serverName = QString();
|
||||
m_proxyServerName = QString();
|
||||
m_proxyServerVersion = QString();
|
||||
m_proxyApiVersion = QString();
|
||||
}
|
||||
}
|
||||
|
||||
void JsonRpcClient::processData(const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcRemoteProxyClientJsonRpc()) << "Invalid JSON data recived" << error.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
||||
|
||||
// check if this is a reply to a request
|
||||
int commandId = dataMap.value("id").toInt();
|
||||
JsonReply *reply = m_replies.take(commandId);
|
||||
if (reply) {
|
||||
reply->deleteLater();
|
||||
|
||||
qCDebug(dcRemoteProxyClientJsonRpcTraffic()) << QString("Got response for %1.%2: %3").arg(reply->nameSpace(),
|
||||
reply->method(),
|
||||
QString::fromUtf8(jsonDoc.toJson(QJsonDocument::Indented)));
|
||||
|
||||
if (dataMap.value("status").toString() == "error") {
|
||||
qCWarning(dcRemoteProxyClientJsonRpc()) << "Api error happend" << dataMap.value("error").toString();
|
||||
return;
|
||||
}
|
||||
|
||||
reply->setResponse(dataMap);
|
||||
reply->finished();
|
||||
return;
|
||||
}
|
||||
|
||||
// check if this is a notification
|
||||
if (dataMap.contains("notification")) {
|
||||
QStringList notification = dataMap.value("notification").toString().split(".");
|
||||
QString nameSpace = notification.first();
|
||||
|
||||
qCDebug(dcRemoteProxyClientJsonRpc()) << "Notification received" << nameSpace << notification;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,16 @@
|
||||
#define JSONRPCCLIENT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include "jsonreply.h"
|
||||
#include "proxyconnection.h"
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyClientJsonRpc)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyClientJsonRpcTraffic)
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
class JsonRpcClient : public QObject
|
||||
{
|
||||
@ -9,9 +19,30 @@ class JsonRpcClient : public QObject
|
||||
public:
|
||||
explicit JsonRpcClient(QObject *parent = nullptr);
|
||||
|
||||
JsonReply *callHello();
|
||||
|
||||
private:
|
||||
ProxyConnection *m_connection = nullptr;
|
||||
|
||||
int m_commandId = 0;
|
||||
|
||||
QHash<int, JsonReply *> m_replies;
|
||||
|
||||
QString m_serverName;
|
||||
QString m_proxyServerName;
|
||||
QString m_proxyServerVersion;
|
||||
QString m_proxyApiVersion;
|
||||
|
||||
void sendRequest(const QVariantMap &request);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void onConnectedChanged(bool connected);
|
||||
void processData(const QByteArray &data);
|
||||
|
||||
};
|
||||
|
||||
#endif // JSONRPCCLIENT_H
|
||||
}
|
||||
|
||||
#endif // JSONRPCCLIENT_H
|
||||
|
||||
@ -4,17 +4,19 @@ TEMPLATE = lib
|
||||
TARGET = nymea-remoteproxyclient
|
||||
|
||||
HEADERS += \
|
||||
remoteproxyconnector.h \
|
||||
websocketconnector.h \
|
||||
socketconnector.h \
|
||||
jsonrpcclient.h
|
||||
jsonrpcclient.h \
|
||||
jsonreply.h \
|
||||
remoteproxyconnection.h \
|
||||
proxyconnection.h \
|
||||
websocketconnection.h
|
||||
|
||||
|
||||
SOURCES += \
|
||||
remoteproxyconnector.cpp \
|
||||
websocketconnector.cpp \
|
||||
socketconnector.cpp \
|
||||
jsonrpcclient.cpp
|
||||
jsonrpcclient.cpp \
|
||||
jsonreply.cpp \
|
||||
remoteproxyconnection.cpp \
|
||||
proxyconnection.cpp \
|
||||
websocketconnection.cpp
|
||||
|
||||
|
||||
# install header file with relative subdirectory
|
||||
|
||||
26
libnymea-remoteproxyclient/proxyconnection.cpp
Normal file
26
libnymea-remoteproxyclient/proxyconnection.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "proxyconnection.h"
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
ProxyConnection::ProxyConnection(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ProxyConnection::~ProxyConnection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ProxyConnection::allowSslErrors() const
|
||||
{
|
||||
return m_allowSslErrors;
|
||||
}
|
||||
|
||||
void ProxyConnection::setAllowSslErrors(bool allowSslErrors)
|
||||
{
|
||||
m_allowSslErrors = allowSslErrors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -4,21 +4,31 @@
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
|
||||
class SocketConnector : public QObject
|
||||
namespace remoteproxyclient {
|
||||
|
||||
class ProxyConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SocketConnector(QObject *parent = nullptr);
|
||||
virtual ~SocketConnector() = 0;
|
||||
explicit ProxyConnection(QObject *parent = nullptr);
|
||||
virtual ~ProxyConnection() = 0;
|
||||
|
||||
virtual void sendData(const QByteArray &data) = 0;
|
||||
virtual bool isConnected() = 0;
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
virtual QUrl serverUrl() const = 0;
|
||||
|
||||
bool allowSslErrors() const;
|
||||
void setAllowSslErrors(bool allowSslErrors);
|
||||
|
||||
private:
|
||||
bool m_allowSslErrors = false;
|
||||
|
||||
signals:
|
||||
void connectedChanged(bool connected);
|
||||
void dataReceived(const QByteArray &data);
|
||||
void errorOccured();
|
||||
void sslErrorOccured();
|
||||
|
||||
public slots:
|
||||
virtual void connectServer(const QHostAddress &address, quint16 port) = 0;
|
||||
@ -26,4 +36,6 @@ public slots:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SOCKETCONNECTOR_H
|
||||
237
libnymea-remoteproxyclient/remoteproxyconnection.cpp
Normal file
237
libnymea-remoteproxyclient/remoteproxyconnection.cpp
Normal file
@ -0,0 +1,237 @@
|
||||
#include "remoteproxyconnection.h"
|
||||
#include "websocketconnection.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(dcRemoteProxyClientConnection, "RemoteProxyClientConnection")
|
||||
Q_LOGGING_CATEGORY(dcRemoteProxyClientConnectionTraffic, "RemoteProxyClientConnectionTraffic")
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
RemoteProxyConnection::RemoteProxyConnection(ConnectionType connectionType, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_connectionType(connectionType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RemoteProxyConnection::~RemoteProxyConnection()
|
||||
{
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
RemoteProxyConnection::State RemoteProxyConnection::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
RemoteProxyConnection::Error RemoteProxyConnection::error() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
QString RemoteProxyConnection::errorString() const
|
||||
{
|
||||
QString errorString;
|
||||
switch (m_error) {
|
||||
case ErrorNoError:
|
||||
errorString = "";
|
||||
break;
|
||||
case ErrorSocketError:
|
||||
errorString = "Socket connection error occured.";
|
||||
break;
|
||||
case ErrorSslError:
|
||||
errorString = "SSL error occured.";
|
||||
break;
|
||||
case ErrorProxyNotResponding:
|
||||
errorString = "The proxy server does not respond.";
|
||||
break;
|
||||
case ErrorProxyAuthenticationFailed:
|
||||
errorString = "The authentication on the proxy server failed.";
|
||||
break;
|
||||
}
|
||||
|
||||
return errorString;
|
||||
}
|
||||
|
||||
bool RemoteProxyConnection::isConnected() const
|
||||
{
|
||||
return m_state == StateConnected || m_state == StateAuthenticating || m_state == StateWaitTunnel || m_state == StateRemoteConnected;
|
||||
}
|
||||
|
||||
bool RemoteProxyConnection::isRemoteConnected() const
|
||||
{
|
||||
return m_state == StateRemoteConnected;
|
||||
}
|
||||
|
||||
RemoteProxyConnection::ConnectionType RemoteProxyConnection::connectionType() const
|
||||
{
|
||||
return m_connectionType;
|
||||
}
|
||||
|
||||
QHostAddress RemoteProxyConnection::serverAddress() const
|
||||
{
|
||||
return m_serverAddress;
|
||||
}
|
||||
|
||||
quint16 RemoteProxyConnection::serverPort() const
|
||||
{
|
||||
return m_serverPort;
|
||||
}
|
||||
|
||||
bool RemoteProxyConnection::insecureConnection() const
|
||||
{
|
||||
return m_insecureConnection;
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::setInsecureConnection(bool insecureConnection)
|
||||
{
|
||||
m_insecureConnection = insecureConnection;
|
||||
}
|
||||
|
||||
bool RemoteProxyConnection::sendData(const QByteArray &data)
|
||||
{
|
||||
if (!isConnected()) {
|
||||
qCWarning(dcRemoteProxyClientConnection()) << "Could not send data. Not connected.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isRemoteConnected()) {
|
||||
qCWarning(dcRemoteProxyClientConnection()) << "Could not send data. The remote client is not connected yet.";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_connection->sendData(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::cleanUp()
|
||||
{
|
||||
if (m_jsonClient) {
|
||||
delete m_jsonClient;
|
||||
m_jsonClient = nullptr;
|
||||
}
|
||||
|
||||
if (m_connection) {
|
||||
delete m_connection;
|
||||
m_connection = nullptr;
|
||||
}
|
||||
|
||||
setState(StateDisconnected);
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::setState(RemoteProxyConnection::State state)
|
||||
{
|
||||
if (m_state == state)
|
||||
return;
|
||||
|
||||
qCDebug(dcRemoteProxyClientConnection()) << "State changed" << state;
|
||||
m_state = state;
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::setError(RemoteProxyConnection::Error error)
|
||||
{
|
||||
if (m_error == error)
|
||||
return;
|
||||
|
||||
qCDebug(dcRemoteProxyClientConnection()) << "Error occured" << error;
|
||||
m_error = error;
|
||||
emit errorOccured(m_error);
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::onConnectionChanged(bool isConnected)
|
||||
{
|
||||
if (!isConnected) {
|
||||
emit disconnected();
|
||||
cleanUp();
|
||||
} else {
|
||||
setState(StateConnected);
|
||||
emit connected();
|
||||
|
||||
JsonReply *reply = m_jsonClient->callHello();
|
||||
connect(reply, &JsonReply::finished, this, &RemoteProxyConnection::onHelloFinished);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::onConnectionDataAvailable(const QByteArray &data)
|
||||
{
|
||||
switch (m_state) {
|
||||
case StateConnected:
|
||||
m_jsonClient->processData(data);
|
||||
case StateRemoteConnected:
|
||||
// Remote data arrived
|
||||
emit dataReady(data);
|
||||
default:
|
||||
qCDebug(dcRemoteProxyClientConnection()) << "Unhandled: Data reviced" << data;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::onConnectionSocketError()
|
||||
{
|
||||
setError(ErrorSocketError);
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::onConnectionSslError()
|
||||
{
|
||||
setError(ErrorSslError);
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::onHelloFinished()
|
||||
{
|
||||
JsonReply *reply = static_cast<JsonReply *>(sender());
|
||||
QVariantMap response = reply->response();
|
||||
qCDebug(dcRemoteProxyClientConnection()) << "Hello response ready" << response;
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::onAuthenticateFinished()
|
||||
{
|
||||
JsonReply *reply = static_cast<JsonReply *>(sender());
|
||||
QVariantMap response = reply->response();
|
||||
qCDebug(dcRemoteProxyClientConnection()) << "Hello response ready" << response;
|
||||
}
|
||||
|
||||
bool RemoteProxyConnection::connectServer(const QHostAddress &serverAddress, quint16 port)
|
||||
{
|
||||
m_serverAddress = serverAddress;
|
||||
m_serverPort = port;
|
||||
|
||||
if (m_connection) {
|
||||
delete m_connection;
|
||||
m_connection = nullptr;
|
||||
}
|
||||
|
||||
if (m_jsonClient) {
|
||||
delete m_jsonClient;
|
||||
m_jsonClient = nullptr;
|
||||
}
|
||||
|
||||
switch (m_connectionType) {
|
||||
case ConnectionTypeWebSocket:
|
||||
m_connection = qobject_cast<ProxyConnection *>(new WebSocketConnection(this));
|
||||
}
|
||||
|
||||
m_connection->setAllowSslErrors(m_insecureConnection);
|
||||
|
||||
connect(m_connection, &ProxyConnection::connectedChanged, this, &RemoteProxyConnection::onConnectionChanged);
|
||||
connect(m_connection, &ProxyConnection::dataReceived, this, &RemoteProxyConnection::onConnectionDataAvailable);
|
||||
connect(m_connection, &ProxyConnection::errorOccured, this, &RemoteProxyConnection::onConnectionSocketError);
|
||||
connect(m_connection, &ProxyConnection::sslErrorOccured, this, &RemoteProxyConnection::onConnectionSslError);
|
||||
|
||||
m_jsonClient = new JsonRpcClient(this);
|
||||
|
||||
qCDebug(dcRemoteProxyClientConnection()) << "Connecting to" << QString("%1:%2").arg(serverAddress.toString()).arg(port);
|
||||
m_connection->connectServer(serverAddress, port);
|
||||
|
||||
setState(StateConnecting);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteProxyConnection::disconnectServer()
|
||||
{
|
||||
if (m_connection)
|
||||
qCDebug(dcRemoteProxyClientConnection()) << "Disconnect from" << m_connection->serverUrl().toString();
|
||||
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,9 +7,15 @@
|
||||
#include <QHostAddress>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyConnector)
|
||||
#include "jsonrpcclient.h"
|
||||
#include "proxyconnection.h"
|
||||
|
||||
class RemoteProxyConnector : public QObject
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyClientConnection)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyClientConnectionTraffic)
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
class RemoteProxyConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -23,7 +29,7 @@ public:
|
||||
StateConnected,
|
||||
StateAuthenticating,
|
||||
StateWaitTunnel,
|
||||
StateTunnelEstablished,
|
||||
StateRemoteConnected,
|
||||
StateDisconnected
|
||||
};
|
||||
Q_ENUM(State)
|
||||
@ -37,23 +43,18 @@ public:
|
||||
};
|
||||
Q_ENUM(Error)
|
||||
|
||||
explicit RemoteProxyConnector(QObject *parent = nullptr);
|
||||
~RemoteProxyConnector();
|
||||
explicit RemoteProxyConnection(ConnectionType connectionType = ConnectionTypeWebSocket, QObject *parent = nullptr);
|
||||
~RemoteProxyConnection();
|
||||
|
||||
State state() const;
|
||||
RemoteProxyConnection::State state() const;
|
||||
|
||||
Error error() const;
|
||||
RemoteProxyConnection::Error error() const;
|
||||
QString errorString() const;
|
||||
|
||||
QAbstractSocket::SocketError socketError() const;
|
||||
QString socketErrorString() const;
|
||||
|
||||
QUrl serverUrl() const;
|
||||
|
||||
bool isConnected() const;
|
||||
bool tunnelEstablished() const;
|
||||
bool isRemoteConnected() const;
|
||||
|
||||
ConnectionType connectionType() const;
|
||||
RemoteProxyConnection::ConnectionType connectionType() const;
|
||||
QHostAddress serverAddress() const;
|
||||
quint16 serverPort() const;
|
||||
|
||||
@ -69,34 +70,33 @@ private:
|
||||
State m_state = StateDisconnected;
|
||||
Error m_error = ErrorNoError;
|
||||
bool m_insecureConnection = false;
|
||||
bool m_tunnelEstablished = false;
|
||||
QWebSocket *m_webSocket = nullptr;
|
||||
bool m_remoteConnected = false;
|
||||
|
||||
JsonRpcClient *m_jsonClient = nullptr;
|
||||
ProxyConnection *m_connection = nullptr;
|
||||
|
||||
void cleanUp();
|
||||
|
||||
void setState(State state);
|
||||
void setError(Error error);
|
||||
|
||||
void setConnectionType(ConnectionType type);
|
||||
void setServerAddress(const QHostAddress serverAddress);
|
||||
void setServerPort(quint16 serverPort);
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void tunnelEstablished();
|
||||
void stateChanged(RemoteProxyConnector::State state);
|
||||
void errorOccured(RemoteProxyConnector::Error error);
|
||||
void remoteConnectedChanged(bool remoteConnected);
|
||||
void stateChanged(RemoteProxyConnection::State state);
|
||||
void errorOccured(RemoteProxyConnection::Error error);
|
||||
|
||||
void dataReady(const QByteArray &data);
|
||||
|
||||
private slots:
|
||||
void onSocketConnected();
|
||||
void onSocketDisconnected();
|
||||
void onSocketError(QAbstractSocket::SocketError error);
|
||||
void onSocketSslError(const QList<QSslError> &errors);
|
||||
void onSocketStateChanged(QAbstractSocket::SocketState state);
|
||||
void onTextMessageReceived(const QString &message);
|
||||
void onBinaryMessageReceived(const QByteArray &message);
|
||||
void onConnectionChanged(bool isConnected);
|
||||
void onConnectionDataAvailable(const QByteArray &data);
|
||||
void onConnectionSocketError();
|
||||
void onConnectionSslError();
|
||||
|
||||
void onHelloFinished();
|
||||
void onAuthenticateFinished();
|
||||
|
||||
public slots:
|
||||
bool connectServer(const QHostAddress &serverAddress, quint16 port);
|
||||
@ -104,8 +104,10 @@ public slots:
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(RemoteProxyConnector::State);
|
||||
Q_DECLARE_METATYPE(RemoteProxyConnector::Error);
|
||||
Q_DECLARE_METATYPE(RemoteProxyConnector::ConnectionType);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(remoteproxyclient::RemoteProxyConnection::State);
|
||||
Q_DECLARE_METATYPE(remoteproxyclient::RemoteProxyConnection::Error);
|
||||
Q_DECLARE_METATYPE(remoteproxyclient::RemoteProxyConnection::ConnectionType);
|
||||
|
||||
#endif // REMOTEPROXYCONNECTOR_H
|
||||
@ -1,282 +0,0 @@
|
||||
#include "remoteproxyconnector.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(dcRemoteProxyConnector, "RemoteProxyConnector")
|
||||
|
||||
RemoteProxyConnector::RemoteProxyConnector(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RemoteProxyConnector::~RemoteProxyConnector()
|
||||
{
|
||||
disconnectServer();
|
||||
}
|
||||
|
||||
RemoteProxyConnector::State RemoteProxyConnector::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
RemoteProxyConnector::Error RemoteProxyConnector::error() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
QString RemoteProxyConnector::errorString() const
|
||||
{
|
||||
QString errorString;
|
||||
switch (m_error) {
|
||||
case ErrorNoError:
|
||||
errorString = "";
|
||||
break;
|
||||
case ErrorSocketError:
|
||||
errorString = "Socket connection error occured: " + socketErrorString();
|
||||
break;
|
||||
case ErrorSslError:
|
||||
errorString = "Socket SSL error occured.";
|
||||
break;
|
||||
case ErrorProxyNotResponding:
|
||||
errorString = "The proxy server does not respond.";
|
||||
break;
|
||||
case ErrorProxyAuthenticationFailed:
|
||||
errorString = "The authentication on the proxy server failed.";
|
||||
break;
|
||||
}
|
||||
|
||||
return errorString;
|
||||
}
|
||||
|
||||
QAbstractSocket::SocketError RemoteProxyConnector::socketError() const
|
||||
{
|
||||
if (!m_webSocket)
|
||||
return QAbstractSocket::UnknownSocketError;
|
||||
|
||||
return m_webSocket->error();
|
||||
}
|
||||
|
||||
QString RemoteProxyConnector::socketErrorString() const
|
||||
{
|
||||
if (!m_webSocket)
|
||||
return QString();
|
||||
|
||||
return m_webSocket->errorString();
|
||||
}
|
||||
|
||||
QUrl RemoteProxyConnector::serverUrl() const
|
||||
{
|
||||
QUrl serverUrl;
|
||||
serverUrl.setScheme("wss");
|
||||
serverUrl.setHost(m_serverAddress.toString());
|
||||
serverUrl.setPort(m_serverPort);
|
||||
return serverUrl;
|
||||
}
|
||||
|
||||
bool RemoteProxyConnector::isConnected() const
|
||||
{
|
||||
return m_state == StateConnected || m_state == StateAuthenticating || m_state == StateWaitTunnel || m_state == StateTunnelEstablished;
|
||||
}
|
||||
|
||||
bool RemoteProxyConnector::tunnelEstablished() const
|
||||
{
|
||||
return m_state == StateTunnelEstablished;
|
||||
}
|
||||
|
||||
RemoteProxyConnector::ConnectionType RemoteProxyConnector::connectionType() const
|
||||
{
|
||||
return m_connectionType;
|
||||
}
|
||||
|
||||
QHostAddress RemoteProxyConnector::serverAddress() const
|
||||
{
|
||||
return m_serverAddress;
|
||||
}
|
||||
|
||||
quint16 RemoteProxyConnector::serverPort() const
|
||||
{
|
||||
return m_serverPort;
|
||||
}
|
||||
|
||||
bool RemoteProxyConnector::insecureConnection() const
|
||||
{
|
||||
return m_insecureConnection;
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::setInsecureConnection(bool insecureConnection)
|
||||
{
|
||||
m_insecureConnection = insecureConnection;
|
||||
}
|
||||
|
||||
bool RemoteProxyConnector::sendData(const QByteArray &data)
|
||||
{
|
||||
// FIXME: reenable once the auth process is finished
|
||||
// if (m_state != StateTunnelEstablished) {
|
||||
// qWarning() << "RemoteProxyClient: There is no established tunnel for" << serverUrl().toString() << "yet.";
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (!m_webSocket) {
|
||||
qCWarning(dcRemoteProxyConnector()) << "There is no websocket";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isConnected()) {
|
||||
qCWarning(dcRemoteProxyConnector()) << "Not connected";
|
||||
return false;
|
||||
}
|
||||
|
||||
qCDebug(dcRemoteProxyConnector()) << "Sending data:" << data;
|
||||
qint64 dataSendCount = m_webSocket->sendTextMessage(QString::fromUtf8(data));
|
||||
if (dataSendCount != data.count()) {
|
||||
qCWarning(dcRemoteProxyConnector()) << "Could not send all data to" << serverUrl().toString();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::setState(RemoteProxyConnector::State state)
|
||||
{
|
||||
if (m_state == state)
|
||||
return;
|
||||
|
||||
qCDebug(dcRemoteProxyConnector()) << "State changed" << state;
|
||||
m_state = state;
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::setError(RemoteProxyConnector::Error error)
|
||||
{
|
||||
if (m_error == error)
|
||||
return;
|
||||
|
||||
qCDebug(dcRemoteProxyConnector()) << "Error occured" << error;
|
||||
m_error = error;
|
||||
emit errorOccured(m_error);
|
||||
}
|
||||
|
||||
|
||||
void RemoteProxyConnector::setConnectionType(RemoteProxyConnector::ConnectionType type)
|
||||
{
|
||||
m_connectionType = type;
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::setServerAddress(const QHostAddress serverAddress)
|
||||
{
|
||||
m_serverAddress = serverAddress;
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::setServerPort(quint16 serverPort)
|
||||
{
|
||||
m_serverPort = serverPort;
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::onSocketConnected()
|
||||
{
|
||||
setState(StateConnected);
|
||||
qCDebug(dcRemoteProxyConnector()) << "Connected to" << serverUrl().toString();
|
||||
emit connected();
|
||||
|
||||
// TODO: start authentication process
|
||||
|
||||
setState(StateAuthenticating);
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::onSocketDisconnected()
|
||||
{
|
||||
qCDebug(dcRemoteProxyConnector()) << "Disconnected from" << serverUrl().toString();
|
||||
setState(StateDisconnected);
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::onSocketError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
qCWarning(dcRemoteProxyConnector()) << "Socket error occured" << error;
|
||||
setError(ErrorSocketError);
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::onSocketSslError(const QList<QSslError> &errors)
|
||||
{
|
||||
if (m_insecureConnection) {
|
||||
qCDebug(dcRemoteProxyConnector()) << "Ignore ssl errors because explicit allowed to use an insecure connection.";
|
||||
m_webSocket->ignoreSslErrors();
|
||||
} else {
|
||||
qCWarning(dcRemoteProxyConnector()) << "Socket ssl errors occured:";
|
||||
foreach (const QSslError sslError, errors) {
|
||||
qCWarning(dcRemoteProxyConnector()) << " -->" << static_cast<int>(sslError.error()) << sslError.errorString();
|
||||
}
|
||||
setError(ErrorSslError);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::onSocketStateChanged(QAbstractSocket::SocketState state)
|
||||
{
|
||||
qCDebug(dcRemoteProxyConnector()) << "Socket state changed" << state;
|
||||
switch (state) {
|
||||
case QAbstractSocket::ConnectingState:
|
||||
case QAbstractSocket::HostLookupState:
|
||||
setState(StateConnecting);
|
||||
break;
|
||||
case QAbstractSocket::ConnectedState:
|
||||
setState(StateConnected);
|
||||
break;
|
||||
default:
|
||||
setState(StateDisconnected);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::onTextMessageReceived(const QString &message)
|
||||
{
|
||||
// TODO: check if tunnel is established, if so, emit data received
|
||||
qCDebug(dcRemoteProxyConnector()) << "Data received" << message;
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::onBinaryMessageReceived(const QByteArray &message)
|
||||
{
|
||||
Q_UNUSED(message);
|
||||
}
|
||||
|
||||
bool RemoteProxyConnector::connectServer(const QHostAddress &serverAddress, quint16 port)
|
||||
{
|
||||
setServerAddress(serverAddress);
|
||||
setServerPort(port);
|
||||
|
||||
switch (m_connectionType) {
|
||||
// TODO: currently only websocket support
|
||||
case ConnectionTypeWebSocket:
|
||||
disconnectServer();
|
||||
|
||||
m_webSocket = new QWebSocket("libnymea-remoteproxyclient", QWebSocketProtocol::VersionLatest, this);
|
||||
|
||||
if (m_insecureConnection)
|
||||
m_webSocket->ignoreSslErrors();
|
||||
|
||||
connect(m_webSocket, &QWebSocket::connected, this, &RemoteProxyConnector::onSocketConnected);
|
||||
connect(m_webSocket, &QWebSocket::disconnected, this, &RemoteProxyConnector::onSocketDisconnected);
|
||||
connect(m_webSocket, &QWebSocket::textMessageReceived, this, &RemoteProxyConnector::onTextMessageReceived);
|
||||
connect(m_webSocket, &QWebSocket::binaryMessageReceived, this, &RemoteProxyConnector::onBinaryMessageReceived);
|
||||
|
||||
connect(m_webSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
|
||||
connect(m_webSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(onSocketSslError(QList<QSslError>)));
|
||||
connect(m_webSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
|
||||
|
||||
setState(StateConnecting);
|
||||
m_webSocket->open(serverUrl());
|
||||
qCDebug(dcRemoteProxyConnector()) << "Start connecting to" << serverUrl().toString();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoteProxyConnector::disconnectServer()
|
||||
{
|
||||
if (!m_webSocket)
|
||||
return;
|
||||
|
||||
qCDebug(dcRemoteProxyConnector()) << "Disconnect from server" << serverUrl().toString();
|
||||
m_webSocket->close(QWebSocketProtocol::CloseCodeNormal, "Bye bye");
|
||||
m_webSocket->deleteLater();
|
||||
m_webSocket = nullptr;
|
||||
setState(StateDisconnected);
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
#include "socketconnector.h"
|
||||
|
||||
SocketConnector::SocketConnector(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SocketConnector::~SocketConnector()
|
||||
{
|
||||
|
||||
}
|
||||
109
libnymea-remoteproxyclient/websocketconnection.cpp
Normal file
109
libnymea-remoteproxyclient/websocketconnection.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
#include "websocketconnection.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(dcRemoteProxyClientWebSocket, "RemoteProxyClientWebSocket")
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
WebSocketConnection::WebSocketConnection(QObject *parent) :
|
||||
ProxyConnection(parent)
|
||||
{
|
||||
m_webSocket = new QWebSocket("libnymea-remoteproxyclient", QWebSocketProtocol::VersionLatest, this);
|
||||
|
||||
if (allowSslErrors())
|
||||
m_webSocket->ignoreSslErrors();
|
||||
|
||||
connect(m_webSocket, &QWebSocket::connected, this, &WebSocketConnection::onConnected);
|
||||
connect(m_webSocket, &QWebSocket::disconnected, this, &WebSocketConnection::onDisconnected);
|
||||
connect(m_webSocket, &QWebSocket::textMessageReceived, this, &WebSocketConnection::onTextMessageReceived);
|
||||
connect(m_webSocket, &QWebSocket::binaryMessageReceived, this, &WebSocketConnection::onBinaryMessageReceived);
|
||||
|
||||
connect(m_webSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
|
||||
connect(m_webSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(onSslError(QList<QSslError>)));
|
||||
connect(m_webSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
|
||||
}
|
||||
|
||||
WebSocketConnection::~WebSocketConnection()
|
||||
{
|
||||
disconnectServer();
|
||||
}
|
||||
|
||||
QUrl WebSocketConnection::serverUrl() const
|
||||
{
|
||||
return m_serverUrl;
|
||||
}
|
||||
|
||||
void WebSocketConnection::sendData(const QByteArray &data)
|
||||
{
|
||||
m_webSocket->sendTextMessage(QString::fromUtf8(data));
|
||||
}
|
||||
|
||||
bool WebSocketConnection::isConnected()
|
||||
{
|
||||
return m_webSocket->state() == QAbstractSocket::ConnectedState;
|
||||
}
|
||||
|
||||
void WebSocketConnection::onConnected()
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientWebSocket()) << "Connected with" << m_webSocket->requestUrl().toString();
|
||||
emit connectedChanged(true);
|
||||
}
|
||||
|
||||
void WebSocketConnection::onDisconnected()
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientWebSocket()) << "Disconnected from" << m_webSocket->requestUrl().toString();
|
||||
emit connectedChanged(false);
|
||||
}
|
||||
|
||||
void WebSocketConnection::onError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientWebSocket()) << "Socket error occured" << error << m_webSocket->errorString();
|
||||
}
|
||||
|
||||
void WebSocketConnection::onSslError(const QList<QSslError> &errors)
|
||||
{
|
||||
if (allowSslErrors()) {
|
||||
qCDebug(dcRemoteProxyClientWebSocket()) << "Ignore ssl errors because the developer explicitly allowed to use an insecure connection.";
|
||||
m_webSocket->ignoreSslErrors();
|
||||
} else {
|
||||
qCWarning(dcRemoteProxyClientWebSocket()) << "SSL errors occured:";
|
||||
foreach (const QSslError sslError, errors) {
|
||||
qCWarning(dcRemoteProxyClientWebSocket()) << " -->" << static_cast<int>(sslError.error()) << sslError.errorString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebSocketConnection::onStateChanged(QAbstractSocket::SocketState state)
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientWebSocket()) << "Socket state changed" << state;
|
||||
}
|
||||
|
||||
void WebSocketConnection::onTextMessageReceived(const QString &message)
|
||||
{
|
||||
emit dataReceived(message.toUtf8());
|
||||
}
|
||||
|
||||
void WebSocketConnection::onBinaryMessageReceived(const QByteArray &message)
|
||||
{
|
||||
Q_UNUSED(message)
|
||||
}
|
||||
|
||||
void WebSocketConnection::connectServer(const QHostAddress &address, quint16 port)
|
||||
{
|
||||
QUrl url;
|
||||
url.setScheme("wss");
|
||||
url.setHost(address.toString());
|
||||
url.port(port);
|
||||
|
||||
m_serverUrl = url;
|
||||
|
||||
qCDebug(dcRemoteProxyClientWebSocket()) << "Connecting to" << serverUrl().toString();
|
||||
m_webSocket->open(m_serverUrl);
|
||||
}
|
||||
|
||||
void WebSocketConnection::disconnectServer()
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientWebSocket()) << "Disconnecting from" << serverUrl().toString();
|
||||
m_webSocket->close();
|
||||
}
|
||||
|
||||
}
|
||||
47
libnymea-remoteproxyclient/websocketconnection.h
Normal file
47
libnymea-remoteproxyclient/websocketconnection.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef WEBSOCKETCONNECTOR_H
|
||||
#define WEBSOCKETCONNECTOR_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QWebSocket>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include "proxyconnection.h"
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyClientWebSocket)
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
class WebSocketConnection : public ProxyConnection
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WebSocketConnection(QObject *parent = nullptr);
|
||||
~WebSocketConnection() override;
|
||||
|
||||
QUrl serverUrl() const override;
|
||||
|
||||
void sendData(const QByteArray &data) override;
|
||||
bool isConnected() override;
|
||||
|
||||
private:
|
||||
QUrl m_serverUrl;
|
||||
QWebSocket *m_webSocket = nullptr;
|
||||
|
||||
private slots:
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onError(QAbstractSocket::SocketError error);
|
||||
void onSslError(const QList<QSslError> &errors);
|
||||
void onStateChanged(QAbstractSocket::SocketState state);
|
||||
void onTextMessageReceived(const QString &message);
|
||||
void onBinaryMessageReceived(const QByteArray &message);
|
||||
|
||||
public slots:
|
||||
void connectServer(const QHostAddress &address, quint16 port) override;
|
||||
void disconnectServer() override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // WEBSOCKETCONNECTOR_H
|
||||
@ -1,12 +0,0 @@
|
||||
#include "websocketconnector.h"
|
||||
|
||||
WebSocketConnector::WebSocketConnector(QObject *parent) :
|
||||
SocketConnector(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void WebSocketConnector::sendData(const QByteArray &data)
|
||||
{
|
||||
Q_UNUSED(data)
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
#ifndef WEBSOCKETCONNECTOR_H
|
||||
#define WEBSOCKETCONNECTOR_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "socketconnector.h"
|
||||
|
||||
class WebSocketConnector : public SocketConnector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WebSocketConnector(QObject *parent = nullptr);
|
||||
|
||||
void sendData(const QByteArray &data) override;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // WEBSOCKETCONNECTOR_H
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
#include "engine.h"
|
||||
#include "loggingcategories.h"
|
||||
#include "remoteproxyconnector.h"
|
||||
#include "remoteproxyconnection.h"
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QSignalSpy>
|
||||
@ -73,7 +73,13 @@ void RemoteProxyTests::startServer()
|
||||
{
|
||||
startEngine();
|
||||
|
||||
Engine::instance()->start();
|
||||
if (!Engine::instance()->running()) {
|
||||
QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged);
|
||||
Engine::instance()->start();
|
||||
runningSpy.wait();
|
||||
QVERIFY(runningSpy.count() == 1);
|
||||
}
|
||||
|
||||
QVERIFY(Engine::instance()->running());
|
||||
QVERIFY(Engine::instance()->webSocketServer()->running());
|
||||
}
|
||||
@ -106,21 +112,21 @@ QVariant RemoteProxyTests::invokeApiCall(const QString &method, const QVariantMa
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// QSignalSpy disconnectedSpy(socket, SIGNAL(disconnected()));
|
||||
// QSignalSpy disconnectedSpy(socket, SIGNAL(disconnected()));
|
||||
QSignalSpy dataSpy(socket, SIGNAL(textMessageReceived(QString)));
|
||||
socket->sendTextMessage(QString(jsonDoc.toJson(QJsonDocument::Compact)));
|
||||
dataSpy.wait();
|
||||
// if (remainsConnected) {
|
||||
// disconnectedSpy.wait(1000);
|
||||
// if (socket->state() != QAbstractSocket::UnconnectedState) {
|
||||
// qWarning() << "!!!!!!!!!!!!! socket still connected but should be disconnected!";
|
||||
// }
|
||||
// } else {
|
||||
// disconnectedSpy.wait();
|
||||
// if (socket->state() != QAbstractSocket::ConnectedState) {
|
||||
// qWarning() << "!!!!!!!!!!!!! socket not connected but should be!";
|
||||
// }
|
||||
// }
|
||||
// if (remainsConnected) {
|
||||
// disconnectedSpy.wait(1000);
|
||||
// if (socket->state() != QAbstractSocket::UnconnectedState) {
|
||||
// qWarning() << "!!!!!!!!!!!!! socket still connected but should be disconnected!";
|
||||
// }
|
||||
// } else {
|
||||
// disconnectedSpy.wait();
|
||||
// if (socket->state() != QAbstractSocket::ConnectedState) {
|
||||
// qWarning() << "!!!!!!!!!!!!! socket not connected but should be!";
|
||||
// }
|
||||
// }
|
||||
|
||||
socket->close();
|
||||
socket->deleteLater();
|
||||
@ -182,7 +188,7 @@ QVariant RemoteProxyTests::injectSocketData(const QByteArray &data)
|
||||
|
||||
void RemoteProxyTests::initTestCase()
|
||||
{
|
||||
qRegisterMetaType<RemoteProxyConnector::Error>();
|
||||
qRegisterMetaType<RemoteProxyConnection::Error>();
|
||||
|
||||
qCDebug(dcApplication()) << "Init test case.";
|
||||
restartEngine();
|
||||
@ -211,10 +217,17 @@ void RemoteProxyTests::webserverConnectionBlocked()
|
||||
Engine::instance()->setAuthenticator(m_authenticator);
|
||||
Engine::instance()->setWebSocketServerHostAddress(QHostAddress::LocalHost);
|
||||
Engine::instance()->setSslConfiguration(m_sslConfiguration);
|
||||
|
||||
QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged);
|
||||
Engine::instance()->start();
|
||||
runningSpy.wait();
|
||||
|
||||
QVERIFY(runningSpy.count() == 1);
|
||||
|
||||
// Make sure the server is not running
|
||||
QVERIFY(Engine::instance()->running());
|
||||
|
||||
// Make sure the websocket server is not running
|
||||
QVERIFY(!Engine::instance()->webSocketServer()->running());
|
||||
|
||||
dummyServer.close();
|
||||
@ -226,62 +239,11 @@ void RemoteProxyTests::webserverConnectionBlocked()
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTests::webserverSocketVersion()
|
||||
{
|
||||
// Start the server
|
||||
startServer();
|
||||
|
||||
QUrl serverUrl;
|
||||
serverUrl.setScheme("wss");
|
||||
serverUrl.setHost("localhost");
|
||||
serverUrl.setPort(m_port);
|
||||
|
||||
// Create a websocket with invalid version
|
||||
QWebSocket socket("tests", QWebSocketProtocol::Version8);
|
||||
socket.open(serverUrl);
|
||||
|
||||
// Clean up
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTests::webserverConnection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RemoteProxyTests::sslConfigurations()
|
||||
{
|
||||
// Start the server
|
||||
startServer();
|
||||
|
||||
// Connect to the server (insecure disabled)
|
||||
RemoteProxyConnector *connector = new RemoteProxyConnector(this);
|
||||
connector->setInsecureConnection(false);
|
||||
|
||||
QSignalSpy spyError(connector, &RemoteProxyConnector::errorOccured);
|
||||
connector->connectServer(QHostAddress::LocalHost, m_port);
|
||||
spyError.wait();
|
||||
|
||||
QCOMPARE(connector->error(), RemoteProxyConnector::ErrorSocketError);
|
||||
QCOMPARE(connector->socketError(), QAbstractSocket::SslHandshakeFailedError);
|
||||
QCOMPARE(connector->state(), RemoteProxyConnector::StateDisconnected);
|
||||
|
||||
// Connect to server (insecue enabled)
|
||||
QSignalSpy spyConnected(connector, &RemoteProxyConnector::connected);
|
||||
connector->setInsecureConnection(true);
|
||||
connector->connectServer(QHostAddress::LocalHost, m_port);
|
||||
spyConnected.wait();
|
||||
|
||||
QVERIFY(connector->isConnected());
|
||||
|
||||
// Disconnect and clean up
|
||||
connector->disconnectServer();
|
||||
QVERIFY(!connector->isConnected());
|
||||
|
||||
connector->deleteLater();
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTests::getIntrospect()
|
||||
{
|
||||
// Start the server
|
||||
@ -351,10 +313,10 @@ void RemoteProxyTests::authenticate_data()
|
||||
<< 100 << Authenticator::AuthenticationErrorNoError;
|
||||
|
||||
QTest::newRow("failed") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << "invalid_token_42"
|
||||
<< 100 << Authenticator::AuthenticationErrorAuthenticationFailed;
|
||||
<< 100 << Authenticator::AuthenticationErrorAuthenticationFailed;
|
||||
|
||||
QTest::newRow("not responding") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << "invalid_token_42"
|
||||
<< 200 << Authenticator::AuthenticationErrorAuthenticationServerNotResponding;
|
||||
<< 200 << Authenticator::AuthenticationErrorAuthenticationServerNotResponding;
|
||||
|
||||
QTest::newRow("aborted") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << "invalid_token_42"
|
||||
<< 100 << Authenticator::AuthenticationErrorAborted;
|
||||
@ -393,6 +355,63 @@ void RemoteProxyTests::authenticate()
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTests::clientConnection()
|
||||
{
|
||||
// Start the server
|
||||
startServer();
|
||||
|
||||
// Connect to the server (insecure disabled)
|
||||
RemoteProxyConnection *connectorOne = new RemoteProxyConnection(RemoteProxyConnection::ConnectionTypeWebSocket, this);
|
||||
connectorOne->setInsecureConnection(true);
|
||||
|
||||
// Connect to server (insecue enabled for testing)
|
||||
QSignalSpy spyConnected(connectorOne, &RemoteProxyConnection::connected);
|
||||
connectorOne->connectServer(QHostAddress::LocalHost, m_port);
|
||||
spyConnected.wait();
|
||||
//QVERIFY(connectorOne->isConnected());
|
||||
|
||||
// Disconnect and clean up
|
||||
QSignalSpy spyDisconnected(connectorOne, &RemoteProxyConnection::disconnected);
|
||||
connectorOne->disconnectServer();
|
||||
spyDisconnected.wait();
|
||||
QVERIFY(!connectorOne->isConnected());
|
||||
|
||||
connectorOne->deleteLater();
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTests::sslConfigurations()
|
||||
{
|
||||
// // Start the server
|
||||
// startServer();
|
||||
|
||||
// // Connect to the server (insecure disabled)
|
||||
// RemoteProxyConnection *connector = new RemoteProxyConnection(RemoteProxyConnection::ConnectionTypeWebSocket, this);
|
||||
// connector->setInsecureConnection(false);
|
||||
|
||||
// QSignalSpy spyError(connector, &RemoteProxyConnection::errorOccured);
|
||||
// connector->connectServer(QHostAddress::LocalHost, m_port);
|
||||
// spyError.wait();
|
||||
|
||||
// QCOMPARE(connector->error(), RemoteProxyConnection::ErrorSslError);
|
||||
// QCOMPARE(connector->state(), RemoteProxyConnection::StateDisconnected);
|
||||
|
||||
// // Connect to server (insecue enabled)
|
||||
// QSignalSpy spyConnected(connector, &RemoteProxyConnection::connected);
|
||||
// connector->setInsecureConnection(true);
|
||||
// connector->connectServer(QHostAddress::LocalHost, m_port);
|
||||
// spyConnected.wait();
|
||||
|
||||
// QVERIFY(connector->isConnected());
|
||||
|
||||
// // Disconnect and clean up
|
||||
// connector->disconnectServer();
|
||||
// QVERIFY(!connector->isConnected());
|
||||
|
||||
// connector->deleteLater();
|
||||
// stopServer();
|
||||
}
|
||||
|
||||
void RemoteProxyTests::timeout()
|
||||
{
|
||||
// Start the server
|
||||
@ -418,5 +437,4 @@ void RemoteProxyTests::timeout()
|
||||
stopServer();
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(RemoteProxyTests)
|
||||
|
||||
@ -12,8 +12,10 @@
|
||||
|
||||
#include "jsonrpc/jsontypes.h"
|
||||
#include "mockauthenticator.h"
|
||||
#include "remoteproxyconnection.h"
|
||||
|
||||
using namespace remoteproxy;
|
||||
using namespace remoteproxyclient;
|
||||
|
||||
class RemoteProxyTests : public QObject
|
||||
{
|
||||
@ -48,9 +50,7 @@ private slots:
|
||||
|
||||
// WebSocket connection
|
||||
void webserverConnectionBlocked();
|
||||
void webserverSocketVersion();
|
||||
void webserverConnection();
|
||||
void sslConfigurations();
|
||||
|
||||
// Api
|
||||
void getIntrospect();
|
||||
@ -62,6 +62,10 @@ private slots:
|
||||
void authenticate_data();
|
||||
void authenticate();
|
||||
|
||||
// Client lib
|
||||
void clientConnection();
|
||||
void sslConfigurations();
|
||||
|
||||
void timeout();
|
||||
|
||||
public slots:
|
||||
|
||||
Reference in New Issue
Block a user