Merge PR #183: Http commander: Add http server
commit
2519babb98
|
|
@ -1,3 +1,11 @@
|
|||
# HTTP commander
|
||||
|
||||
The HTTP commander allows you to execute HTTP methods on a HTTP server and is ment as a generic way to interact with a server.
|
||||
The HTTP commander allows you to send and reqceive generiv HTTP requests.
|
||||
|
||||
## HTTP Request
|
||||
|
||||
Send simple HTTP GET/POST/PUT/DELETE requests. URL and port will be defined during setup, body and HTTP method can be set within every request.
|
||||
|
||||
## HTTP Server
|
||||
|
||||
Simple HTTP Server to receive GET/POST/PUT/DELETE requests. Emits an event including HTTP request type, Url and body as parameter.
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "devicepluginhttpcommander.h"
|
||||
#include "network/networkaccessmanager.h"
|
||||
#include "plugininfo.h"
|
||||
#include <QNetworkInterface>
|
||||
|
||||
DevicePluginHttpCommander::DevicePluginHttpCommander()
|
||||
{
|
||||
|
|
@ -34,24 +35,10 @@ void DevicePluginHttpCommander::setupDevice(DeviceSetupInfo *info)
|
|||
Device *device = info->device();
|
||||
qDebug(dcHttpCommander()) << "Setup device" << device->name() << device->params();
|
||||
|
||||
if(!m_pluginTimer) {
|
||||
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(60);
|
||||
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginHttpCommander::onPluginTimer);
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == httpGetCommanderDeviceClassId) {
|
||||
QUrl url = device->paramValue(httpGetCommanderDeviceUrlParamTypeId).toUrl();
|
||||
if (!url.isValid()) {
|
||||
qDebug(dcHttpCommander()) << "Given URL is not valid";
|
||||
//: Error setting up device
|
||||
return info->finish(Device::DeviceErrorInvalidParameter, QT_TR_NOOP("The given url is not valid."));
|
||||
}
|
||||
if (device->deviceClassId() == httpRequestDeviceClassId) {
|
||||
QUrl url = device->paramValue(httpRequestDeviceUrlParamTypeId).toUrl();
|
||||
|
||||
return info->finish(Device::DeviceErrorNoError);
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == httpPutCommanderDeviceClassId) {
|
||||
QUrl url = device->paramValue(httpPutCommanderDeviceUrlParamTypeId).toUrl();
|
||||
if (!url.isValid()) {
|
||||
qDebug(dcHttpCommander()) << "Given URL is not valid";
|
||||
//: Error setting up device
|
||||
|
|
@ -60,175 +47,82 @@ void DevicePluginHttpCommander::setupDevice(DeviceSetupInfo *info)
|
|||
return info->finish(Device::DeviceErrorNoError);
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == httpPostCommanderDeviceClassId) {
|
||||
QUrl url = device->paramValue(httpPostCommanderDeviceUrlParamTypeId).toUrl();
|
||||
if (!url.isValid()) {
|
||||
qDebug(dcHttpCommander()) << "Given URL is not valid";
|
||||
//: Error setting up device
|
||||
return info->finish(Device::DeviceErrorInvalidParameter, QT_TR_NOOP("The given url is not valid."));
|
||||
}
|
||||
if (device->deviceClassId() == httpServerDeviceClassId) {
|
||||
quint16 port = static_cast<uint16_t>(device->paramValue(httpServerDevicePortParamTypeId).toUInt());
|
||||
HttpSimpleServer *httpSimpleServer = new HttpSimpleServer(port, this);
|
||||
connect(httpSimpleServer, &HttpSimpleServer::requestReceived, this, &DevicePluginHttpCommander::onHttpSimpleServerRequestReceived);
|
||||
m_httpSimpleServer.insert(device, httpSimpleServer);
|
||||
|
||||
return info->finish(Device::DeviceErrorNoError);
|
||||
}
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginHttpCommander::postSetupDevice(Device *device)
|
||||
{
|
||||
if (device->deviceClassId() == httpGetCommanderDeviceClassId) {
|
||||
makeGetCall(device);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginHttpCommander::executeAction(DeviceActionInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
Action action = info->action();
|
||||
|
||||
if (device->deviceClassId() == httpPostCommanderDeviceClassId) {
|
||||
if (device->deviceClassId() == httpRequestDeviceClassId) {
|
||||
|
||||
if (action.actionTypeId() == httpPostCommanderPostActionTypeId) {
|
||||
QUrl url = device->paramValue(httpPostCommanderDeviceUrlParamTypeId).toUrl();
|
||||
url.setPort(device->paramValue(httpPostCommanderDevicePortParamTypeId).toInt());
|
||||
QByteArray payload = action.param(httpPostCommanderPostActionDataParamTypeId).value().toByteArray();
|
||||
if (action.actionTypeId() == httpRequestRequestActionTypeId) {
|
||||
QUrl url = device->paramValue(httpRequestDeviceUrlParamTypeId).toUrl();
|
||||
url.setPort(device->paramValue(httpRequestDevicePortParamTypeId).toInt());
|
||||
QString method = action.param(httpRequestRequestActionMethodParamTypeId).value().toString();
|
||||
QByteArray payload = action.param(httpRequestRequestActionBodyParamTypeId).value().toByteArray();
|
||||
|
||||
QNetworkReply *reply = hardwareManager()->networkManager()->post(QNetworkRequest(url), payload);
|
||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginHttpCommander::onPostRequestFinished);
|
||||
QNetworkReply *reply;
|
||||
if (method == "GET") {
|
||||
reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
|
||||
} else if (method == "POST") {
|
||||
reply = hardwareManager()->networkManager()->post(QNetworkRequest(url), payload);
|
||||
} else if (method == "PUT") {
|
||||
reply = hardwareManager()->networkManager()->put(QNetworkRequest(url), payload);
|
||||
} else if (method == "DELETE") {
|
||||
reply = hardwareManager()->networkManager()->deleteResource(QNetworkRequest(url));
|
||||
}
|
||||
connect(reply, &QNetworkReply::finished, this, [device, reply, this](){
|
||||
|
||||
m_httpRequests.insert(reply, device);
|
||||
qDebug(dcHttpCommander()) << "POST reply finished";
|
||||
QByteArray data = reply->readAll();
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
|
||||
device->setStateValue(httpRequestResponseStateTypeId, data);
|
||||
device->setStateValue(httpRequestStatusStateTypeId, status);
|
||||
|
||||
// Check HTTP status code
|
||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcHttpCommander()) << "Request error:" << status << reply->errorString();
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
|
||||
return info->finish(Device::DeviceErrorNoError);
|
||||
}
|
||||
return info->finish(Device::DeviceErrorActionTypeNotFound);
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == httpPutCommanderDeviceClassId) {
|
||||
|
||||
// check if this is the "press" action
|
||||
if (action.actionTypeId() == httpPutCommanderPutActionTypeId) {
|
||||
QUrl url = device->paramValue(httpPutCommanderDeviceUrlParamTypeId).toUrl();
|
||||
url.setPort(device->paramValue(httpPutCommanderDevicePortParamTypeId).toInt());
|
||||
QByteArray payload = action.param(httpPutCommanderPutActionDataParamTypeId).value().toByteArray();
|
||||
|
||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(QNetworkRequest(url), payload);
|
||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginHttpCommander::onPutRequestFinished);
|
||||
|
||||
m_httpRequests.insert(reply, device);
|
||||
|
||||
return info->finish(Device::DeviceErrorNoError);
|
||||
}
|
||||
}
|
||||
return info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||
}
|
||||
|
||||
void DevicePluginHttpCommander::makeGetCall(Device *device)
|
||||
void DevicePluginHttpCommander::onHttpSimpleServerRequestReceived(const QString &type, const QString &path, const QString &body)
|
||||
{
|
||||
QUrl url = device->paramValue(httpGetCommanderDeviceUrlParamTypeId).toUrl();
|
||||
url.setPort(device->paramValue(httpGetCommanderDevicePortParamTypeId).toInt());
|
||||
QNetworkRequest request;
|
||||
request.setUrl(url);
|
||||
request.setRawHeader("User-Agent", "nymea 1.0");
|
||||
|
||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
|
||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginHttpCommander::onGetRequestFinished);
|
||||
|
||||
m_httpRequests.insert(reply, device);
|
||||
}
|
||||
|
||||
void DevicePluginHttpCommander::onPluginTimer()
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
if (device->deviceClassId() == httpGetCommanderDeviceClassId) {
|
||||
makeGetCall(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginHttpCommander::onGetRequestFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
qDebug(dcHttpCommander()) << "GET reply finished";
|
||||
QByteArray data = reply->readAll();
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
|
||||
if (!m_httpRequests.contains(reply)) {
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
Device *device = m_httpRequests.take(reply);
|
||||
device->setStateValue(httpGetCommanderResponseStateTypeId, data);
|
||||
device->setStateValue(httpGetCommanderStatusStateTypeId, true);
|
||||
|
||||
// Check HTTP status code
|
||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcHttpCommander()) << "Request error:" << status << reply->errorString();
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void DevicePluginHttpCommander::onPostRequestFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
qDebug(dcHttpCommander()) << "POST reply finished";
|
||||
QByteArray data = reply->readAll();
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
|
||||
if (!m_httpRequests.contains(reply)) {
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
Device *device = m_httpRequests.take(reply);
|
||||
device->setStateValue(httpPostCommanderResponseStateTypeId, data);
|
||||
device->setStateValue(httpPostCommanderStatusStateTypeId, status);
|
||||
|
||||
// Check HTTP status code
|
||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcHttpCommander()) << "Request error:" << status << reply->errorString();
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void DevicePluginHttpCommander::onPutRequestFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
qDebug(dcHttpCommander()) << "PUT reply finished";
|
||||
QByteArray data = reply->readAll();
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
|
||||
if (!m_httpRequests.contains(reply)) {
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
Device *device = m_httpRequests.take(reply);
|
||||
device->setStateValue(httpPutCommanderResponseStateTypeId, data);
|
||||
device->setStateValue(httpPutCommanderStatusStateTypeId, status);
|
||||
|
||||
// Check HTTP status code
|
||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcHttpCommander()) << "Request error:" << status << reply->errorString();
|
||||
}
|
||||
reply->deleteLater();
|
||||
//qCDebug(dcHttpCommander()) << "Request recieved" << type << body;
|
||||
HttpSimpleServer *httpServer = static_cast<HttpSimpleServer *>(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)
|
||||
{
|
||||
if ((device->deviceClassId() == httpPostCommanderDeviceClassId) ||
|
||||
(device->deviceClassId() == httpPutCommanderDeviceClassId) ||
|
||||
(device->deviceClassId() == httpGetCommanderDeviceClassId)) {
|
||||
|
||||
while (m_httpRequests.values().contains(device)) {
|
||||
QNetworkReply *reply = m_httpRequests.key(device);
|
||||
m_httpRequests.remove(reply);
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
if (myDevices().empty()) {
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
|
||||
if (device->deviceClassId() == httpServerDeviceClassId) {
|
||||
HttpSimpleServer* httpSimpleServer= m_httpSimpleServer.take(device);
|
||||
httpSimpleServer->deleteLater();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "devices/deviceplugin.h"
|
||||
#include "plugintimer.h"
|
||||
#include "httpsimpleserver.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QHostInfo>
|
||||
|
|
@ -38,25 +39,18 @@ class DevicePluginHttpCommander : public DevicePlugin
|
|||
Q_INTERFACES(DevicePlugin)
|
||||
|
||||
public:
|
||||
|
||||
explicit DevicePluginHttpCommander();
|
||||
|
||||
void setupDevice(DeviceSetupInfo *info) override;
|
||||
void postSetupDevice(Device *device) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
void executeAction(DeviceActionInfo *info) override;
|
||||
|
||||
private:
|
||||
PluginTimer *m_pluginTimer = nullptr;
|
||||
QHash<QNetworkReply *, Device *> m_httpRequests;
|
||||
|
||||
void makeGetCall(Device *device);
|
||||
QHash<Device *, HttpSimpleServer *> m_httpSimpleServer;
|
||||
|
||||
private slots:
|
||||
void onPluginTimer();
|
||||
|
||||
void onGetRequestFinished();
|
||||
void onPostRequestFinished();
|
||||
void onPutRequestFinished();
|
||||
void onHttpSimpleServerRequestReceived(const QString &type, const QString &path, const QString &body);
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINHTTPCOMMANDER_H
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
"deviceClasses": [
|
||||
{
|
||||
"id": "b101abdf-86fd-4d2e-a657-ee76044235bd",
|
||||
"name": "httpPostCommander",
|
||||
"displayName": "HTTP post",
|
||||
"name": "httpRequest",
|
||||
"displayName": "HTTP Request",
|
||||
"createMethods": ["user"],
|
||||
"interfaces": [ ],
|
||||
"paramTypes": [
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
"displayName": "Address",
|
||||
"type": "QString",
|
||||
"inputType": "None",
|
||||
"defaultValue": "https://httpbin.org/post"
|
||||
"defaultValue": "https://httpbin.org/get"
|
||||
},
|
||||
{
|
||||
"id": "37830ea8-2249-46e6-aaca-12164928a81a",
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
{
|
||||
"id": "69f32ec8-114d-43f4-9241-1f6a57261f32",
|
||||
"name": "response",
|
||||
"displayName": "response",
|
||||
"displayName": "Response",
|
||||
"displayNameEvent": "Response received",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
|
|
@ -52,119 +52,85 @@
|
|||
"actionTypes": [
|
||||
{
|
||||
"id": "5a97ca56-b334-411b-adba-116496ffe83d",
|
||||
"name": "post",
|
||||
"displayName": "Post data",
|
||||
"name": "request",
|
||||
"displayName": "Request",
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "363119a3-c02c-4ed5-a915-11706198f3eb",
|
||||
"name": "data",
|
||||
"displayName": "Data",
|
||||
"name": "body",
|
||||
"displayName": "Body",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "9fc9948a-5995-48d2-94ce-3c1fd26f6181",
|
||||
"name": "method",
|
||||
"displayName": "Method",
|
||||
"type": "QString",
|
||||
"defaultValue": "GET",
|
||||
"allowedValues": [
|
||||
"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "05bf65f5-ff13-43e3-b6ae-77019e79d8a1",
|
||||
"name": "httpPutCommander",
|
||||
"displayName": "HTTP put",
|
||||
|
||||
"id": "56efcdc3-c769-4e25-8a5b-c0affe68252a",
|
||||
"name": "httpServer",
|
||||
"displayName": "HTTP Server",
|
||||
"createMethods": ["user"],
|
||||
"interfaces": [ ],
|
||||
"interfaces": [ "inputtrigger" ],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "1a3fcb23-931b-4ba1-b134-c49b656c76f7",
|
||||
"name": "url",
|
||||
"displayName": "Address",
|
||||
"type": "QString",
|
||||
"inputType": "None",
|
||||
"defaultValue": "https://httpbin.org/put"
|
||||
},
|
||||
{
|
||||
"id": "db994349-1105-4ce5-b6fe-6fd38fbc436a",
|
||||
"id": "438117cb-c2de-49d0-9f91-5988c17225f8",
|
||||
"name": "port",
|
||||
"displayName": "Port",
|
||||
"type": "int",
|
||||
"defaultValue": "443"
|
||||
"defaultValue": "8000"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
"eventTypes": [
|
||||
{
|
||||
"id": "4959c589-4550-479f-ae11-c4d1097ce3d5",
|
||||
"name": "status",
|
||||
"displayName": "Status code",
|
||||
"displayNameEvent": "Status code changed",
|
||||
"type": "int",
|
||||
"defaultValue": 200
|
||||
},
|
||||
{
|
||||
"id": "22f8be58-be2b-4dba-b1ca-6c2a16dec533",
|
||||
"name": "response",
|
||||
"displayName": "Response",
|
||||
"displayNameEvent": "Response received",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "a9f165dc-cdf1-48f0-b4b6-7c24373cb77c",
|
||||
"name": "put",
|
||||
"displayName": "put",
|
||||
"id": "86f794c6-31ad-40a8-928f-4b8802506ce1",
|
||||
"name": "triggered",
|
||||
"displayName": "Http request received",
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "7742d445-8fc1-4b20-87f2-1bb35929fce1",
|
||||
"name": "data",
|
||||
"displayName": "Data",
|
||||
"id": "dd3c6033-0483-4237-ac15-7a64ae4dd29c",
|
||||
"name": "requestType",
|
||||
"displayName": "Request type",
|
||||
"type": "QString",
|
||||
"allowedValues": [
|
||||
"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE"
|
||||
],
|
||||
"defaultValue": "GET"
|
||||
},
|
||||
{
|
||||
"id": "c936810e-a73d-424f-8981-48baf0a440bb",
|
||||
"name": "body",
|
||||
"displayName": "Body",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
} ,
|
||||
{
|
||||
"id": "0d4dc8f0-df0d-4fb0-b771-b62dee28a625",
|
||||
"name": "path",
|
||||
"displayName": "Path",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "8f3f6dde-9db3-4237-800b-bb7f804098c9",
|
||||
"name": "httpGetCommander",
|
||||
"displayName": "HTTP get",
|
||||
"createMethods": ["user"],
|
||||
"interfaces": [ ],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "477b544b-b631-4526-a4ef-c712ff5f955d",
|
||||
"name": "url",
|
||||
"displayName": "URL or IPv4 Address",
|
||||
"type": "QString",
|
||||
"inputType": "None",
|
||||
"defaultValue": "https://httpbin.org/get"
|
||||
},
|
||||
{
|
||||
"id": "bee8b151-815a-4159-9d8a-42b76e99b42c",
|
||||
"name": "port",
|
||||
"displayName": "Port",
|
||||
"type": "int",
|
||||
"defaultValue": "443"
|
||||
}
|
||||
],
|
||||
"stateTypes":[
|
||||
{
|
||||
"id": "8a60ffe0-e39a-43ec-be8c-c1ed1886aa41",
|
||||
"name": "status",
|
||||
"displayName": "Status code",
|
||||
"displayNameEvent": "Status code changed",
|
||||
"type": "int",
|
||||
"defaultValue": 200
|
||||
},
|
||||
{
|
||||
"id": "d81f0644-b94e-48ed-ae48-1b8ff6cebc0c",
|
||||
"name": "response",
|
||||
"displayName": "Response",
|
||||
"type": "QString",
|
||||
"defaultValue": "",
|
||||
"displayNameEvent": "Response data received"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ TARGET = $$qtLibraryTarget(nymea_devicepluginhttpcommander)
|
|||
|
||||
SOURCES += \
|
||||
devicepluginhttpcommander.cpp \
|
||||
httpsimpleserver.cpp
|
||||
|
||||
HEADERS += \
|
||||
devicepluginhttpcommander.h \
|
||||
httpsimpleserver.h
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "httpsimpleserver.h"
|
||||
|
||||
#include "types/statetype.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include <QUrlQuery>
|
||||
#include <QRegExp>
|
||||
#include <QStringList>
|
||||
|
||||
HttpSimpleServer::HttpSimpleServer(quint16 port, QObject *parent):
|
||||
QTcpServer(parent)
|
||||
{
|
||||
listen(QHostAddress::Any, port);
|
||||
}
|
||||
|
||||
HttpSimpleServer::~HttpSimpleServer()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void HttpSimpleServer::incomingConnection(qintptr socket)
|
||||
{
|
||||
// When a new client connects, the server constructs a QTcpSocket and all
|
||||
// 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* tcpSocket = new QTcpSocket(this);
|
||||
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readClient()));
|
||||
connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(discardClient()));
|
||||
tcpSocket->setSocketDescriptor(socket);
|
||||
|
||||
}
|
||||
|
||||
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* tcpSocket = static_cast<QTcpSocket*>(sender());
|
||||
if (tcpSocket->canReadLine()) {
|
||||
|
||||
QByteArray data = tcpSocket->readAll();
|
||||
QStringList tokens = QString(data).split(QRegExp("[ \r\n][ \r\n]*"));
|
||||
qCDebug(dcHttpCommander()) << "Http Request, type" << tokens[0] << "path" << tokens[1] << "body" << tokens.last();
|
||||
|
||||
if ((tokens[0] == "GET") ||
|
||||
(tokens[0] == "PUT") ||
|
||||
(tokens[0] == "POST") ||
|
||||
(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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HttpSimpleServer::discardClient()
|
||||
{
|
||||
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
|
||||
socket->deleteLater();
|
||||
}
|
||||
|
||||
QString HttpSimpleServer::generateHeader()
|
||||
{
|
||||
QString contentHeader(
|
||||
"HTTP/1.0 200 Ok\r\n"
|
||||
"Content-Type: text/html; charset=\"utf-8\"\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
return contentHeader;
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
|
||||
* Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef HTTPSIMPLESERVER1_H
|
||||
#define HTTPSIMPLESERVER1_H
|
||||
|
||||
#include "typeutils.h"
|
||||
|
||||
#include <QTcpServer>
|
||||
#include <QUuid>
|
||||
#include <QDateTime>
|
||||
#include <QUrl>
|
||||
|
||||
class Device;
|
||||
class DevicePlugin;
|
||||
|
||||
class HttpSimpleServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
HttpSimpleServer(quint16 port, QObject* parent = nullptr);
|
||||
~HttpSimpleServer() override;
|
||||
void incomingConnection(qintptr socket) override;
|
||||
|
||||
signals:
|
||||
void disappear();
|
||||
void reconfigureAutodevice();
|
||||
//void getRequestReceied(QUrl url);
|
||||
|
||||
void requestReceived(const QString &type, const QString &path, const QString &body);
|
||||
|
||||
private slots:
|
||||
void readClient();
|
||||
void discardClient();
|
||||
|
||||
private:
|
||||
QString generateHeader();
|
||||
|
||||
};
|
||||
|
||||
#endif // HttpSimpleServer_H
|
||||
|
|
@ -13,64 +13,19 @@
|
|||
<name>HttpCommander</name>
|
||||
<message>
|
||||
<source>Address</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpPutCommander, Type: device, ID: {1a3fcb23-931b-4ba1-b134-c49b656c76f7})
|
||||
----------
|
||||
The name of the ParamType (DeviceClass: httpPostCommander, Type: device, ID: {020f672e-cc9a-4b74-92dd-a92a93ab1d23})</extracomment>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpRequest, Type: device, ID: {020f672e-cc9a-4b74-92dd-a92a93ab1d23})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Port</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpGetCommander, Type: device, ID: {bee8b151-815a-4159-9d8a-42b76e99b42c})
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpServer, Type: device, ID: {438117cb-c2de-49d0-9f91-5988c17225f8})
|
||||
----------
|
||||
The name of the ParamType (DeviceClass: httpPutCommander, Type: device, ID: {db994349-1105-4ce5-b6fe-6fd38fbc436a})
|
||||
----------
|
||||
The name of the ParamType (DeviceClass: httpPostCommander, Type: device, ID: {37830ea8-2249-46e6-aaca-12164928a81a})</extracomment>
|
||||
The name of the ParamType (DeviceClass: httpRequest, Type: device, ID: {37830ea8-2249-46e6-aaca-12164928a81a})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Response received</source>
|
||||
<extracomment>The name of the EventType ({22f8be58-be2b-4dba-b1ca-6c2a16dec533}) of DeviceClass httpPutCommander
|
||||
----------
|
||||
The name of the EventType ({69f32ec8-114d-43f4-9241-1f6a57261f32}) of DeviceClass httpPostCommander</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>response</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpPostCommander, EventType: response, ID: {69f32ec8-114d-43f4-9241-1f6a57261f32})
|
||||
----------
|
||||
The name of the StateType ({69f32ec8-114d-43f4-9241-1f6a57261f32}) of DeviceClass httpPostCommander</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Post data</source>
|
||||
<extracomment>The name of the ActionType ({5a97ca56-b334-411b-adba-116496ffe83d}) of DeviceClass httpPostCommander</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Data</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpPutCommander, ActionType: put, ID: {7742d445-8fc1-4b20-87f2-1bb35929fce1})
|
||||
----------
|
||||
The name of the ParamType (DeviceClass: httpPostCommander, ActionType: post, ID: {363119a3-c02c-4ed5-a915-11706198f3eb})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>put</source>
|
||||
<extracomment>The name of the ActionType ({a9f165dc-cdf1-48f0-b4b6-7c24373cb77c}) of DeviceClass httpPutCommander</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HTTP get</source>
|
||||
<extracomment>The name of the DeviceClass ({8f3f6dde-9db3-4237-800b-bb7f804098c9})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>URL or IPv4 Address</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpGetCommander, Type: device, ID: {477b544b-b631-4526-a4ef-c712ff5f955d})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Response data received</source>
|
||||
<extracomment>The name of the EventType ({d81f0644-b94e-48ed-ae48-1b8ff6cebc0c}) of DeviceClass httpGetCommander</extracomment>
|
||||
<extracomment>The name of the EventType ({69f32ec8-114d-43f4-9241-1f6a57261f32}) of DeviceClass httpRequest</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
@ -80,13 +35,9 @@ The name of the ParamType (DeviceClass: httpPostCommander, ActionType: post, ID:
|
|||
</message>
|
||||
<message>
|
||||
<source>Response</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpGetCommander, EventType: response, ID: {d81f0644-b94e-48ed-ae48-1b8ff6cebc0c})
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpRequest, EventType: response, ID: {69f32ec8-114d-43f4-9241-1f6a57261f32})
|
||||
----------
|
||||
The name of the StateType ({d81f0644-b94e-48ed-ae48-1b8ff6cebc0c}) of DeviceClass httpGetCommander
|
||||
----------
|
||||
The name of the ParamType (DeviceClass: httpPutCommander, EventType: response, ID: {22f8be58-be2b-4dba-b1ca-6c2a16dec533})
|
||||
----------
|
||||
The name of the StateType ({22f8be58-be2b-4dba-b1ca-6c2a16dec533}) of DeviceClass httpPutCommander</extracomment>
|
||||
The name of the StateType ({69f32ec8-114d-43f4-9241-1f6a57261f32}) of DeviceClass httpRequest</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
@ -94,38 +45,58 @@ The name of the StateType ({22f8be58-be2b-4dba-b1ca-6c2a16dec533}) of DeviceClas
|
|||
<extracomment>The name of the vendor ({2062d64d-3232-433c-88bc-0d33c0ba2ba6})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HTTP post</source>
|
||||
<extracomment>The name of the DeviceClass ({b101abdf-86fd-4d2e-a657-ee76044235bd})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Status code changed</source>
|
||||
<extracomment>The name of the EventType ({8a60ffe0-e39a-43ec-be8c-c1ed1886aa41}) of DeviceClass httpGetCommander
|
||||
----------
|
||||
The name of the EventType ({4959c589-4550-479f-ae11-c4d1097ce3d5}) of DeviceClass httpPutCommander
|
||||
----------
|
||||
The name of the EventType ({8daac0e7-4c2f-4cdf-b528-02cfe04c6b39}) of DeviceClass httpPostCommander</extracomment>
|
||||
<extracomment>The name of the EventType ({8daac0e7-4c2f-4cdf-b528-02cfe04c6b39}) of DeviceClass httpRequest</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Status code</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpGetCommander, EventType: status, ID: {8a60ffe0-e39a-43ec-be8c-c1ed1886aa41})
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpRequest, EventType: status, ID: {8daac0e7-4c2f-4cdf-b528-02cfe04c6b39})
|
||||
----------
|
||||
The name of the StateType ({8a60ffe0-e39a-43ec-be8c-c1ed1886aa41}) of DeviceClass httpGetCommander
|
||||
----------
|
||||
The name of the ParamType (DeviceClass: httpPutCommander, EventType: status, ID: {4959c589-4550-479f-ae11-c4d1097ce3d5})
|
||||
----------
|
||||
The name of the StateType ({4959c589-4550-479f-ae11-c4d1097ce3d5}) of DeviceClass httpPutCommander
|
||||
----------
|
||||
The name of the ParamType (DeviceClass: httpPostCommander, EventType: status, ID: {8daac0e7-4c2f-4cdf-b528-02cfe04c6b39})
|
||||
----------
|
||||
The name of the StateType ({8daac0e7-4c2f-4cdf-b528-02cfe04c6b39}) of DeviceClass httpPostCommander</extracomment>
|
||||
The name of the StateType ({8daac0e7-4c2f-4cdf-b528-02cfe04c6b39}) of DeviceClass httpRequest</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HTTP put</source>
|
||||
<extracomment>The name of the DeviceClass ({05bf65f5-ff13-43e3-b6ae-77019e79d8a1})</extracomment>
|
||||
<source>Body</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpServer, EventType: triggered, ID: {c936810e-a73d-424f-8981-48baf0a440bb})
|
||||
----------
|
||||
The name of the ParamType (DeviceClass: httpRequest, ActionType: request, ID: {363119a3-c02c-4ed5-a915-11706198f3eb})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HTTP Server</source>
|
||||
<extracomment>The name of the DeviceClass ({56efcdc3-c769-4e25-8a5b-c0affe68252a})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Http request received</source>
|
||||
<extracomment>The name of the EventType ({86f794c6-31ad-40a8-928f-4b8802506ce1}) of DeviceClass httpServer</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpServer, EventType: triggered, ID: {0d4dc8f0-df0d-4fb0-b771-b62dee28a625})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Request type</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpServer, EventType: triggered, ID: {dd3c6033-0483-4237-ac15-7a64ae4dd29c})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HTTP Request</source>
|
||||
<extracomment>The name of the DeviceClass ({b101abdf-86fd-4d2e-a657-ee76044235bd})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Method</source>
|
||||
<extracomment>The name of the ParamType (DeviceClass: httpRequest, ActionType: request, ID: {9fc9948a-5995-48d2-94ce-3c1fd26f6181})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Request</source>
|
||||
<extracomment>The name of the ActionType ({5a97ca56-b334-411b-adba-116496ffe83d}) of DeviceClass httpRequest</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
|
|
|||
Loading…
Reference in New Issue