add more rest resources
This commit is contained in:
parent
b86a062a87
commit
34e53ef5b3
@ -97,16 +97,41 @@
|
||||
...
|
||||
*/
|
||||
|
||||
/*! \enum HttpReply::Type
|
||||
|
||||
*/
|
||||
|
||||
#include "httpreply.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QPair>
|
||||
|
||||
/*! Construct a HttpReply with the given \a statusCode. */
|
||||
HttpReply::HttpReply(const HttpStatusCode &statusCode) :
|
||||
m_statusCode(statusCode),
|
||||
m_payload(QByteArray())
|
||||
HttpReply::HttpReply(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_statusCode(HttpReply::Ok),
|
||||
m_type(HttpReply::TypeSync),
|
||||
m_payload(QByteArray()),
|
||||
m_timedOut(false)
|
||||
{
|
||||
connect(&m_timer, &QTimer::timeout, this, &HttpReply::timedOut);
|
||||
|
||||
// set known headers
|
||||
setHeader(HttpHeaderType::ServerHeader, "guh/" + QByteArray(GUH_VERSION_STRING));
|
||||
setHeader(HttpHeaderType::DateHeader, QDateTime::currentDateTime().toString("ddd, dd MMM yyyy hh:mm:ss").toUtf8() + " GMT");
|
||||
setHeader(HttpHeaderType::CacheControlHeader, "no-cache");
|
||||
packReply();
|
||||
}
|
||||
|
||||
HttpReply::HttpReply(const HttpReply::HttpStatusCode &statusCode, const HttpReply::Type &type, QObject *parent):
|
||||
QObject(parent),
|
||||
m_statusCode(statusCode),
|
||||
m_type(type),
|
||||
m_payload(QByteArray()),
|
||||
m_timedOut(false)
|
||||
{
|
||||
connect(&m_timer, &QTimer::timeout, this, &HttpReply::timedOut);
|
||||
|
||||
// set known headers
|
||||
setHeader(HttpHeaderType::ServerHeader, "guh/" + QByteArray(GUH_VERSION_STRING));
|
||||
setHeader(HttpHeaderType::DateHeader, QDateTime::currentDateTime().toString("ddd, dd MMM yyyy hh:mm:ss").toUtf8() + " GMT");
|
||||
@ -118,6 +143,7 @@ HttpReply::HttpReply(const HttpStatusCode &statusCode) :
|
||||
void HttpReply::setHttpStatusCode(const HttpReply::HttpStatusCode &statusCode)
|
||||
{
|
||||
m_statusCode = statusCode;
|
||||
packReply();
|
||||
}
|
||||
|
||||
/*! Returns the status code of this \l{HttpReply}.*/
|
||||
@ -126,11 +152,30 @@ HttpReply::HttpStatusCode HttpReply::httpStatusCode() const
|
||||
return m_statusCode;
|
||||
}
|
||||
|
||||
/*! Returns the type of this \l{HttpReply}.
|
||||
* \sa Type
|
||||
*/
|
||||
HttpReply::Type HttpReply::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void HttpReply::setClientId(const QUuid &clientId)
|
||||
{
|
||||
m_clientId = clientId;
|
||||
}
|
||||
|
||||
QUuid HttpReply::clientId() const
|
||||
{
|
||||
return m_clientId;
|
||||
}
|
||||
|
||||
/*! Set the payload of this \l{HttpReply} to the given \a data.*/
|
||||
void HttpReply::setPayload(const QByteArray &data)
|
||||
{
|
||||
m_payload = data;
|
||||
setHeader(HttpHeaderType::ContentLenghtHeader, QByteArray::number(data.length()));
|
||||
packReply();
|
||||
}
|
||||
|
||||
/*! Returns the payload of this \l{HttpReply}.*/
|
||||
@ -149,6 +194,7 @@ void HttpReply::setRawHeader(const QByteArray headerType, const QByteArray &valu
|
||||
m_rawHeaderList.remove(headerType);
|
||||
}
|
||||
m_rawHeaderList.insert(headerType, value);
|
||||
packReply();
|
||||
}
|
||||
|
||||
/*! This method appends a known header to the header list of this \l{HttpReply}.
|
||||
@ -211,6 +257,11 @@ QByteArray HttpReply::data() const
|
||||
return m_data;
|
||||
}
|
||||
|
||||
bool HttpReply::timedOut() const
|
||||
{
|
||||
return m_timedOut;
|
||||
}
|
||||
|
||||
QByteArray HttpReply::getHttpReasonPhrase(const HttpReply::HttpStatusCode &statusCode)
|
||||
{
|
||||
switch (statusCode) {
|
||||
@ -278,3 +329,14 @@ QByteArray HttpReply::getHeaderType(const HttpReply::HttpHeaderType &headerType)
|
||||
return QByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
void HttpReply::startWait()
|
||||
{
|
||||
m_timer.start(5000);
|
||||
}
|
||||
|
||||
void HttpReply::timeout()
|
||||
{
|
||||
m_timedOut = true;
|
||||
emit finished();
|
||||
}
|
||||
|
||||
@ -21,13 +21,17 @@
|
||||
#ifndef HTTPREPLY_H
|
||||
#define HTTPREPLY_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
|
||||
// Note: RFC 7231 HTTP/1.1 Semantics and Content -> http://tools.ietf.org/html/rfc7231
|
||||
|
||||
class HttpReply
|
||||
class HttpReply: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum HttpStatusCode {
|
||||
@ -62,11 +66,22 @@ public:
|
||||
ServerHeader
|
||||
};
|
||||
|
||||
explicit HttpReply(const HttpStatusCode &statusCode = HttpStatusCode::Ok);
|
||||
enum Type {
|
||||
TypeSync,
|
||||
TypeAsync
|
||||
};
|
||||
|
||||
HttpReply(QObject *parent = 0);
|
||||
HttpReply(const HttpStatusCode &statusCode = HttpStatusCode::Ok, const Type &type = TypeSync, QObject *parent = 0);
|
||||
|
||||
void setHttpStatusCode(const HttpStatusCode &statusCode);
|
||||
HttpStatusCode httpStatusCode() const;
|
||||
|
||||
Type type() const;
|
||||
|
||||
void setClientId(const QUuid &clientId);
|
||||
QUuid clientId() const;
|
||||
|
||||
void setPayload(const QByteArray &data);
|
||||
QByteArray payload() const;
|
||||
|
||||
@ -82,18 +97,34 @@ public:
|
||||
|
||||
QByteArray data() const;
|
||||
|
||||
bool timedOut() const;
|
||||
|
||||
private:
|
||||
HttpStatusCode m_statusCode;
|
||||
Type m_type;
|
||||
QUuid m_clientId;
|
||||
|
||||
QByteArray m_rawHeader;
|
||||
QByteArray m_payload;
|
||||
QByteArray m_data;
|
||||
|
||||
QHash<QByteArray, QByteArray> m_rawHeaderList;
|
||||
|
||||
QTimer m_timer;
|
||||
bool m_timedOut;
|
||||
|
||||
QByteArray getHttpReasonPhrase(const HttpStatusCode &statusCode);
|
||||
QByteArray getHeaderType(const HttpHeaderType &headerType);
|
||||
|
||||
QByteArray packHeader() const;
|
||||
public slots:
|
||||
void startWait();
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private slots:
|
||||
void timeout();
|
||||
|
||||
};
|
||||
|
||||
#endif // HTTPREPLY_H
|
||||
|
||||
@ -56,9 +56,13 @@ HttpRequest::HttpRequest(QByteArray rawData) :
|
||||
qCWarning(dcWebServer) << "Unknown HTTP version:" << m_httpVersion;
|
||||
return;
|
||||
}
|
||||
m_method = getRequestMethodType(statusLineTokens.at(0).simplified());
|
||||
m_methodString = statusLineTokens.at(0).simplified();
|
||||
m_method = getRequestMethodType(m_methodString);
|
||||
|
||||
m_urlQuery = QUrlQuery(statusLineTokens.at(1).simplified());
|
||||
m_url = QUrl("http://example.com" + statusLineTokens.at(1).simplified());
|
||||
|
||||
if (m_url.hasQuery())
|
||||
m_urlQuery = QUrlQuery(m_url.query());
|
||||
|
||||
// verify headers
|
||||
foreach (const QString &line, headerLines) {
|
||||
@ -92,11 +96,21 @@ HttpRequest::RequestMethod HttpRequest::method() const
|
||||
return m_method;
|
||||
}
|
||||
|
||||
QString HttpRequest::methodString() const
|
||||
{
|
||||
return m_methodString;
|
||||
}
|
||||
|
||||
QByteArray HttpRequest::httpVersion() const
|
||||
{
|
||||
return m_httpVersion;
|
||||
}
|
||||
|
||||
QUrl HttpRequest::url() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
QUrlQuery HttpRequest::urlQuery() const
|
||||
{
|
||||
return m_urlQuery;
|
||||
@ -134,9 +148,10 @@ HttpRequest::RequestMethod HttpRequest::getRequestMethodType(const QString &meth
|
||||
|
||||
QDebug operator<<(QDebug debug, const HttpRequest &httpRequest)
|
||||
{
|
||||
debug << "===================================" << "\n";
|
||||
debug << "\n===================================" << "\n";
|
||||
debug << " http version: " << httpRequest.httpVersion() << "\n";
|
||||
debug << " method: " << httpRequest.method() << "\n";
|
||||
debug << " method: " << httpRequest.methodString() << "\n";
|
||||
debug << " URL path: " << httpRequest.url().path() << "\n";
|
||||
debug << " URL query: " << httpRequest.urlQuery().query() << "\n";
|
||||
debug << " is valid: " << httpRequest.isValid() << "\n";
|
||||
debug << "-----------------------------------" << "\n";
|
||||
|
||||
@ -43,7 +43,10 @@ public:
|
||||
QHash<QByteArray, QByteArray> rawHeaderList() const;
|
||||
|
||||
RequestMethod method() const;
|
||||
QString methodString() const;
|
||||
QByteArray httpVersion() const;
|
||||
|
||||
QUrl url() const;
|
||||
QUrlQuery urlQuery() const;
|
||||
|
||||
QByteArray payload() const;
|
||||
@ -57,7 +60,10 @@ private:
|
||||
QHash<QByteArray, QByteArray> m_rawHeaderList;
|
||||
|
||||
RequestMethod m_method;
|
||||
QString m_methodString;
|
||||
QByteArray m_httpVersion;
|
||||
|
||||
QUrl m_url;
|
||||
QUrlQuery m_urlQuery;
|
||||
|
||||
QByteArray m_payload;
|
||||
|
||||
@ -574,12 +574,9 @@ void DeviceHandler::devicesDiscovered(const DeviceClassId &deviceClassId, const
|
||||
}
|
||||
|
||||
JsonReply *reply = m_discoverRequests.take(deviceClassId);
|
||||
QVariantList list;
|
||||
foreach (const DeviceDescriptor &descriptor, deviceDescriptors) {
|
||||
list.append(JsonTypes::packDeviceDescriptor(descriptor));
|
||||
}
|
||||
|
||||
QVariantMap returns;
|
||||
returns.insert("deviceDescriptors", list);
|
||||
returns.insert("deviceDescriptors", JsonTypes::packDeviceDescriptors(deviceDescriptors));
|
||||
returns.insert("deviceError", JsonTypes::deviceErrorToString(DeviceManager::DeviceErrorNoError));
|
||||
|
||||
reply->setData(returns);
|
||||
|
||||
@ -713,6 +713,42 @@ QVariantList JsonTypes::packDeviceStates(Device *device)
|
||||
return stateValues;
|
||||
}
|
||||
|
||||
QVariantList JsonTypes::packDeviceDescriptors(const QList<DeviceDescriptor> deviceDescriptors)
|
||||
{
|
||||
QVariantList deviceDescriptorList;
|
||||
foreach (const DeviceDescriptor &deviceDescriptor, deviceDescriptors) {
|
||||
deviceDescriptorList.append(JsonTypes::packDeviceDescriptor(deviceDescriptor));
|
||||
}
|
||||
return deviceDescriptorList;
|
||||
}
|
||||
|
||||
QVariantList JsonTypes::packActionTypes(const DeviceClass &deviceClass)
|
||||
{
|
||||
QVariantList actionTypes;
|
||||
foreach (const ActionType &actionType, deviceClass.actionTypes()) {
|
||||
actionTypes.append(JsonTypes::packActionType(actionType));
|
||||
}
|
||||
return actionTypes;
|
||||
}
|
||||
|
||||
QVariantList JsonTypes::packStateTypes(const DeviceClass &deviceClass)
|
||||
{
|
||||
QVariantList stateTypes;
|
||||
foreach (const StateType &stateType, deviceClass.stateTypes()) {
|
||||
stateTypes.append(JsonTypes::packStateType(stateType));
|
||||
}
|
||||
return stateTypes;
|
||||
}
|
||||
|
||||
QVariantList JsonTypes::packEventTypes(const DeviceClass &deviceClass)
|
||||
{
|
||||
QVariantList eventTypes;
|
||||
foreach (const EventType &eventType, deviceClass.eventTypes()) {
|
||||
eventTypes.append(JsonTypes::packEventType(eventType));
|
||||
}
|
||||
return eventTypes;
|
||||
}
|
||||
|
||||
QVariantList JsonTypes::packPlugins()
|
||||
{
|
||||
QVariantList pluginsList;
|
||||
|
||||
@ -165,6 +165,13 @@ public:
|
||||
static QVariantList packSupportedDevices(const VendorId &vendorId);
|
||||
static QVariantList packConfiguredDevices();
|
||||
static QVariantList packDeviceStates(Device *device);
|
||||
static QVariantList packDeviceDescriptors(const QList<DeviceDescriptor> deviceDescriptors);
|
||||
|
||||
|
||||
static QVariantList packActionTypes(const DeviceClass &deviceClass);
|
||||
static QVariantList packStateTypes(const DeviceClass &deviceClass);
|
||||
static QVariantList packEventTypes(const DeviceClass &deviceClass);
|
||||
|
||||
|
||||
static QVariantList packPlugins();
|
||||
|
||||
|
||||
269
server/rest/deviceclassesresource.cpp
Normal file
269
server/rest/deviceclassesresource.cpp
Normal file
@ -0,0 +1,269 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "deviceclassesresource.h"
|
||||
#include "network/httprequest.h"
|
||||
#include "guhcore.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
DeviceClassesResource::DeviceClassesResource(QObject *parent) :
|
||||
RestResource(parent)
|
||||
{
|
||||
connect(GuhCore::instance(), &GuhCore::devicesDiscovered, this, &DeviceClassesResource::devicesDiscovered, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
|
||||
// get the main resource
|
||||
|
||||
// /api/v1/deviceclasses/{deviceClassId}/
|
||||
if (urlTokens.count() >= 4) {
|
||||
DeviceClassId deviceClassId = DeviceClassId(urlTokens.at(3));
|
||||
if (deviceClassId.isNull()) {
|
||||
qCWarning(dcRest) << "Could not parse DeviceClassId:" << urlTokens.at(3);
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
m_deviceClass = GuhCore::instance()->findDeviceClass(deviceClassId);
|
||||
if (!m_deviceClass.isValid()) {
|
||||
return createErrorReply(HttpReply::NotFound);
|
||||
}
|
||||
}
|
||||
|
||||
// check method
|
||||
HttpReply *reply;
|
||||
switch (request.method()) {
|
||||
case HttpRequest::Get:
|
||||
reply = proccessGetRequest(request, urlTokens);
|
||||
break;
|
||||
default:
|
||||
reply = createErrorReply(HttpReply::BadRequest);
|
||||
break;
|
||||
}
|
||||
return reply;
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
|
||||
// GET /api/v1/deviceclasses?vendorId="{vendorId}"
|
||||
if (urlTokens.count() == 3) {
|
||||
VendorId vendorId;
|
||||
if (request.url().hasQuery()) {
|
||||
if (request.urlQuery().hasQueryItem("vendorId")) {
|
||||
vendorId = VendorId(request.urlQuery().queryItemValue("vendorId"));
|
||||
if (vendorId.isNull()) {
|
||||
qCWarning(dcRest) << "Could not parse VendorId:" << request.urlQuery().queryItemValue("vendorId");
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
return getDeviceClasses(vendorId);
|
||||
}
|
||||
|
||||
// GET /api/v1/deviceclasses/{deviceClassId}
|
||||
if (urlTokens.count() == 4)
|
||||
return getDeviceClass();
|
||||
|
||||
// GET /api/v1/deviceclasses/{deviceClassId}/actiontypes
|
||||
if (urlTokens.count() == 5 && urlTokens.at(4) == "actiontypes")
|
||||
return getActionTypes();
|
||||
|
||||
// GET /api/v1/deviceclasses/{deviceClassId}/actiontypes/{actionTypeId}
|
||||
if (urlTokens.count() == 6 && urlTokens.at(4) == "actiontypes") {
|
||||
ActionTypeId actionTypeId = ActionTypeId(urlTokens.at(5));
|
||||
if (actionTypeId.isNull()) {
|
||||
qCWarning(dcRest) << "Could not parse ActionTypeId:" << urlTokens.at(5);
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
return getActionType(actionTypeId);
|
||||
}
|
||||
|
||||
// GET /api/v1/deviceclasses/{deviceClassId}/statetypes
|
||||
if (urlTokens.count() == 5 && urlTokens.at(4) == "statetypes")
|
||||
return getStateTypes();
|
||||
|
||||
// GET /api/v1/deviceclasses/{deviceClassId}/statetypes/{stateTypeId}
|
||||
if (urlTokens.count() == 6 && urlTokens.at(4) == "statetypes") {
|
||||
StateTypeId stateTypeId = StateTypeId(urlTokens.at(5));
|
||||
if (stateTypeId.isNull()) {
|
||||
qCWarning(dcRest) << "Could not parse StateTypeId:" << urlTokens.at(5);
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
return getStateType(stateTypeId);
|
||||
}
|
||||
|
||||
// GET /api/v1/deviceclasses/{deviceClassId}/eventtypes
|
||||
if (urlTokens.count() == 5 && urlTokens.at(4) == "eventtypes")
|
||||
return getEventTypes();
|
||||
|
||||
// GET /api/v1/deviceclasses/{deviceClassId}/eventtypes/{eventTypeId}
|
||||
if (urlTokens.count() == 6 && urlTokens.at(4) == "eventtypes") {
|
||||
EventTypeId eventTypeId = EventTypeId(urlTokens.at(5));
|
||||
if (eventTypeId.isNull()) {
|
||||
qCWarning(dcRest) << "Could not parse EventTypeId:" << urlTokens.at(5);
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
return getEventType(eventTypeId);
|
||||
}
|
||||
|
||||
// GET /api/v1/deviceclasses/{deviceClassId}/discover?name=paramName&value=paramValue
|
||||
if (urlTokens.count() == 5 && urlTokens.at(4) == "discover") {
|
||||
|
||||
// FIXME: find a better way to get discovery params
|
||||
|
||||
ParamList paramList;
|
||||
if (request.url().hasQuery()) {
|
||||
if (request.urlQuery().hasQueryItem("name") && request.urlQuery().hasQueryItem("name")) {
|
||||
paramList.append(Param(request.urlQuery().queryItemValue("name"), QVariant(request.urlQuery().queryItemValue("value"))));
|
||||
} else {
|
||||
qCWarning(dcRest) << "Invalid discovery params in" << request.urlQuery().query();
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
}
|
||||
return getDiscoverdDevices(paramList);
|
||||
}
|
||||
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::getDeviceClass()
|
||||
{
|
||||
qCDebug(dcRest) << "Get device class with id " << m_deviceClass.id();
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packDeviceClass(m_deviceClass)).toJson());
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::getActionTypes()
|
||||
{
|
||||
qCDebug(dcRest) << "Get action types for device class" << m_deviceClass.id();
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packActionTypes(m_deviceClass)).toJson());
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::getActionType(const ActionTypeId &actionTypeId)
|
||||
{
|
||||
qCDebug(dcRest) << "Get action type with id" << actionTypeId;
|
||||
|
||||
foreach (const ActionType &actionType, m_deviceClass.actionTypes()) {
|
||||
if (actionType.id() == actionTypeId) {
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packActionType(actionType)).toJson());
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
return createErrorReply(HttpReply::NotFound);
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::getStateTypes()
|
||||
{
|
||||
qCDebug(dcRest) << "Get state types for device class" << m_deviceClass.id();
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packStateTypes(m_deviceClass)).toJson());
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::getStateType(const StateTypeId &stateTypeId)
|
||||
{
|
||||
qCDebug(dcRest) << "Get state type with id" << stateTypeId;
|
||||
|
||||
foreach (const StateType &stateType, m_deviceClass.stateTypes()) {
|
||||
if (stateType.id() == stateTypeId) {
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packStateType(stateType)).toJson());
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
return createErrorReply(HttpReply::NotFound);
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::getEventTypes()
|
||||
{
|
||||
qCDebug(dcRest) << "Get event types for device class" << m_deviceClass.id();
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packEventTypes(m_deviceClass)).toJson());
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::getEventType(const EventTypeId &eventTypeId)
|
||||
{
|
||||
qCDebug(dcRest) << "Get event type with id" << eventTypeId;
|
||||
|
||||
foreach (const EventType &eventType, m_deviceClass.eventTypes()) {
|
||||
if (eventType.id() == eventTypeId) {
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packEventType(eventType)).toJson());
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
return createErrorReply(HttpReply::NotFound);
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::getDiscoverdDevices(const ParamList &discoveryParams)
|
||||
{
|
||||
qCDebug(dcRest) << "Discover devices for DeviceClass" << m_deviceClass.id();
|
||||
|
||||
DeviceManager::DeviceError status = GuhCore::instance()->discoverDevices(m_deviceClass.id(), discoveryParams);
|
||||
|
||||
if (status == DeviceManager::DeviceErrorAsync) {
|
||||
HttpReply *reply = createAsyncReply();
|
||||
m_discoverRequests.insert(m_deviceClass.id(), reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
if (status != DeviceManager::DeviceErrorNoError)
|
||||
return createErrorReply(HttpReply::InternalServerError);
|
||||
|
||||
return createSuccessReply();
|
||||
}
|
||||
|
||||
void DeviceClassesResource::devicesDiscovered(const DeviceClassId &deviceClassId, const QList<DeviceDescriptor> deviceDescriptors)
|
||||
{
|
||||
if (!m_discoverRequests.contains(deviceClassId))
|
||||
return; // Not the discovery we are waiting for.
|
||||
|
||||
qCDebug(dcRest) << "Discovery finished. Found" << deviceDescriptors.count() << "devices.";
|
||||
HttpReply *reply = m_discoverRequests.take(deviceClassId);
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packDeviceDescriptors(deviceDescriptors)).toJson());
|
||||
reply->finished();
|
||||
}
|
||||
|
||||
HttpReply *DeviceClassesResource::getDeviceClasses(const VendorId &vendorId)
|
||||
{
|
||||
if (vendorId == VendorId()) {
|
||||
qCDebug(dcRest) << "Get all device classes.";
|
||||
} else {
|
||||
qCDebug(dcRest) << "Get device classes for vendor" << vendorId.toString();
|
||||
}
|
||||
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packSupportedDevices(vendorId)).toJson());
|
||||
return reply;
|
||||
}
|
||||
|
||||
}
|
||||
74
server/rest/deviceclassesresource.h
Normal file
74
server/rest/deviceclassesresource.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef DEVICECLASSESRESOURCE_H
|
||||
#define DEVICECLASSESRESOURCE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
|
||||
#include "jsontypes.h"
|
||||
#include "restresource.h"
|
||||
#include "network/httpreply.h"
|
||||
|
||||
class HttpRequest;
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class DeviceClassesResource : public RestResource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeviceClassesResource(QObject *parent = 0);
|
||||
|
||||
HttpReply *proccessRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
private:
|
||||
mutable QHash<DeviceClassId, HttpReply *> m_discoverRequests;
|
||||
|
||||
DeviceClass m_deviceClass;
|
||||
|
||||
// Process method
|
||||
HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
// Get methods
|
||||
HttpReply *getDeviceClasses(const VendorId &vendorId);
|
||||
HttpReply *getDeviceClass();
|
||||
|
||||
HttpReply *getActionTypes();
|
||||
HttpReply *getActionType(const ActionTypeId &actionTypeId);
|
||||
|
||||
HttpReply *getStateTypes();
|
||||
HttpReply *getStateType(const StateTypeId &stateTypeId);
|
||||
|
||||
HttpReply *getEventTypes();
|
||||
HttpReply *getEventType(const EventTypeId &eventTypeId);
|
||||
|
||||
HttpReply *getDiscoverdDevices(const ParamList &discoveryParams);
|
||||
|
||||
private slots:
|
||||
void devicesDiscovered(const DeviceClassId &deviceClassId, const QList<DeviceDescriptor> deviceDescriptors);
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DEVICECLASSESRESOURCE_H
|
||||
@ -19,135 +19,342 @@
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "devicesresource.h"
|
||||
#include "jsontypes.h"
|
||||
#include "guhcore.h"
|
||||
#include "network/httpreply.h"
|
||||
#include "network/httprequest.h"
|
||||
#include "jsontypes.h"
|
||||
#include "guhcore.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
DevicesResource::DevicesResource(QObject *parent) :
|
||||
QObject(parent)
|
||||
RestResource(parent)
|
||||
{
|
||||
connect(GuhCore::instance(), &GuhCore::actionExecuted, this, &DevicesResource::actionExecuted);
|
||||
connect(GuhCore::instance(), &GuhCore::deviceSetupFinished, this, &DevicesResource::deviceSetupFinished);
|
||||
connect(GuhCore::instance(), &GuhCore::deviceEditFinished, this, &DevicesResource::deviceEditFinished);
|
||||
}
|
||||
|
||||
HttpReply DevicesResource::proccessDeviceRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
HttpReply *DevicesResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
DeviceId deviceId;
|
||||
StateTypeId stateTypeId;
|
||||
m_device = 0;
|
||||
|
||||
Device *device = 0;
|
||||
|
||||
// first parse device, stateTypeId
|
||||
// get the main resource
|
||||
if (urlTokens.count() >= 4) {
|
||||
deviceId = DeviceId(urlTokens.at(3));
|
||||
DeviceId deviceId = DeviceId(urlTokens.at(3));
|
||||
if (deviceId.isNull()) {
|
||||
qCWarning(dcRest) << "Could not parse DeviceId:" << urlTokens.at(3);
|
||||
return HttpReply(HttpReply::BadRequest);
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
device = GuhCore::instance()->findConfiguredDevice(deviceId);
|
||||
if (!device) {
|
||||
m_device = GuhCore::instance()->findConfiguredDevice(deviceId);
|
||||
if (!m_device) {
|
||||
qCWarning(dcRest) << "Could find any device with DeviceId:" << urlTokens.at(3);
|
||||
return HttpReply(HttpReply::NotFound);
|
||||
}
|
||||
|
||||
// /api/v1/devices/{deviceId}/states/{stateTypeId}
|
||||
if (urlTokens.count() >= 6 && urlTokens.at(4) == "states") {
|
||||
stateTypeId = StateTypeId(urlTokens.at(5));
|
||||
if (stateTypeId.isNull()) {
|
||||
qCWarning(dcRest) << "Could not parse StateTypeId:" << urlTokens.at(5);
|
||||
return HttpReply(HttpReply::BadRequest);
|
||||
}
|
||||
|
||||
if (!device->hasState(stateTypeId)){
|
||||
qCWarning(dcRest) << "This device has no StateTypeId:" << urlTokens.at(5);
|
||||
return HttpReply(HttpReply::NotFound);
|
||||
}
|
||||
return createErrorReply(HttpReply::NotFound);
|
||||
}
|
||||
}
|
||||
|
||||
// check methods
|
||||
if (request.method() == HttpRequest::Get) {
|
||||
// check method
|
||||
HttpReply *reply;
|
||||
switch (request.method()) {
|
||||
case HttpRequest::Get:
|
||||
reply = proccessGetRequest(request, urlTokens);
|
||||
break;
|
||||
case HttpRequest::Post:
|
||||
reply = proccessPostRequest(request, urlTokens);
|
||||
break;
|
||||
case HttpRequest::Put:
|
||||
reply = proccessPutRequest(request, urlTokens);
|
||||
break;
|
||||
case HttpRequest::Delete:
|
||||
reply = proccessDeleteRequest(request, urlTokens);
|
||||
break;
|
||||
default:
|
||||
reply = createErrorReply(HttpReply::BadRequest);
|
||||
break;
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
// /api/v1/devices
|
||||
if (urlTokens.count() == 3)
|
||||
return getConfiguredDevices();
|
||||
HttpReply *DevicesResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
|
||||
// /api/v1/devices/{deviceId}
|
||||
if (urlTokens.count() == 4)
|
||||
return getConfiguredDevice(device);
|
||||
// GET /api/v1/devices
|
||||
if (urlTokens.count() == 3)
|
||||
return getConfiguredDevices();
|
||||
|
||||
// /api/v1/devices/{deviceId}/states
|
||||
if (urlTokens.count() == 5 && urlTokens.at(4) == "states")
|
||||
return getDeviceStateValues(device);
|
||||
// GET /api/v1/devices/{deviceId}
|
||||
if (urlTokens.count() == 4)
|
||||
return getConfiguredDevice(m_device);
|
||||
|
||||
// /api/v1/devices/{deviceId}/states/{stateTypeId}
|
||||
if (urlTokens.count() == 6 && urlTokens.at(4) == "states")
|
||||
return getDeviceStateValue(device, stateTypeId);
|
||||
} else if (request.method() == HttpRequest::Delete) {
|
||||
// GET /api/v1/devices/{deviceId}/states
|
||||
if (urlTokens.count() == 5 && urlTokens.at(4) == "states")
|
||||
return getDeviceStateValues(m_device);
|
||||
|
||||
// /api/v1/devices
|
||||
if (urlTokens.count() == 3)
|
||||
return HttpReply(HttpReply::BadRequest);
|
||||
|
||||
if (urlTokens.count() == 4)
|
||||
return removeDevice(device);
|
||||
// /api/v1/devices/{deviceId}/states/{stateTypeId}
|
||||
if (urlTokens.count() >= 6 && urlTokens.at(4) == "states") {
|
||||
StateTypeId stateTypeId = StateTypeId(urlTokens.at(5));
|
||||
if (stateTypeId.isNull()) {
|
||||
qCWarning(dcRest) << "Could not parse StateTypeId:" << urlTokens.at(5);
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
|
||||
if (!m_device->hasState(stateTypeId)){
|
||||
qCWarning(dcRest) << "This device has no StateTypeId:" << urlTokens.at(5);
|
||||
return createErrorReply(HttpReply::NotFound);
|
||||
}
|
||||
return getDeviceStateValue(m_device, stateTypeId);
|
||||
}
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *DevicesResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
|
||||
// DELETE /api/v1/devices
|
||||
if (urlTokens.count() == 3)
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
|
||||
// DELETE /api/v1/devices/{deviceId}
|
||||
if (urlTokens.count() == 4)
|
||||
return removeDevice(m_device);
|
||||
|
||||
// TODO: /api/v1/devices/{deviceId}?ruleId={ruleId}&removePolicy={RemovePolicy}
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *DevicesResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
// POST /api/v1/devices
|
||||
if (urlTokens.count() == 3)
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
|
||||
// POST /api/v1/devices/{deviceId}
|
||||
if (urlTokens.count() == 4)
|
||||
return editDevice(m_device, request.payload());
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *DevicesResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
// POST /api/v1/devices
|
||||
if (urlTokens.count() == 3)
|
||||
return addConfiguredDevice(request.payload());
|
||||
|
||||
// POST /api/v1/devices/{deviceId}
|
||||
if (urlTokens.count() == 4)
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
|
||||
// POST /api/v1/devices/{deviceId}/execute/{actionTypeId}
|
||||
if (urlTokens.count() >= 6 && urlTokens.at(4) == "execute") {
|
||||
ActionTypeId actionTypeId = ActionTypeId(urlTokens.at(5));
|
||||
if (actionTypeId.isNull()) {
|
||||
qCWarning(dcRest) << "Could not parse ActionTypeId:" << urlTokens.at(5);
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
}
|
||||
return executeAction(m_device, actionTypeId, request.payload());
|
||||
}
|
||||
|
||||
return HttpReply(HttpReply::BadRequest);
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply DevicesResource::getConfiguredDevices()
|
||||
HttpReply *DevicesResource::getConfiguredDevices() const
|
||||
{
|
||||
HttpReply httpReply(HttpReply::Ok);
|
||||
httpReply.setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
|
||||
httpReply.setPayload(QJsonDocument::fromVariant(JsonTypes::packConfiguredDevices()).toJson());
|
||||
httpReply.packReply();
|
||||
return httpReply;
|
||||
qCDebug(dcRest) << "Get all configured devices";
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packConfiguredDevices()).toJson());
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply DevicesResource::getConfiguredDevice(Device *device)
|
||||
HttpReply *DevicesResource::getConfiguredDevice(Device *device) const
|
||||
{
|
||||
HttpReply httpReply(HttpReply::Ok);
|
||||
httpReply.setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
|
||||
httpReply.setPayload(QJsonDocument::fromVariant(JsonTypes::packDevice(device)).toJson());
|
||||
httpReply.packReply();
|
||||
return httpReply;
|
||||
qCDebug(dcRest) << "Get configured device with id:" << device->id().toString();
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packDevice(device)).toJson());
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply DevicesResource::getDeviceStateValues(Device *device)
|
||||
HttpReply *DevicesResource::getDeviceStateValues(Device *device) const
|
||||
{
|
||||
HttpReply httpReply(HttpReply::Ok);
|
||||
httpReply.setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
|
||||
httpReply.setPayload(QJsonDocument::fromVariant(JsonTypes::packDeviceStates(device)).toJson());
|
||||
httpReply.packReply();
|
||||
return httpReply;
|
||||
qCDebug(dcRest) << "Get states of device with id:" << device->id().toString();
|
||||
HttpReply *reply = createSuccessReply();
|
||||
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packDeviceStates(device)).toJson());
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply DevicesResource::getDeviceStateValue(Device *device, const StateTypeId &stateTypeId)
|
||||
HttpReply *DevicesResource::getDeviceStateValue(Device *device, const StateTypeId &stateTypeId) const
|
||||
{
|
||||
HttpReply httpReply(HttpReply::Ok);
|
||||
httpReply.setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
|
||||
QVariantMap stateValue;
|
||||
stateValue.insert("value", device->state(stateTypeId).value());
|
||||
httpReply.setPayload(QJsonDocument::fromVariant(stateValue).toJson());
|
||||
httpReply.packReply();
|
||||
return httpReply;
|
||||
qCDebug(dcRest) << "Get device state value of state with id:" << stateTypeId.toString();
|
||||
HttpReply *reply = createSuccessReply();
|
||||
QVariantMap stateValueMap;
|
||||
stateValueMap.insert("value", device->state(stateTypeId).value());
|
||||
reply->setPayload(QJsonDocument::fromVariant(stateValueMap).toJson());
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply DevicesResource::removeDevice(Device *device)
|
||||
HttpReply *DevicesResource::removeDevice(Device *device) const
|
||||
{
|
||||
qCDebug(dcRest) << "Remove device with id:" << device->id().toString();
|
||||
DeviceManager::DeviceError result = GuhCore::instance()->removeConfiguredDevice(device->id(), QHash<RuleId, RuleEngine::RemovePolicy>());
|
||||
|
||||
// TODO: parse removepolicy query params
|
||||
// TODO: /api/v1/devices/{deviceId}?ruleId={ruleId}&removePolicy={RemovePolicy}
|
||||
|
||||
if (result == DeviceManager::DeviceErrorNoError)
|
||||
return HttpReply(HttpReply::Ok);
|
||||
return createSuccessReply();
|
||||
|
||||
return HttpReply(HttpReply::Forbidden);
|
||||
return createErrorReply(HttpReply::Forbidden);
|
||||
}
|
||||
|
||||
HttpReply *DevicesResource::executeAction(Device *device, const ActionTypeId &actionTypeId, const QByteArray &payload) const
|
||||
{
|
||||
qCDebug(dcRest) << "Execute action" << actionTypeId.toString();
|
||||
|
||||
QPair<bool, QVariant> verification = RestResource::verifyPayload(payload);
|
||||
if (!verification.first)
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
|
||||
QVariantMap message = verification.second.toMap();
|
||||
|
||||
if (!message.contains("params"))
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
|
||||
ParamList actionParams = JsonTypes::unpackParams(message.value("params").toList());
|
||||
|
||||
Action action(actionTypeId, device->id());
|
||||
action.setParams(actionParams);
|
||||
|
||||
DeviceManager::DeviceError status = GuhCore::instance()->executeAction(action);
|
||||
if (status == DeviceManager::DeviceErrorAsync) {
|
||||
HttpReply *reply = createAsyncReply();
|
||||
m_asyncActionExecutions.insert(action.id(), reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
if (status != DeviceManager::DeviceErrorNoError)
|
||||
return createErrorReply(HttpReply::InternalServerError);
|
||||
|
||||
return createSuccessReply();
|
||||
}
|
||||
|
||||
HttpReply *DevicesResource::addConfiguredDevice(const QByteArray &payload) const
|
||||
{
|
||||
QPair<bool, QVariant> verification = RestResource::verifyPayload(payload);
|
||||
if (!verification.first)
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
|
||||
qCDebug(dcRest) << "Add device";
|
||||
|
||||
QVariantMap params = verification.second.toMap();
|
||||
|
||||
DeviceClassId deviceClass(params.value("deviceClassId").toString());
|
||||
ParamList deviceParams = JsonTypes::unpackParams(params.value("deviceParams").toList());
|
||||
DeviceDescriptorId deviceDescriptorId(params.value("deviceDescriptorId").toString());
|
||||
DeviceId newDeviceId = DeviceId::createDeviceId();
|
||||
|
||||
DeviceManager::DeviceError status;
|
||||
if (deviceDescriptorId.isNull()) {
|
||||
qCDebug(dcRest) << "...adding device with params" << deviceParams;
|
||||
status = GuhCore::instance()->addConfiguredDevice(deviceClass, deviceParams, newDeviceId);
|
||||
} else {
|
||||
qCDebug(dcRest) << "...adding discovered device with descriptor id" << deviceDescriptorId;
|
||||
status = GuhCore::instance()->addConfiguredDevice(deviceClass, deviceDescriptorId, newDeviceId);
|
||||
}
|
||||
if (status == DeviceManager::DeviceErrorAsync) {
|
||||
HttpReply *reply = createAsyncReply();
|
||||
m_asynDeviceAdditions.insert(newDeviceId, reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
if (status != DeviceManager::DeviceErrorNoError)
|
||||
return createErrorReply(HttpReply::InternalServerError);
|
||||
|
||||
return createSuccessReply();
|
||||
|
||||
}
|
||||
|
||||
HttpReply *DevicesResource::editDevice(Device *device, const QByteArray &payload) const
|
||||
{
|
||||
qCDebug(dcRest) << "Edit device" << device->id();
|
||||
QPair<bool, QVariant> verification = RestResource::verifyPayload(payload);
|
||||
if (!verification.first)
|
||||
return createErrorReply(HttpReply::BadRequest);
|
||||
|
||||
QVariantMap params = verification.second.toMap();
|
||||
ParamList deviceParams = JsonTypes::unpackParams(params.value("deviceParams").toList());
|
||||
|
||||
qCDebug(dcRest) << "Edit device with params:" << deviceParams;
|
||||
DeviceManager::DeviceError status;
|
||||
DeviceDescriptorId deviceDescriptorId(params.value("deviceDescriptorId").toString());
|
||||
if (deviceDescriptorId.isNull()) {
|
||||
status = GuhCore::instance()->editDevice(device->id(), deviceParams);
|
||||
} else {
|
||||
status = GuhCore::instance()->editDevice(device->id(), deviceDescriptorId);
|
||||
}
|
||||
|
||||
if (status == DeviceManager::DeviceErrorAsync) {
|
||||
HttpReply *reply = createAsyncReply();
|
||||
m_asyncEditDevice.insert(device, reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
if (status != DeviceManager::DeviceErrorNoError)
|
||||
return createErrorReply(HttpReply::InternalServerError);
|
||||
|
||||
return createSuccessReply();
|
||||
}
|
||||
|
||||
void DevicesResource::actionExecuted(const ActionId &actionId, DeviceManager::DeviceError status)
|
||||
{
|
||||
if (!m_asyncActionExecutions.contains(actionId))
|
||||
return; // Not the action we are waiting for.
|
||||
|
||||
HttpReply *reply = m_asyncActionExecutions.take(actionId);
|
||||
if (status == DeviceManager::DeviceErrorNoError) {
|
||||
reply->setHttpStatusCode(HttpReply::Ok);
|
||||
} else {
|
||||
reply->setHttpStatusCode(HttpReply::BadRequest);
|
||||
}
|
||||
|
||||
reply->finished();
|
||||
}
|
||||
|
||||
void DevicesResource::deviceSetupFinished(Device *device, DeviceManager::DeviceError status)
|
||||
{
|
||||
if (!m_asyncEditDevice.contains(device))
|
||||
return; // Not the device we are waiting for.
|
||||
|
||||
HttpReply *reply = m_asyncEditDevice.take(device);
|
||||
if (status == DeviceManager::DeviceErrorNoError) {
|
||||
reply->setHttpStatusCode(HttpReply::Ok);
|
||||
} else {
|
||||
reply->setHttpStatusCode(HttpReply::BadRequest);
|
||||
}
|
||||
|
||||
QVariantMap result;
|
||||
result.insert("deviceId", device->id());
|
||||
|
||||
reply->setPayload(QJsonDocument::fromVariant(result).toJson());
|
||||
reply->finished();
|
||||
}
|
||||
|
||||
void DevicesResource::deviceEditFinished(Device *device, DeviceManager::DeviceError status)
|
||||
{
|
||||
if (!m_asynDeviceAdditions.contains(device->id()))
|
||||
return; // Not the device we are waiting for.
|
||||
|
||||
HttpReply *reply = m_asyncEditDevice.take(device);
|
||||
if (status == DeviceManager::DeviceErrorNoError) {
|
||||
reply->setHttpStatusCode(HttpReply::Ok);
|
||||
} else {
|
||||
reply->setHttpStatusCode(HttpReply::BadRequest);
|
||||
}
|
||||
|
||||
reply->finished();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -22,32 +22,58 @@
|
||||
#define DEVICESRESOURCE_H
|
||||
|
||||
#include <QObject>
|
||||
#include "jsontypes.h"
|
||||
#include <QHash>
|
||||
|
||||
#include "jsontypes.h"
|
||||
#include "restresource.h"
|
||||
#include "network/httpreply.h"
|
||||
|
||||
class HttpReply;
|
||||
class HttpRequest;
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class DevicesResource : public QObject
|
||||
class DevicesResource: public RestResource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DevicesResource(QObject *parent = 0);
|
||||
|
||||
HttpReply proccessDeviceRequest(const HttpRequest &request, const QStringList &urlTokens);
|
||||
HttpReply *proccessRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
private:
|
||||
HttpReply getConfiguredDevices();
|
||||
HttpReply getConfiguredDevice(Device *device);
|
||||
HttpReply getDeviceStateValues(Device *device);
|
||||
HttpReply getDeviceStateValue(Device *device, const StateTypeId &stateTypeId);
|
||||
mutable QHash<ActionId, HttpReply *> m_asyncActionExecutions;
|
||||
mutable QHash<DeviceId, HttpReply *> m_asynDeviceAdditions;
|
||||
mutable QHash<Device *, HttpReply *> m_asyncEditDevice;
|
||||
mutable QHash<QUuid, HttpReply *> m_asyncPairingRequests;
|
||||
|
||||
HttpReply removeDevice(Device *device);
|
||||
Device *m_device;
|
||||
|
||||
signals:
|
||||
// Process method
|
||||
HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
public slots:
|
||||
// Get methods
|
||||
HttpReply *getConfiguredDevices() const;
|
||||
HttpReply *getConfiguredDevice(Device *device) const;
|
||||
HttpReply *getDeviceStateValues(Device *device) const;
|
||||
HttpReply *getDeviceStateValue(Device *device, const StateTypeId &stateTypeId) const;
|
||||
|
||||
// Delete methods
|
||||
HttpReply *removeDevice(Device *device) const;
|
||||
|
||||
// Post methods
|
||||
HttpReply *executeAction(Device *device, const ActionTypeId &actionTypeId, const QByteArray &payload) const;
|
||||
HttpReply *addConfiguredDevice(const QByteArray &payload) const;
|
||||
|
||||
// Put methods
|
||||
HttpReply *editDevice(Device *device, const QByteArray &payload) const;
|
||||
|
||||
private slots:
|
||||
void actionExecuted(const ActionId &actionId, DeviceManager::DeviceError status);
|
||||
void deviceSetupFinished(Device *device, DeviceManager::DeviceError status);
|
||||
void deviceEditFinished(Device *device, DeviceManager::DeviceError status);
|
||||
|
||||
};
|
||||
|
||||
|
||||
71
server/rest/logsresource.cpp
Normal file
71
server/rest/logsresource.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "logsresource.h"
|
||||
#include "network/httprequest.h"
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
LogsResource::LogsResource(QObject *parent) :
|
||||
RestResource(parent)
|
||||
{
|
||||
}
|
||||
|
||||
HttpReply *LogsResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *LogsResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);}
|
||||
|
||||
HttpReply *LogsResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *LogsResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *LogsResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
62
server/rest/logsresource.h
Normal file
62
server/rest/logsresource.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef LOGSRESOURCE_H
|
||||
#define LOGSRESOURCE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
|
||||
#include "jsontypes.h"
|
||||
#include "restresource.h"
|
||||
#include "network/httpreply.h"
|
||||
|
||||
class HttpRequest;
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class LogsResource : public RestResource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LogsResource(QObject *parent = 0);
|
||||
|
||||
HttpReply *proccessRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
private:
|
||||
// Process method
|
||||
HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
// Get methods
|
||||
|
||||
// Delete methods
|
||||
|
||||
// Post methods
|
||||
|
||||
// Put methods
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LOGSRESOURCE_H
|
||||
72
server/rest/pluginsresource.cpp
Normal file
72
server/rest/pluginsresource.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "pluginsresource.h"
|
||||
#include "network/httprequest.h"
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
PluginsResource::PluginsResource(QObject *parent) :
|
||||
RestResource(parent)
|
||||
{
|
||||
}
|
||||
|
||||
HttpReply *PluginsResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *PluginsResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *PluginsResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *PluginsResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *PluginsResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
62
server/rest/pluginsresource.h
Normal file
62
server/rest/pluginsresource.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef PLUGINSRESOURCE_H
|
||||
#define PLUGINSRESOURCE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
|
||||
#include "jsontypes.h"
|
||||
#include "restresource.h"
|
||||
#include "network/httpreply.h"
|
||||
|
||||
class HttpRequest;
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class PluginsResource : public RestResource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PluginsResource(QObject *parent = 0);
|
||||
|
||||
HttpReply *proccessRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
private:
|
||||
// Process method
|
||||
HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
// Get methods
|
||||
|
||||
// Delete methods
|
||||
|
||||
// Post methods
|
||||
|
||||
// Put methods
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PLUGINSRESOURCE_H
|
||||
108
server/rest/restresource.cpp
Normal file
108
server/rest/restresource.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "restresource.h"
|
||||
#include "network/httprequest.h"
|
||||
#include "loggingcategories.h"
|
||||
#include "guhcore.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QVariant>
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
RestResource::RestResource(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
RestResource::~RestResource()
|
||||
{
|
||||
}
|
||||
|
||||
HttpReply *RestResource::createSuccessReply()
|
||||
{
|
||||
HttpReply *reply = new HttpReply(HttpReply::Ok, HttpReply::TypeSync);
|
||||
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply *RestResource::createErrorReply(const HttpReply::HttpStatusCode &statusCode)
|
||||
{
|
||||
HttpReply *reply = new HttpReply(statusCode, HttpReply::TypeSync);
|
||||
return reply;
|
||||
}
|
||||
|
||||
HttpReply *RestResource::createAsyncReply()
|
||||
{
|
||||
HttpReply *reply = new HttpReply(HttpReply::Ok, HttpReply::TypeAsync);
|
||||
return reply;
|
||||
}
|
||||
|
||||
QPair<bool, QVariant> RestResource::verifyPayload(const QByteArray &payload)
|
||||
{
|
||||
QVariant data;
|
||||
if (!payload.isEmpty()) {
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error);
|
||||
|
||||
if(error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcRest) << "Failed to parse JSON payload" << payload << ":" << error.errorString();
|
||||
return QPair<bool, QVariant>(true, QVariant());
|
||||
}
|
||||
|
||||
data = jsonDoc.toVariant();
|
||||
}
|
||||
return QPair<bool, QVariant>(true, data);
|
||||
}
|
||||
|
||||
HttpReply *RestResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *RestResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *RestResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *RestResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
}
|
||||
59
server/rest/restresource.h
Normal file
59
server/rest/restresource.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef RESTRESOURCE_H
|
||||
#define RESTRESOURCE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPair>
|
||||
|
||||
#include "network/httpreply.h"
|
||||
|
||||
class HttpRequest;
|
||||
class HttpReply;
|
||||
class QVariant;
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class RestResource : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RestResource(QObject *parent = 0);
|
||||
virtual ~RestResource() = 0;
|
||||
|
||||
virtual HttpReply *proccessRequest(const HttpRequest &request, const QStringList &urlTokens) = 0;
|
||||
|
||||
static HttpReply *createSuccessReply();
|
||||
static HttpReply *createErrorReply(const HttpReply::HttpStatusCode &statusCode);
|
||||
static HttpReply *createAsyncReply();
|
||||
static QPair<bool, QVariant> verifyPayload(const QByteArray &payload);
|
||||
|
||||
private:
|
||||
virtual HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens);
|
||||
virtual HttpReply *proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens);
|
||||
virtual HttpReply *proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens);
|
||||
virtual HttpReply *proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // RESTRESOURCE_H
|
||||
@ -36,11 +36,16 @@ RestServer::RestServer(QObject *parent) :
|
||||
connect(m_webserver, &WebServer::clientDisconnected, this, &RestServer::clientDisconnected);
|
||||
connect(m_webserver, &WebServer::httpRequestReady, this, &RestServer::processHttpRequest);
|
||||
|
||||
// Resources
|
||||
m_deviceResource = new DevicesResource(this);
|
||||
|
||||
|
||||
m_webserver->startServer();
|
||||
|
||||
QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void RestServer::setup()
|
||||
{
|
||||
// Create resources
|
||||
m_deviceResource = new DevicesResource(this);
|
||||
m_deviceClassesResource = new DeviceClassesResource(this);
|
||||
}
|
||||
|
||||
void RestServer::clientConnected(const QUuid &clientId)
|
||||
@ -55,108 +60,65 @@ void RestServer::clientDisconnected(const QUuid &clientId)
|
||||
|
||||
void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &request)
|
||||
{
|
||||
qCDebug(dcRest) << "Process HTTP request" << clientId << request.method() << request.urlQuery().query();
|
||||
qCDebug(dcRest) << "Process HTTP request";
|
||||
qCDebug(dcRest) << request;
|
||||
|
||||
QStringList urlTokens = request.urlQuery().query(QUrl::FullyDecoded).split("/");
|
||||
QStringList urlTokens = request.url().path().split("/");
|
||||
urlTokens.removeAll(QString());
|
||||
|
||||
qCDebug(dcRest) << urlTokens;
|
||||
|
||||
if (urlTokens.count() < 3) {
|
||||
m_webserver->sendHttpReply(clientId, HttpReply(HttpReply::BadRequest));
|
||||
HttpReply *reply = new HttpReply(HttpReply::BadRequest, HttpReply::TypeSync, this);
|
||||
reply->setClientId(clientId);
|
||||
m_webserver->sendHttpReply(reply);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
if (urlTokens.at(2) == "devices") {
|
||||
HttpReply httpReply = m_deviceResource->proccessDeviceRequest(request, urlTokens);
|
||||
qCDebug(dcRest) << "sending header" << httpReply.rawHeader();
|
||||
m_webserver->sendHttpReply(clientId, httpReply);
|
||||
HttpReply *reply = m_deviceResource->proccessRequest(request, urlTokens);
|
||||
reply->setClientId(clientId);
|
||||
if (reply->type() == HttpReply::TypeAsync) {
|
||||
connect(reply, &HttpReply::finished, this, &RestServer::asyncReplyFinished);
|
||||
reply->startWait();
|
||||
m_asyncReplies.insert(clientId, reply);
|
||||
return;
|
||||
}
|
||||
m_webserver->sendHttpReply(reply);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// QString targetNamespace;
|
||||
// QString method;
|
||||
// QVariantMap params;
|
||||
|
||||
// // check filter
|
||||
// QVariantList deviceList;
|
||||
// if (!request.urlQuery().hasQueryItem("id")) {
|
||||
// HttpReply httpReply = m_deviceResource->proccessDeviceRequest(request);
|
||||
// m_webserver->sendHttpReply(clientId, httpReply);
|
||||
// return;
|
||||
// } else {
|
||||
// foreach (const QString& idString, request.urlQuery().allQueryItemValues("id")) {
|
||||
// Device *device = GuhCore::instance()->deviceManager()->findConfiguredDevice(DeviceId(idString));
|
||||
// if (device == Device()) {
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// if (request.method() == HttpRequest::Get && request.urlQuery().query() == "/api/v1/devices.json") {
|
||||
// targetNamespace = "Devices";
|
||||
// method = "GetConfiguredDevices";
|
||||
// } else if (request.method() == HttpRequest::Get && request.urlQuery().query() == "/api/v1/devices.json") {
|
||||
// targetNamespace = "Devices";
|
||||
// method = "GetConfiguredDevices";
|
||||
// } else {
|
||||
// HttpReply httpReply(HttpReply::BadRequest);
|
||||
// httpReply.setPayload("400 Bad Request.");
|
||||
// httpReply.packReply();
|
||||
// m_webserver->sendHttpReply(clientId, httpReply);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// JsonHandler *handler = GuhCore::instance()->jsonRPCServer()->handlers().value(targetNamespace);
|
||||
|
||||
// QPair<bool, QString> validationResult = handler->validateParams(method, params);
|
||||
// if (!validationResult.first) {
|
||||
// qCWarning(dcWebServer) << "Invalid params: " << validationResult.second;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// JsonReply *jsonReply;
|
||||
// QMetaObject::invokeMethod(handler, method.toLatin1().data(), Q_RETURN_ARG(JsonReply*, jsonReply), Q_ARG(QVariantMap, params));
|
||||
// if (jsonReply->type() == JsonReply::TypeAsync) {
|
||||
// jsonReply->setClientId(clientId);
|
||||
// connect(jsonReply, &JsonReply::finished, this, &RestServer::asyncReplyFinished);
|
||||
// jsonReply->startWait();
|
||||
// m_asyncReplies.insert(clientId, jsonReply);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// HttpReply httpReply(HttpReply::Ok);
|
||||
// httpReply.setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
|
||||
// httpReply.setPayload(QJsonDocument::fromVariant(jsonReply->data()).toJson());
|
||||
// httpReply.packReply();
|
||||
|
||||
// m_webserver->sendHttpReply(clientId, httpReply);
|
||||
|
||||
// jsonReply->deleteLater();
|
||||
if (urlTokens.at(2) == "deviceclasses") {
|
||||
HttpReply *reply = m_deviceClassesResource->proccessRequest(request, urlTokens);
|
||||
reply->setClientId(clientId);
|
||||
if (reply->type() == HttpReply::TypeAsync) {
|
||||
connect(reply, &HttpReply::finished, this, &RestServer::asyncReplyFinished);
|
||||
reply->startWait();
|
||||
m_asyncReplies.insert(clientId, reply);
|
||||
return;
|
||||
}
|
||||
m_webserver->sendHttpReply(reply);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void RestServer::asyncReplyFinished()
|
||||
{
|
||||
JsonReply *jsonReply = qobject_cast<JsonReply*>(sender());
|
||||
QUuid clientId = m_asyncReplies.key(jsonReply);
|
||||
HttpReply *reply = qobject_cast<HttpReply*>(sender());
|
||||
|
||||
if (!jsonReply->timedOut()) {
|
||||
HttpReply httpReply(HttpReply::Ok);
|
||||
httpReply.setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
|
||||
httpReply.setPayload(QJsonDocument::fromVariant(jsonReply->data()).toJson());
|
||||
httpReply.packReply();
|
||||
m_webserver->sendHttpReply(clientId, httpReply);
|
||||
qCDebug(dcWebServer) << "sending reply" << reply->data();
|
||||
|
||||
if (!reply->timedOut()) {
|
||||
reply->setHttpStatusCode(HttpReply::Ok);
|
||||
} else {
|
||||
HttpReply httpReply(HttpReply::GatewayTimeout);
|
||||
httpReply.setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
|
||||
httpReply.setPayload(QJsonDocument::fromVariant(jsonReply->data()).toJson());
|
||||
httpReply.packReply();
|
||||
m_webserver->sendHttpReply(clientId, httpReply);
|
||||
reply->setHttpStatusCode(HttpReply::GatewayTimeout);
|
||||
}
|
||||
jsonReply->deleteLater();
|
||||
|
||||
m_webserver->sendHttpReply(reply);
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "webserver.h"
|
||||
#include "jsonhandler.h"
|
||||
#include "devicesresource.h"
|
||||
#include "deviceclassesresource.h"
|
||||
|
||||
class HttpRequest;
|
||||
class HttpReply;
|
||||
@ -38,17 +39,17 @@ class RestServer : public QObject
|
||||
public:
|
||||
explicit RestServer(QObject *parent = 0);
|
||||
|
||||
|
||||
private:
|
||||
WebServer *m_webserver;
|
||||
QList<QUuid> m_clientList;
|
||||
QHash<QUuid, JsonReply *> m_asyncReplies;
|
||||
QHash<QUuid, HttpReply *> m_asyncReplies;
|
||||
|
||||
DevicesResource *m_deviceResource;
|
||||
|
||||
signals:
|
||||
void httpReplyReady(const HttpReply &httpReply);
|
||||
DeviceClassesResource *m_deviceClassesResource;
|
||||
|
||||
private slots:
|
||||
void setup();
|
||||
void clientConnected(const QUuid &clientId);
|
||||
void clientDisconnected(const QUuid &clientId);
|
||||
|
||||
|
||||
70
server/rest/rulesresource.cpp
Normal file
70
server/rest/rulesresource.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "rulesresource.h"
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
RulesResource::RulesResource(QObject *parent) :
|
||||
RestResource(parent)
|
||||
{
|
||||
}
|
||||
|
||||
HttpReply *RulesResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *RulesResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);}
|
||||
|
||||
HttpReply *RulesResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *RulesResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *RulesResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
62
server/rest/rulesresource.h
Normal file
62
server/rest/rulesresource.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef RULESRESOURCE_H
|
||||
#define RULESRESOURCE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
|
||||
#include "jsontypes.h"
|
||||
#include "restresource.h"
|
||||
#include "network/httpreply.h"
|
||||
|
||||
class HttpRequest;
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class RulesResource : public RestResource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RulesResource(QObject *parent = 0);
|
||||
|
||||
HttpReply *proccessRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
private:
|
||||
// Process method
|
||||
HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
// Get methods
|
||||
|
||||
// Delete methods
|
||||
|
||||
// Post methods
|
||||
|
||||
// Put methods
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // RULESRESOURCE_H
|
||||
72
server/rest/vendorsresource.cpp
Normal file
72
server/rest/vendorsresource.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "vendorsresource.h"
|
||||
#include "network/httprequest.h"
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
VendorsResource::VendorsResource(QObject *parent) :
|
||||
RestResource(parent)
|
||||
{
|
||||
}
|
||||
|
||||
HttpReply *VendorsResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *VendorsResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *VendorsResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *VendorsResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
HttpReply *VendorsResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens)
|
||||
{
|
||||
Q_UNUSED(request)
|
||||
Q_UNUSED(urlTokens)
|
||||
|
||||
return createErrorReply(HttpReply::NotImplemented);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
62
server/rest/vendorsresource.h
Normal file
62
server/rest/vendorsresource.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh 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. *
|
||||
* *
|
||||
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef VENDORSRESOURCE_H
|
||||
#define VENDORSRESOURCE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
|
||||
#include "jsontypes.h"
|
||||
#include "restresource.h"
|
||||
#include "network/httpreply.h"
|
||||
|
||||
class HttpRequest;
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class VendorsResource : public RestResource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VendorsResource(QObject *parent = 0);
|
||||
|
||||
HttpReply *proccessRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
private:
|
||||
// Process method
|
||||
HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
HttpReply *proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) override;
|
||||
|
||||
// Get methods
|
||||
|
||||
// Delete methods
|
||||
|
||||
// Post methods
|
||||
|
||||
// Put methods
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // VENDORSRESOURCE_H
|
||||
@ -26,7 +26,13 @@ SOURCES += $$top_srcdir/server/guhcore.cpp \
|
||||
$$top_srcdir/server/servermanager.cpp \
|
||||
$$top_srcdir/server/websocketserver.cpp \
|
||||
$$top_srcdir/server/rest/restserver.cpp \
|
||||
$$top_srcdir/server/rest/restresource.cpp \
|
||||
$$top_srcdir/server/rest/devicesresource.cpp \
|
||||
$$top_srcdir/server/rest/deviceclassesresource.cpp \
|
||||
$$top_srcdir/server/rest/vendorsresource.cpp \
|
||||
$$top_srcdir/server/rest/logsresource.cpp \
|
||||
$$top_srcdir/server/rest/pluginsresource.cpp \
|
||||
$$top_srcdir/server/rest/rulesresource.cpp \
|
||||
|
||||
|
||||
HEADERS += $$top_srcdir/server/guhcore.h \
|
||||
@ -52,6 +58,12 @@ HEADERS += $$top_srcdir/server/guhcore.h \
|
||||
$$top_srcdir/server/servermanager.h \
|
||||
$$top_srcdir/server/websocketserver.h \
|
||||
$$top_srcdir/server/rest/restserver.h \
|
||||
$$top_srcdir/server/rest/restresource.h \
|
||||
$$top_srcdir/server/rest/devicesresource.h \
|
||||
$$top_srcdir/server/rest/deviceclassesresource.h \
|
||||
$$top_srcdir/server/rest/vendorsresource.h \
|
||||
$$top_srcdir/server/rest/logsresource.h \
|
||||
$$top_srcdir/server/rest/pluginsresource.h \
|
||||
$$top_srcdir/server/rest/rulesresource.h \
|
||||
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ ServerManager::ServerManager(QObject *parent) :
|
||||
qCDebug(dcApplication) << "Starting JSON RPC Server";
|
||||
m_jsonServer = new JsonRPCServer(this);
|
||||
|
||||
qCDebug(dcApplication) << "Starting REST Webserver";
|
||||
qCDebug(dcApplication) << "Starting REST Server";
|
||||
m_restServer = new RestServer(this);
|
||||
}
|
||||
|
||||
|
||||
@ -84,10 +84,16 @@ void WebServer::sendData(const QList<QUuid> &clients, const QVariantMap &data)
|
||||
}
|
||||
}
|
||||
|
||||
void WebServer::sendHttpReply(const QUuid &clientId, const HttpReply &reply)
|
||||
void WebServer::sendHttpReply(HttpReply *reply)
|
||||
{
|
||||
QTcpSocket *socket = m_clientList.value(clientId);
|
||||
writeData(socket, reply.data());
|
||||
QTcpSocket *socket = 0;
|
||||
socket = m_clientList.value(reply->clientId());
|
||||
|
||||
if (!socket) {
|
||||
qCDebug(dcWebServer) << "Invalid socket pointer! This should never happen!!!";
|
||||
return;
|
||||
}
|
||||
writeData(socket, reply->data());
|
||||
}
|
||||
|
||||
bool WebServer::verifyFile(QTcpSocket *socket, const QString &fileName)
|
||||
@ -202,7 +208,6 @@ void WebServer::readClient()
|
||||
}
|
||||
|
||||
qCDebug(dcWebServer) << QString("Got valid request from %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort());
|
||||
qCDebug(dcWebServer) << request;
|
||||
|
||||
// verify method
|
||||
if (request.method() == HttpRequest::Unhandled) {
|
||||
@ -215,7 +220,7 @@ void WebServer::readClient()
|
||||
}
|
||||
|
||||
// verify query
|
||||
if (request.urlQuery().query().startsWith("/api/v1")) {
|
||||
if (request.url().path().startsWith("/api/v1")) {
|
||||
emit httpRequestReady(clientId, request);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ public:
|
||||
|
||||
void sendData(const QUuid &clientId, const QVariantMap &data) override;
|
||||
void sendData(const QList<QUuid> &clients, const QVariantMap &data) override;
|
||||
void sendHttpReply(const QUuid &clientId, const HttpReply &reply);
|
||||
void sendHttpReply(HttpReply *reply);
|
||||
|
||||
private:
|
||||
QTcpServer *m_server;
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
namespace guhserver {
|
||||
|
||||
WebSocketServer::WebSocketServer(QObject *parent) :
|
||||
QObject(parent)
|
||||
TransportInterface(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,12 +23,14 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "transportinterface.h"
|
||||
|
||||
// Note: WebSocket Protocol from the Internet Engineering Task Force (IETF) -> RFC6455 V13:
|
||||
// http://tools.ietf.org/html/rfc6455
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class WebSocketServer : public QObject
|
||||
class WebSocketServer : public TransportInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user