diff --git a/httpcommander/README.md b/httpcommander/README.md index cc6ac9df..fd13a348 100644 --- a/httpcommander/README.md +++ b/httpcommander/README.md @@ -1,7 +1,11 @@ # HTTP commander -## HTTP PUT/POST/GET 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. diff --git a/httpcommander/devicepluginhttpcommander.cpp b/httpcommander/devicepluginhttpcommander.cpp index fbcc5bd5..962598ed 100644 --- a/httpcommander/devicepluginhttpcommander.cpp +++ b/httpcommander/devicepluginhttpcommander.cpp @@ -35,33 +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.")); - } - return info->finish(Device::DeviceErrorNoError); - } + if (device->deviceClassId() == httpRequestDeviceClassId) { + QUrl url = device->paramValue(httpRequestDeviceUrlParamTypeId).toUrl(); - if (device->deviceClassId() == httpPutCommanderDeviceClassId) { - QUrl url = device->paramValue(httpPutCommanderDeviceUrlParamTypeId).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.")); - } - 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 @@ -71,167 +48,62 @@ void DevicePluginHttpCommander::setupDevice(DeviceSetupInfo *info) } if (device->deviceClassId() == httpServerDeviceClassId) { - - HttpSimpleServer *httpSimpleServer = new HttpSimpleServer(this); + quint16 port = static_cast(device->paramValue(httpServerDevicePortParamTypeId).toUInt()); + HttpSimpleServer *httpSimpleServer = new HttpSimpleServer(port, 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); } - -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) -{ - QUrl url = device->paramValue(httpGetCommanderDeviceUrlParamTypeId).toUrl(); - url.setPort(device->paramValue(httpGetCommanderDevicePortParamTypeId).toInt()); - QNetworkRequest request; - request.setUrl(url); - request.setRawHeader("User-Agent", "nymea http commander"); - - 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(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(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(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(); -} - void DevicePluginHttpCommander::onHttpSimpleServerRequestReceived(const QString &type, const QString &path, const QString &body) { //qCDebug(dcHttpCommander()) << "Request recieved" << type << body; @@ -249,18 +121,8 @@ void DevicePluginHttpCommander::onHttpSimpleServerRequestReceived(const QString 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(); } } diff --git a/httpcommander/devicepluginhttpcommander.h b/httpcommander/devicepluginhttpcommander.h index c255a397..68443c5e 100644 --- a/httpcommander/devicepluginhttpcommander.h +++ b/httpcommander/devicepluginhttpcommander.h @@ -27,7 +27,6 @@ #include "devices/deviceplugin.h" #include "plugintimer.h" #include "httpsimpleserver.h" -#include "httprequest.h" #include #include @@ -44,24 +43,13 @@ 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 m_httpSimpleServer; - QHash m_httpRequests; - - void makeGetCall(Device *device); private slots: - void onPluginTimer(); - - void onGetRequestFinished(); - void onPostRequestFinished(); - void onPutRequestFinished(); - void onHttpSimpleServerRequestReceived(const QString &type, const QString &path, const QString &body); }; diff --git a/httpcommander/devicepluginhttpcommander.json b/httpcommander/devicepluginhttpcommander.json index ff3830b0..cf7d42cb 100644 --- a/httpcommander/devicepluginhttpcommander.json +++ b/httpcommander/devicepluginhttpcommander.json @@ -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,120 +52,33 @@ "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": "05bf65f5-ff13-43e3-b6ae-77019e79d8a1", - "name": "httpPutCommander", - "displayName": "HTTP put", - "createMethods": ["user"], - "interfaces": [ ], - "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", - "name": "port", - "displayName": "Port", - "type": "int", - "defaultValue": "443" - } - ], - "stateTypes": [ - { - "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", - "paramTypes": [ + }, { - "id": "7742d445-8fc1-4b20-87f2-1bb35929fce1", - "name": "data", - "displayName": "Data", + "id": "9fc9948a-5995-48d2-94ce-3c1fd26f6181", + "name": "method", + "displayName": "Method", "type": "QString", - "defaultValue": "" + "defaultValue": "GET", + "allowedValues": [ + "GET", + "POST", + "PUT", + "DELETE" + ] } ] } ] }, - { - "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" - } - ] - }, { "id": "56efcdc3-c769-4e25-8a5b-c0affe68252a", @@ -182,16 +95,6 @@ "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/httpcommander.pro b/httpcommander/httpcommander.pro index 24fb6276..2e18b912 100644 --- a/httpcommander/httpcommander.pro +++ b/httpcommander/httpcommander.pro @@ -6,12 +6,10 @@ TARGET = $$qtLibraryTarget(nymea_devicepluginhttpcommander) SOURCES += \ devicepluginhttpcommander.cpp \ - httprequest.cpp \ httpsimpleserver.cpp HEADERS += \ devicepluginhttpcommander.h \ - httprequest.h \ httpsimpleserver.h diff --git a/httpcommander/httprequest.cpp b/httpcommander/httprequest.cpp deleted file mode 100644 index c8c793b5..00000000 --- a/httpcommander/httprequest.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2015 Simon Stürz * - * * - * This file is part of nymea. * - * * - * nymea is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, version 2 of the License. * - * * - * nymea 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 General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with nymea. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -//This file has been copied from the libnymea-core library -//TODO create a http library - -#include "httprequest.h" -#include "loggingcategories.h" - -#include - -/*! Construct an empty \l{HttpRequest}. */ -HttpRequest::HttpRequest() : - m_rawData(QByteArray()), - m_valid(false), - m_isComplete(false) -{ -} - -/*! Construct a \l{HttpRequest} with the given \a rawData. The \a rawData will be parsed in this constructor. You can check - if the data is valid with \l{isValid()}. You can check if the request is complete with \l{isComplete}. - \sa isValid(), isComplete() -*/ -HttpRequest::HttpRequest(QByteArray rawData) : - m_rawData(rawData), - m_valid(false), - m_isComplete(false) -{ - validate(); -} - -/*! Returns the raw header of this request.*/ -QByteArray HttpRequest::rawHeader() const -{ - return m_rawHeader; -} - -/*! Returns the list of raw header as key and value pairs.*/ -QHash HttpRequest::rawHeaderList() const -{ - return m_rawHeaderList; -} - -/*! Returns the \l{RequestMethod} of this request. - \sa RequestMethod -*/ -HttpRequest::RequestMethod HttpRequest::method() const -{ - return m_method; -} - -/*! Returns the method as human readable string.*/ -QString HttpRequest::methodString() const -{ - return m_methodString; -} - -/*! Returns the HTTP version of this \l{HttpRequest}.*/ -QByteArray HttpRequest::httpVersion() const -{ - return m_httpVersion; -} - -/*! Returns the URL of this \l{HttpRequest}.*/ -QUrl HttpRequest::url() const -{ - return m_url; -} - -/*! Returns the URL query of this \l{HttpRequest}.*/ -QUrlQuery HttpRequest::urlQuery() const -{ - return m_urlQuery; -} - -/*! Returns the payload (content) of this \l{HttpRequest}.*/ -QByteArray HttpRequest::payload() const -{ - return m_payload; -} - -/*! Returns true if this \l{HttpRequest} is valid. A HTTP request is valid if the header and the payload were paresed successfully without errors.*/ -bool HttpRequest::isValid() const -{ - return m_valid; -} - -/*! Returns true if this \l{HttpRequest} is complete. A HTTP request is complete if "Content-Length" header value matches the actual payload size. Bigger packages will be sent in multiple TCP packages. */ -bool HttpRequest::isComplete() const -{ - return m_isComplete; -} - -/*! Returns true if this \l{HttpRequest} has a payload.*/ -bool HttpRequest::hasPayload() const -{ - return !m_payload.isEmpty(); -} - -/*! Appends the given \a data to the current raw data of this \l{HttpRequest}. - * This method will be used if a \l{HttpRequest} is not complete yet. - * - * \sa isComplete() -*/ -void HttpRequest::appendData(const QByteArray &data) -{ - m_rawData.append(data); - validate(); -} - -void HttpRequest::validate() -{ - m_isComplete = true; m_valid = false; - - // Parese the HTTP request. The request is invalid, until the end of the parse process. - if (m_rawData.isEmpty()) - return; - - // split the data into header and payload - int headerEndIndex = m_rawData.indexOf("\r\n\r\n"); - if (headerEndIndex < 0) { - qCWarning(dcWebServer()) << "Could not parse end of HTTP header (empty line between header and body):" << m_rawData; - return; - } - - m_rawHeader = m_rawData.left(headerEndIndex); - m_payload = m_rawData.right(m_rawData.length() - headerEndIndex).simplified(); - - // parse status line - QStringList headerLines = QString(m_rawHeader).split(QRegExp("\r\n")); - QString statusLine = headerLines.takeFirst(); - QStringList statusLineTokens = statusLine.split(QRegExp("[ \r\n][ \r\n]*")); - if (statusLineTokens.count() != 3) { - qCWarning(dcWebServer()) << "Could not parse HTTP status line:" << statusLine; - return; - } - - // verify http version - m_httpVersion = statusLineTokens.at(2).toUtf8().simplified(); - if (!m_httpVersion.contains("HTTP")) { - qCWarning(dcWebServer()) << "Unknown HTTP version:" << m_httpVersion; - return; - } - m_methodString = statusLineTokens.at(0).simplified(); - m_method = getRequestMethodType(m_methodString); - - m_url = QUrl("http://example.com" + statusLineTokens.at(1).simplified()); - - if (m_url.hasQuery()) - m_urlQuery = QUrlQuery(m_url.query()); - - // verify header formating - foreach (const QString &line, headerLines) { - if (!line.contains(":")) { - qCWarning(dcWebServer()) << "Invalid HTTP header:" << line; - return; - } - int index = line.indexOf(":"); - QByteArray key = line.left(index).toUtf8().simplified(); - QByteArray value = line.right(line.count() - index - 1).toUtf8().simplified(); - m_rawHeaderList.insert(key, value); - } - - // check User-Agent - if (!m_rawHeaderList.contains("User-Agent")) - qCWarning(dcWebServer()) << "User-Agent header is missing"; - - - // verify content length with actual payload - if (m_rawHeaderList.contains("Content-Length")) { - bool ok = false; - int contentLength = m_rawHeaderList.value("Content-Length").toInt(&ok); - if (!ok) { - qCWarning(dcWebServer()) << "Could not parse Content-Length."; - return; - } - // check if we have all data - if (m_payload.size() < contentLength) { - qCDebug(dcWebServer()) << "Request incomplete:"; - qCDebug(dcWebServer()) << " -> Content-Length:" << contentLength; - qCDebug(dcWebServer()) << " -> Payload size :" << payload().size(); - m_isComplete = false; - return; - } - // check if the content length bigger than header Content-Length - if (m_payload.size() > contentLength) { - qCWarning(dcWebServer()) << "Payload size greater than header Content-Length:"; - qCWarning(dcWebServer()) << " -> Content-Length:" << contentLength; - qCWarning(dcWebServer()) << " -> Payload size :" << payload().size(); - m_isComplete = true; - return; - } - - } - m_valid = true; -} - -HttpRequest::RequestMethod HttpRequest::getRequestMethodType(const QString &methodString) -{ - if (methodString == "GET") { - return RequestMethod::Get; - } else if (methodString == "POST") { - return RequestMethod::Post; - } else if (methodString == "PUT") { - return RequestMethod::Put; - } else if (methodString == "DELETE") { - return RequestMethod::Delete; - } else if (methodString == "OPTIONS") { - return RequestMethod::Options; - } - qCWarning(dcWebServer()) << "Method" << methodString << "will not be handled."; - return RequestMethod::Unhandled; -} - -QDebug operator<<(QDebug debug, const HttpRequest &httpRequest) -{ - debug << "HttpRequest:" << endl; - debug << qUtf8Printable(httpRequest.rawHeader()); - debug << qUtf8Printable(httpRequest.payload()); - return debug; -} diff --git a/httpcommander/httprequest.h b/httpcommander/httprequest.h deleted file mode 100644 index e02f17a9..00000000 --- a/httpcommander/httprequest.h +++ /dev/null @@ -1,85 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2015 Simon Stürz * - * * - * This file is part of nymea. * - * * - * nymea is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, version 2 of the License. * - * * - * nymea 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 General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with nymea. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HTTPREQUEST_H -#define HTTPREQUEST_H - -#include -#include -#include -#include - -class HttpRequest -{ -public: - enum RequestMethod { - Get, - Post, - Put, - Delete, - Options, - Unhandled - }; - - HttpRequest(); - HttpRequest(QByteArray rawData); - - QByteArray rawHeader() const; - QHash rawHeaderList() const; - - RequestMethod method() const; - QString methodString() const; - QByteArray httpVersion() const; - - QUrl url() const; - QUrlQuery urlQuery() const; - - QByteArray payload() const; - - bool isValid() const; - bool isComplete() const; - bool hasPayload() const; - - void appendData(const QByteArray &data); - -private: - QByteArray m_rawData; - QByteArray m_rawHeader; - QHash m_rawHeaderList; - - RequestMethod m_method; - QString m_methodString; - QByteArray m_httpVersion; - - QUrl m_url; - QUrlQuery m_urlQuery; - - QByteArray m_payload; - - bool m_valid; - bool m_isComplete; - - void validate(); - RequestMethod getRequestMethodType(const QString &methodString); -}; - -QDebug operator<< (QDebug debug, const HttpRequest &httpRequest); - -#endif // HTTPREQUEST_H diff --git a/httpcommander/httpsimpleserver.cpp b/httpcommander/httpsimpleserver.cpp index e1d2b012..f17db230 100644 --- a/httpcommander/httpsimpleserver.cpp +++ b/httpcommander/httpsimpleserver.cpp @@ -33,10 +33,10 @@ #include #include -HttpSimpleServer::HttpSimpleServer(QObject *parent): +HttpSimpleServer::HttpSimpleServer(quint16 port, QObject *parent): QTcpServer(parent) { - listen(QHostAddress::Any, 7777); + listen(QHostAddress::Any, port); } HttpSimpleServer::~HttpSimpleServer() diff --git a/httpcommander/httpsimpleserver.h b/httpcommander/httpsimpleserver.h index ab8c1993..b8a808ac 100644 --- a/httpcommander/httpsimpleserver.h +++ b/httpcommander/httpsimpleserver.h @@ -40,7 +40,7 @@ class HttpSimpleServer : public QTcpServer Q_OBJECT public: - HttpSimpleServer(QObject* parent = nullptr); + HttpSimpleServer(quint16 port, QObject* parent = nullptr); ~HttpSimpleServer() override; void incomingConnection(qintptr socket) override; diff --git a/httpcommander/translations/4e62670c-6268-4487-8dff-cccca498731a-en_US.ts b/httpcommander/translations/4e62670c-6268-4487-8dff-cccca498731a-en_US.ts index 73b3610c..3dbb4bd8 100644 --- a/httpcommander/translations/4e62670c-6268-4487-8dff-cccca498731a-en_US.ts +++ b/httpcommander/translations/4e62670c-6268-4487-8dff-cccca498731a-en_US.ts @@ -13,66 +13,19 @@ HttpCommander Address - 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}) + The name of the ParamType (DeviceClass: httpRequest, Type: device, ID: {020f672e-cc9a-4b74-92dd-a92a93ab1d23}) Port The name of the ParamType (DeviceClass: httpServer, Type: device, ID: {438117cb-c2de-49d0-9f91-5988c17225f8}) ---------- -The name of the ParamType (DeviceClass: httpGetCommander, Type: device, ID: {bee8b151-815a-4159-9d8a-42b76e99b42c}) ----------- -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}) +The name of the ParamType (DeviceClass: httpRequest, Type: device, ID: {37830ea8-2249-46e6-aaca-12164928a81a}) Response received - 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 - - - - response - 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 - - - - Post data - The name of the ActionType ({5a97ca56-b334-411b-adba-116496ffe83d}) of DeviceClass httpPostCommander - - - - Data - 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}) - - - - put - The name of the ActionType ({a9f165dc-cdf1-48f0-b4b6-7c24373cb77c}) of DeviceClass httpPutCommander - - - - HTTP get - The name of the DeviceClass ({8f3f6dde-9db3-4237-800b-bb7f804098c9}) - - - - URL or IPv4 Address - The name of the ParamType (DeviceClass: httpGetCommander, Type: device, ID: {477b544b-b631-4526-a4ef-c712ff5f955d}) - - - - Response data received - The name of the EventType ({d81f0644-b94e-48ed-ae48-1b8ff6cebc0c}) of DeviceClass httpGetCommander + The name of the EventType ({69f32ec8-114d-43f4-9241-1f6a57261f32}) of DeviceClass httpRequest @@ -82,13 +35,9 @@ The name of the ParamType (DeviceClass: httpPostCommander, ActionType: post, ID: Response - The name of the ParamType (DeviceClass: httpGetCommander, EventType: response, ID: {d81f0644-b94e-48ed-ae48-1b8ff6cebc0c}) + 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 +The name of the StateType ({69f32ec8-114d-43f4-9241-1f6a57261f32}) of DeviceClass httpRequest @@ -96,43 +45,23 @@ The name of the StateType ({22f8be58-be2b-4dba-b1ca-6c2a16dec533}) of DeviceClas The name of the vendor ({2062d64d-3232-433c-88bc-0d33c0ba2ba6}) - - HTTP post - The name of the DeviceClass ({b101abdf-86fd-4d2e-a657-ee76044235bd}) - - Status code changed - 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 + The name of the EventType ({8daac0e7-4c2f-4cdf-b528-02cfe04c6b39}) of DeviceClass httpRequest Status code - The name of the ParamType (DeviceClass: httpGetCommander, EventType: status, ID: {8a60ffe0-e39a-43ec-be8c-c1ed1886aa41}) + 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 - - - - HTTP put - The name of the DeviceClass ({05bf65f5-ff13-43e3-b6ae-77019e79d8a1}) +The name of the StateType ({8daac0e7-4c2f-4cdf-b528-02cfe04c6b39}) of DeviceClass httpRequest Body - The name of the ParamType (DeviceClass: httpServer, EventType: triggered, ID: {c936810e-a73d-424f-8981-48baf0a440bb}) + 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}) @@ -156,15 +85,18 @@ The name of the StateType ({8daac0e7-4c2f-4cdf-b528-02cfe04c6b39}) of DeviceClas - Server address - The name of the ParamType (DeviceClass: httpServer, EventType: serverAddress, ID: {f4458008-67f2-4ba1-bbca-e85771a30ddc}) ----------- -The name of the StateType ({f4458008-67f2-4ba1-bbca-e85771a30ddc}) of DeviceClass httpServer + HTTP Request + The name of the DeviceClass ({b101abdf-86fd-4d2e-a657-ee76044235bd}) - Server address changed - The name of the EventType ({f4458008-67f2-4ba1-bbca-e85771a30ddc}) of DeviceClass httpServer + Method + The name of the ParamType (DeviceClass: httpRequest, ActionType: request, ID: {9fc9948a-5995-48d2-94ce-3c1fd26f6181}) + + + + Request + The name of the ActionType ({5a97ca56-b334-411b-adba-116496ffe83d}) of DeviceClass httpRequest