From 622a1718085589da58f58e9f1a7617d940e94ee3 Mon Sep 17 00:00:00 2001 From: brindosch Date: Wed, 5 Jul 2017 23:19:52 +0200 Subject: [PATCH] add http jsonrpc (#450) --- include/utils/JsonProcessor.h | 11 ++++-- libsrc/utils/JsonProcessor.cpp | 15 +++++--- libsrc/webconfig/StaticFileServing.cpp | 50 +++++++++++++++++++------- libsrc/webconfig/StaticFileServing.h | 2 ++ 4 files changed, 59 insertions(+), 19 deletions(-) diff --git a/include/utils/JsonProcessor.h b/include/utils/JsonProcessor.h index 9c395356..3d1f031b 100644 --- a/include/utils/JsonProcessor.h +++ b/include/utils/JsonProcessor.h @@ -41,15 +41,22 @@ class JsonProcessor : public QObject Q_OBJECT public: - JsonProcessor(QString peerAddress); + /// + /// Constructor + /// + /// @param peerAddress provide the Address of the peer + /// @param noListener if true, this instance won't listen for hyperion push events + /// + JsonProcessor(QString peerAddress, bool noListener = false); ~JsonProcessor(); /// /// Handle an incoming JSON message /// /// @param message the incoming message as string + /// @param peerAddress overwrite peerAddress of constructor /// - void handleMessage(const QString & message); + void handleMessage(const QString & message, const QString peerAddress = NULL); /// /// send a forced serverinfo to a client diff --git a/libsrc/utils/JsonProcessor.cpp b/libsrc/utils/JsonProcessor.cpp index f0b1d15e..ee5bc4b6 100644 --- a/libsrc/utils/JsonProcessor.cpp +++ b/libsrc/utils/JsonProcessor.cpp @@ -38,7 +38,7 @@ using namespace hyperion; std::map JsonProcessor::_componentsPrevState; -JsonProcessor::JsonProcessor(QString peerAddress) +JsonProcessor::JsonProcessor(QString peerAddress, bool noListener) : QObject() , _peerAddress(peerAddress) , _log(Logger::getInstance("JSONRPCPROCESSOR")) @@ -51,8 +51,12 @@ JsonProcessor::JsonProcessor(QString peerAddress) connect(this, &JsonProcessor::forwardJsonMessage, _hyperion, &Hyperion::forwardJsonMessage); // notify hyperion about a push emit connect(this, &JsonProcessor::pushReq, _hyperion, &Hyperion::hyperionStateChanged); - // listen for sendServerInfo pushes from hyperion - connect(_hyperion, &Hyperion::sendServerInfo, this, &JsonProcessor::forceServerInfo); + + if(!noListener) + { + // listen for sendServerInfo pushes from hyperion + connect(_hyperion, &Hyperion::sendServerInfo, this, &JsonProcessor::forceServerInfo); + } // led color stream update timer _timer_ledcolors.setSingleShot(false); @@ -65,8 +69,11 @@ JsonProcessor::~JsonProcessor() } -void JsonProcessor::handleMessage(const QString& messageString) +void JsonProcessor::handleMessage(const QString& messageString, const QString peerAddress) { + if(!peerAddress.isNull()) + _peerAddress = peerAddress; + QString errors; try diff --git a/libsrc/webconfig/StaticFileServing.cpp b/libsrc/webconfig/StaticFileServing.cpp index 481a2d80..6dc80cae 100644 --- a/libsrc/webconfig/StaticFileServing.cpp +++ b/libsrc/webconfig/StaticFileServing.cpp @@ -60,10 +60,14 @@ void StaticFileServing::onServerStarted (quint16 port) txtRecord ); Debug(_log, "Web Config mDNS responder started"); + + // json-rpc for http + _jsonProcessor = new JsonProcessor(QString("HTTP-API"),true); } void StaticFileServing::onServerStopped () { Info(_log, "stopped %s", _server->getServerName().toStdString().c_str()); + delete _jsonProcessor; } void StaticFileServing::onServerError (QString msg) @@ -115,24 +119,44 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl QStringList uri_parts = path.split('/', QString::SkipEmptyParts); // special uri handling for server commands - if ( ! uri_parts.empty() && uri_parts.at(0) == "cgi" ) + if ( ! uri_parts.empty() ) { - uri_parts.removeAt(0); - try + if(uri_parts.at(0) == "cgi") { - _cgi.exec(uri_parts, request, reply); + uri_parts.removeAt(0); + try + { + _cgi.exec(uri_parts, request, reply); + } + catch(int err) + { + Error(_log,"Exception while executing cgi %s : %d", path.toStdString().c_str(), err); + printErrorToReply (reply, QtHttpReply::InternalError, "script failed (" % path % ")"); + } + catch(std::exception &e) + { + Error(_log,"Exception while executing cgi %s : %s", path.toStdString().c_str(), e.what()); + printErrorToReply (reply, QtHttpReply::InternalError, "script failed (" % path % ")"); + } + return; } - catch(int err) + else if ( uri_parts.at(0) == "json-rpc" ) { - Error(_log,"Exception while executing cgi %s : %d", path.toStdString().c_str(), err); - printErrorToReply (reply, QtHttpReply::InternalError, "script failed (" % path % ")"); + QMetaObject::Connection m_connection; + QByteArray data = request->getRawData(); + QtHttpRequest::ClientInfo info = request->getClientInfo(); + + m_connection = QObject::connect(_jsonProcessor, &JsonProcessor::callbackMessage, + [reply](QJsonObject result) { + QJsonDocument doc(result); + reply->addHeader ("Content-Type", "application/json"); + reply->appendRawData (doc.toJson()); + }); + + _jsonProcessor->handleMessage(data,info.clientAddress.toString()); + QObject::disconnect( m_connection ); + return; } - catch(std::exception &e) - { - Error(_log,"Exception while executing cgi %s : %s", path.toStdString().c_str(), e.what()); - printErrorToReply (reply, QtHttpReply::InternalError, "script failed (" % path % ")"); - } - return; } Q_INIT_RESOURCE(WebConfig); diff --git a/libsrc/webconfig/StaticFileServing.h b/libsrc/webconfig/StaticFileServing.h index 8c82b69c..73069c4c 100644 --- a/libsrc/webconfig/StaticFileServing.h +++ b/libsrc/webconfig/StaticFileServing.h @@ -12,6 +12,7 @@ #include #include +#include class StaticFileServing : public QObject { @@ -34,6 +35,7 @@ private: QMimeDatabase * _mimeDb; CgiHandler _cgi; Logger * _log; + JsonProcessor * _jsonProcessor; void printErrorToReply (QtHttpReply * reply, QtHttpReply::StatusCode code, QString errorMessage);