Permalink
Browse files

webui - "cgi" handler and multiple fixes (#700)

* initial commit of webconfig

* update example config with webconfig and fix format of file
update debian postinst script for install example config

* fix compiling
add new web server command "serverinfo" to use in webapp to retrieve json port

* change web default port to 8099

* add cgi engine to webserver

* fix include
  • Loading branch information...
1 parent eb64e7e commit 4a841710dd014ee7d946b4ec42e4f5e2041da897 @redPanther redPanther committed with brindosch Jun 14, 2016
@@ -67,7 +67,7 @@ class Hyperion : public QObject
///
/// @param[in] jsonConfig The Json configuration
///
- Hyperion(const Json::Value& jsonConfig);
+ Hyperion(const Json::Value& jsonConfig, const std::string configFile);
///
/// Destructor; cleans up resourcess
@@ -110,6 +110,11 @@ class Hyperion : public QObject
/// Get the list of active effects
/// @return The list of active effects
const std::list<ActiveEffectDefinition> &getActiveEffects();
+
+ ///
+ const Json::Value& getJsonConfig() { return _jsonConfig; };
+
+ std::string getConfigFileName() { return _configFile; };
public slots:
///
@@ -293,6 +298,12 @@ private slots:
// proto and json Message forwarder
MessageForwarder * _messageForwarder;
+ // json configuration
+ const Json::Value& _jsonConfig;
+
+ // the name of config file
+ std::string _configFile;
+
/// The timer for handling priority channel timeouts
QTimer _timer;
};
@@ -5,26 +5,25 @@
#include <QString>
#include <string>
#include <utils/jsonschema/JsonFactory.h>
+#include <hyperion/Hyperion.h>
class StaticFileServing;
class WebConfig : public QObject {
Q_OBJECT
public:
- WebConfig (std::string baseUrl, quint16 port, quint16 jsonPort, QObject * parent = NULL);
- WebConfig (const Json::Value &config, QObject * parent = NULL);
+ WebConfig (Hyperion *hyperion, QObject * parent = NULL);
virtual ~WebConfig (void);
void start();
void stop();
private:
- QObject* _parent;
+ Hyperion* _hyperion;
QString _baseUrl;
quint16 _port;
- quint16 _jsonPort;
StaticFileServing* _server;
const std::string WEBCONFIG_DEFAULT_PATH = "/usr/share/hyperion/webconfig";
@@ -114,6 +114,7 @@ void Effect::run()
{
std::cerr << "EFFECTENGINE ERROR: Unable to open script file " << _script << std::endl;
}
+ fclose(file);
// Clean up the thread state
Py_EndInterpreter(_interpreterThreadState);
@@ -615,7 +615,7 @@ MessageForwarder * Hyperion::getForwarder()
return _messageForwarder;
}
-Hyperion::Hyperion(const Json::Value &jsonConfig) :
+Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile) :
_ledString(createLedString(jsonConfig["leds"], createColorOrder(jsonConfig["device"]))),
_muxer(_ledString.leds().size()),
_raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), jsonConfig["color"])),
@@ -625,6 +625,8 @@ Hyperion::Hyperion(const Json::Value &jsonConfig) :
_device(LedDeviceFactory::construct(jsonConfig["device"])),
_effectEngine(nullptr),
_messageForwarder(createMessageForwarder(jsonConfig["forwarder"])),
+ _jsonConfig(jsonConfig),
+ _configFile(configFile),
_timer()
{
if (!_raw2ledAdjustment->verifyAdjustments())
@@ -46,7 +46,7 @@ Logger::Logger ( std::string name, LogLevel minLevel ):
_syslogEnabled(true),
_loggerId(loggerId++)
{
-#ifdef __linux__
+#ifdef __GLIBC__
_appname = std::string(program_invocation_short_name);
#else
_appname = std::string(getprogname());
@@ -10,6 +10,7 @@ set(WebConfig_QT_HEADERS
${CURRENT_SOURCE_DIR}/QtHttpReply.h
${CURRENT_SOURCE_DIR}/QtHttpRequest.h
${CURRENT_SOURCE_DIR}/QtHttpServer.h
+ ${CURRENT_SOURCE_DIR}/CgiHandler.h
${CURRENT_SOURCE_DIR}/StaticFileServing.h
${CURRENT_HEADER_DIR}/WebConfig.h
)
@@ -23,6 +24,7 @@ set(WebConfig_SOURCES
${CURRENT_SOURCE_DIR}/QtHttpReply.cpp
${CURRENT_SOURCE_DIR}/QtHttpRequest.cpp
${CURRENT_SOURCE_DIR}/QtHttpServer.cpp
+ ${CURRENT_SOURCE_DIR}/CgiHandler.cpp
${CURRENT_SOURCE_DIR}/StaticFileServing.cpp
${CURRENT_SOURCE_DIR}/WebConfig.cpp
)
@@ -0,0 +1,69 @@
+#include <QStringBuilder>
+#include <QUrlQuery>
+#include <QFile>
+#include <QByteArray>
+
+#include "CgiHandler.h"
+
+CgiHandler::CgiHandler (Hyperion * hyperion, QObject * parent)
+ : QObject(parent)
+ , _hyperion(hyperion)
+ , _hyperionConfig(_hyperion->getJsonConfig())
+{
+}
+
+CgiHandler::~CgiHandler()
+{
+}
+
+void CgiHandler::exec(const QStringList & args, QtHttpReply * reply)
+{
+ try
+ {
+ cmd_cfg_jsonserver(args,reply);
+ cmd_cfg_hyperion(args,reply);
+ throw 1;
+ }
+ catch(int e)
+ {
+ if (e != 0)
+ throw 1;
+ }
+}
+
+void CgiHandler::cmd_cfg_jsonserver(const QStringList & args, QtHttpReply * reply)
+{
+ if ( args.at(0) == "cfg_jsonserver" )
+ {
+ quint16 jsonPort = 19444;
+ if (_hyperionConfig.isMember("jsonServer"))
+ {
+ const Json::Value & jsonConfig = _hyperionConfig["jsonServer"];
+ jsonPort = jsonConfig.get("port", jsonPort).asUInt();
+ }
+
+ // send result as reply
+ reply->addHeader ("Content-Type", "text/plain" );
+ reply->appendRawData (QByteArrayLiteral(":") % QString::number(jsonPort).toUtf8() );
+ throw 0;
+ }
+}
+
+
+void CgiHandler::cmd_cfg_hyperion(const QStringList & args, QtHttpReply * reply)
+{
+ if ( args.at(0) == "cfg_hyperion" )
+ {
+ QFile file ( _hyperion->getConfigFileName().c_str() );
+ if (file.exists ())
+ {
+ if (file.open (QFile::ReadOnly)) {
+ QByteArray data = file.readAll ();
+ reply->addHeader ("Content-Type", "text/plain");
+ reply->appendRawData (data);
+ file.close ();
+ }
+ }
+ throw 0;
+ }
+}
@@ -0,0 +1,34 @@
+#ifndef CGIHANDLER_H
+#define CGIHANDLER_H
+
+#include <QObject>
+#include <QString>
+#include <QStringList>
+
+#include <utils/jsonschema/JsonFactory.h>
+#include <hyperion/Hyperion.h>
+
+#include "QtHttpReply.h"
+
+class CgiHandler : public QObject {
+ Q_OBJECT
+
+public:
+ CgiHandler (Hyperion * hyperion, QObject * parent = NULL);
+ virtual ~CgiHandler (void);
+
+ void exec(const QStringList & args, QtHttpReply * reply);
+
+ // cgi commands
+ void cmd_cfg_jsonserver(const QStringList & args, QtHttpReply * reply);
+ void cmd_cfg_hyperion (const QStringList & args, QtHttpReply * reply);
+
+private:
+ Hyperion* _hyperion;
+ QtHttpReply * _reply;
+ const Json::Value &_hyperionConfig;
+};
+
+#endif // CGIHANDLER_H
+
+
@@ -8,12 +8,13 @@
#include <QPair>
#include <QFile>
-StaticFileServing::StaticFileServing (QString baseUrl, quint16 port, quint16 jsonPort, QObject * parent)
- : QObject (parent)
- , m_baseUrl (baseUrl)
- , _jsonPort (jsonPort)
+StaticFileServing::StaticFileServing (Hyperion *hyperion, QString baseUrl, quint16 port, QObject * parent)
+ : QObject (parent)
+ , _hyperion(hyperion)
+ , _baseUrl (baseUrl)
+ , _cgi(hyperion, this)
{
- m_mimeDb = new QMimeDatabase;
+ _mimeDb = new QMimeDatabase;
_server = new QtHttpServer (this);
_server->setServerName (QStringLiteral ("Qt Static HTTP File Server"));
@@ -57,23 +58,31 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl
if (command == QStringLiteral ("GET"))
{
QString path = request->getUrl ().path ();
+ QStringList uri_parts = path.split('/', QString::SkipEmptyParts);
// special uri handling for server commands
- if ( path == "/serverinfo" )
+ if ( ! uri_parts.empty() && uri_parts.at(0) == "cgi" )
{
- reply->addHeader ("Content-Type", "text/plain" );
- reply->appendRawData (QByteArrayLiteral(":") % QString::number(_jsonPort).toUtf8() );
+ uri_parts.removeAt(0);
+ try
+ {
+ _cgi.exec(uri_parts, reply);
+ }
+ catch(...)
+ {
+ printErrorToReply (reply, "cgi script failed (" % path % ")");
+ }
return;
}
// get static files
- if ( path == "/" || path.isEmpty() || ! QFile::exists(m_baseUrl % "/" % path) )
+ if ( path == "/" || path.isEmpty() || ! QFile::exists(_baseUrl % "/" % path) )
path = "index.html";
- QFile file (m_baseUrl % "/" % path);
+ QFile file (_baseUrl % "/" % path);
if (file.exists ())
{
- QMimeType mime = m_mimeDb->mimeTypeForFile (file.fileName ());
+ QMimeType mime = _mimeDb->mimeTypeForFile (file.fileName ());
if (file.open (QFile::ReadOnly)) {
QByteArray data = file.readAll ();
reply->addHeader ("Content-Type", mime.name ().toLocal8Bit ());
@@ -82,7 +91,7 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl
}
else
{
- printErrorToReply (reply, "Requested file " % m_baseUrl % "/" % path % " couldn't be open for reading !");
+ printErrorToReply (reply, "Requested file " % path % " couldn't be open for reading !");
}
}
else
@@ -8,12 +8,15 @@
#include "QtHttpRequest.h"
#include "QtHttpReply.h"
#include "QtHttpHeader.h"
+#include "CgiHandler.h"
+
+#include <hyperion/Hyperion.h>
class StaticFileServing : public QObject {
Q_OBJECT
public:
- explicit StaticFileServing (QString baseUrl, quint16 port, quint16 jsonPort, QObject * parent = NULL);
+ explicit StaticFileServing (Hyperion *hyperion, QString baseUrl, quint16 port, QObject * parent = NULL);
virtual ~StaticFileServing (void);
public slots:
@@ -23,10 +26,11 @@ public slots:
void onRequestNeedsReply (QtHttpRequest * request, QtHttpReply * reply);
private:
- QString m_baseUrl;
- QtHttpServer * _server;
- QMimeDatabase * m_mimeDb;
- quint16 _jsonPort;
+ Hyperion * _hyperion;
+ QString _baseUrl;
+ QtHttpServer * _server;
+ QMimeDatabase * _mimeDb;
+ CgiHandler _cgi;
};
#endif // STATICFILESERVING_H
@@ -1,23 +1,16 @@
-#include "webconfig/webconfig.h"
+#include "webconfig/WebConfig.h"
#include "StaticFileServing.h"
-WebConfig::WebConfig(std::string baseUrl, quint16 port, quint16 jsonPort, QObject * parent) :
- _parent(parent),
- _baseUrl(QString::fromStdString(baseUrl)),
- _port(port),
- _jsonPort(jsonPort),
- _server(nullptr)
-{
-}
-
-WebConfig::WebConfig(const Json::Value &config, QObject * parent) :
- _parent(parent),
- _port(WEBCONFIG_DEFAULT_PORT),
- _server(nullptr)
+WebConfig::WebConfig(Hyperion *hyperion, QObject * parent)
+ : QObject(parent)
+ , _hyperion(hyperion)
+ , _port(WEBCONFIG_DEFAULT_PORT)
+ , _server(nullptr)
{
+ const Json::Value &config = hyperion->getJsonConfig();
_baseUrl = QString::fromStdString(WEBCONFIG_DEFAULT_PATH);
- _jsonPort = 19444;
+
bool webconfigEnable = true;
if (config.isMember("webConfig"))
@@ -28,13 +21,6 @@ WebConfig::WebConfig(const Json::Value &config, QObject * parent) :
_baseUrl = QString::fromStdString( webconfigConfig.get("document_root", WEBCONFIG_DEFAULT_PATH).asString() );
}
- if (config.isMember("jsonServer"))
- {
- const Json::Value & jsonConfig = config["jsonServer"];
- _jsonPort = jsonConfig.get("port", 19444).asUInt();
- }
-
-
if ( webconfigEnable )
start();
}
@@ -49,7 +35,7 @@ WebConfig::~WebConfig()
void WebConfig::start()
{
if ( _server == nullptr )
- _server = new StaticFileServing (_baseUrl, _port, _jsonPort, this);
+ _server = new StaticFileServing (_hyperion, _baseUrl, _port, this);
}
void WebConfig::stop()
Oops, something went wrong.

0 comments on commit 4a84171

Please sign in to comment.