From 8a0d30605bb3dceafc097d32d430297ad046b96b Mon Sep 17 00:00:00 2001 From: Boernsman Date: Sun, 10 Nov 2019 22:54:43 +0100 Subject: [PATCH] first working version --- httpcommander/devicepluginhttpcommander.cpp | 30 ++++++++++- httpcommander/devicepluginhttpcommander.h | 3 ++ httpcommander/devicepluginhttpcommander.json | 10 ++++ httpcommander/httpsimpleserver.cpp | 57 +++++++++++++++----- httpcommander/httpsimpleserver.h | 10 ++-- 5 files changed, 92 insertions(+), 18 deletions(-) diff --git a/httpcommander/devicepluginhttpcommander.cpp b/httpcommander/devicepluginhttpcommander.cpp index 0b4ff8e2..a6548505 100644 --- a/httpcommander/devicepluginhttpcommander.cpp +++ b/httpcommander/devicepluginhttpcommander.cpp @@ -24,6 +24,7 @@ #include "devicepluginhttpcommander.h" #include "network/networkaccessmanager.h" #include "plugininfo.h" +#include DevicePluginHttpCommander::DevicePluginHttpCommander() { @@ -71,9 +72,20 @@ void DevicePluginHttpCommander::setupDevice(DeviceSetupInfo *info) } if (device->deviceClassId() == httpServerDeviceClassId) { - //TODO create a simple server + HttpSimpleServer *httpSimpleServer = new HttpSimpleServer(this); + connect(httpSimpleServer, &HttpSimpleServer::requestReceived, this, &DevicePluginHttpCommander::onHttpSimpleServerRequestReceived); m_httpSimpleServer.insert(device, httpSimpleServer); + + QString interfaces; + foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { + foreach (QNetworkAddressEntry entry, interface.addressEntries()) { + if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && entry.ip().toString() != "127.0.0.1") { + interfaces.append(entry.ip().toString()); + } + } + } + device->setStateValue(httpServerServerAddressStateTypeId, interfaces); return info->finish(Device::DeviceErrorNoError); } info->finish(Device::DeviceErrorNoError); @@ -135,7 +147,7 @@ void DevicePluginHttpCommander::makeGetCall(Device *device) url.setPort(device->paramValue(httpGetCommanderDevicePortParamTypeId).toInt()); QNetworkRequest request; request.setUrl(url); - request.setRawHeader("User-Agent", "nymea 1.0"); + request.setRawHeader("User-Agent", "nymea http commander"); QNetworkReply *reply = hardwareManager()->networkManager()->get(request); connect(reply, &QNetworkReply::finished, this, &DevicePluginHttpCommander::onGetRequestFinished); @@ -221,6 +233,20 @@ void DevicePluginHttpCommander::onPutRequestFinished() reply->deleteLater(); } +void DevicePluginHttpCommander::onHttpSimpleServerRequestReceived(const QString &type, const QString &path, const QString &body) +{ + //qCDebug(dcHttpCommander()) << "Request recieved" << type << body; + HttpSimpleServer *httpServer = static_cast(sender()); + Device *device = m_httpSimpleServer.key(httpServer); + Event ev = Event(httpServerTriggeredEventTypeId, device->id()); + ParamList params; + params.append(Param(httpServerTriggeredEventRequestTypeParamTypeId, type)); + params.append(Param(httpServerTriggeredEventPathParamTypeId, path)); + params.append(Param(httpServerTriggeredEventBodyParamTypeId, body)); + ev.setParams(params); + emit emitEvent(ev); +} + void DevicePluginHttpCommander::deviceRemoved(Device *device) { diff --git a/httpcommander/devicepluginhttpcommander.h b/httpcommander/devicepluginhttpcommander.h index e2c03859..c255a397 100644 --- a/httpcommander/devicepluginhttpcommander.h +++ b/httpcommander/devicepluginhttpcommander.h @@ -40,6 +40,7 @@ class DevicePluginHttpCommander : public DevicePlugin Q_INTERFACES(DevicePlugin) public: + explicit DevicePluginHttpCommander(); void setupDevice(DeviceSetupInfo *info) override; @@ -60,6 +61,8 @@ private slots: void onGetRequestFinished(); void onPostRequestFinished(); void onPutRequestFinished(); + + void onHttpSimpleServerRequestReceived(const QString &type, const QString &path, const QString &body); }; #endif // DEVICEPLUGINHTTPCOMMANDER_H diff --git a/httpcommander/devicepluginhttpcommander.json b/httpcommander/devicepluginhttpcommander.json index 4109174e..ff3830b0 100644 --- a/httpcommander/devicepluginhttpcommander.json +++ b/httpcommander/devicepluginhttpcommander.json @@ -182,6 +182,16 @@ "defaultValue": "8000" } ], + "stateTypes": [ + { + "id": "f4458008-67f2-4ba1-bbca-e85771a30ddc", + "name": "serverAddress", + "displayName": "Server address", + "displayNameEvent": "Server address changed", + "type": "QString", + "defaultValue": "127.0.0.1" + } + ], "eventTypes": [ { "id": "86f794c6-31ad-40a8-928f-4b8802506ce1", diff --git a/httpcommander/httpsimpleserver.cpp b/httpcommander/httpsimpleserver.cpp index 4ad0d338..a13838d3 100644 --- a/httpcommander/httpsimpleserver.cpp +++ b/httpcommander/httpsimpleserver.cpp @@ -36,11 +36,13 @@ HttpSimpleServer::HttpSimpleServer(QObject *parent): QTcpServer(parent) { + listen(QHostAddress::Any, 7777); } HttpSimpleServer::~HttpSimpleServer() { close(); + } void HttpSimpleServer::incomingConnection(qintptr socket) @@ -49,10 +51,10 @@ void HttpSimpleServer::incomingConnection(qintptr socket) // communication with the client is done over this QTcpSocket. QTcpSocket // works asynchronously, this means that all the communication is done // in the two slots readClient() and discardClient(). - QTcpSocket* s = new QTcpSocket(this); - connect(s, SIGNAL(readyRead()), this, SLOT(readClient())); - connect(s, SIGNAL(disconnected()), this, SLOT(discardClient())); - s->setSocketDescriptor(socket); + QTcpSocket* tcpSocket = new QTcpSocket(this); + connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readClient())); + connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(discardClient())); + tcpSocket->setSocketDescriptor(socket); } @@ -61,27 +63,56 @@ void HttpSimpleServer::readClient() // This slot is called when the client sent data to the server. The // server looks if it was a get request and sends a very simple HTML // document back. - QTcpSocket* socket = static_cast(sender()); - if (socket->canReadLine()) { - QByteArray data = socket->readLine(); + QTcpSocket* tcpSocket = static_cast(sender()); + if (tcpSocket->canReadLine()) { + + QByteArray data = tcpSocket->readAll(); QStringList tokens = QString(data).split(QRegExp("[ \r\n][ \r\n]*")); - QUrl url("http://foo.bar" + tokens[1]); - QUrlQuery query(url); + //QUrl url("http://foo.bar" + tokens[1]); + //QUrlQuery query(url); + qCDebug(dcHttpCommander()) << "Http Request, type" << tokens[0] << "path" << tokens[1] << "body" << tokens.last(); if (tokens[0] == "GET") { - QTextStream os(socket); + QTextStream os(tcpSocket); os.setAutoDetectUnicode(true); os << generateHeader(); - socket->close(); + tcpSocket->close(); - if (socket->state() == QTcpSocket::UnconnectedState) - delete socket; + if (tcpSocket->state() == QTcpSocket::UnconnectedState) + delete tcpSocket; + + emit requestReceived(tokens[0], tokens[1], tokens.last()); } else if (tokens[0] == "PUT") { + QTextStream os(tcpSocket); + os.setAutoDetectUnicode(true); + os << generateHeader(); + tcpSocket->close(); + + if (tcpSocket->state() == QTcpSocket::UnconnectedState) + delete tcpSocket; + + emit requestReceived(tokens[0], tokens[1], tokens.last()); } else if (tokens[0] == "POST") { + QTextStream os(tcpSocket); + os.setAutoDetectUnicode(true); + os << generateHeader(); + tcpSocket->close(); + + if (tcpSocket->state() == QTcpSocket::UnconnectedState) + delete tcpSocket; + emit requestReceived(tokens[0], tokens[1], tokens.last()); } else if (tokens[0] == "DELETE") { + QTextStream os(tcpSocket); + os.setAutoDetectUnicode(true); + os << generateHeader(); + tcpSocket->close(); + if (tcpSocket->state() == QTcpSocket::UnconnectedState) + delete tcpSocket; + + emit requestReceived(tokens[0], tokens[1], tokens.last()); } } } diff --git a/httpcommander/httpsimpleserver.h b/httpcommander/httpsimpleserver.h index 393037cb..ab8c1993 100644 --- a/httpcommander/httpsimpleserver.h +++ b/httpcommander/httpsimpleserver.h @@ -22,14 +22,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef HTTPSIMPLESERVER_H -#define HTTPSIMPLESERVER_H +#ifndef HTTPSIMPLESERVER1_H +#define HTTPSIMPLESERVER1_H #include "typeutils.h" #include #include #include +#include class Device; class DevicePlugin; @@ -38,6 +39,7 @@ class HttpSimpleServer : public QTcpServer { Q_OBJECT public: + HttpSimpleServer(QObject* parent = nullptr); ~HttpSimpleServer() override; void incomingConnection(qintptr socket) override; @@ -45,7 +47,9 @@ public: signals: void disappear(); void reconfigureAutodevice(); - void getRequestReceied(QUrl url); + //void getRequestReceied(QUrl url); + + void requestReceived(const QString &type, const QString &path, const QString &body); private slots: void readClient();