move write config from json api to http post (#363)

* implement config save over http post instead of json

* remove json set config
finish config write thrugh http post

* remove debug code and add failure messages
This commit is contained in:
redPanther 2017-01-14 19:04:58 +01:00 committed by GitHub
parent b2a6366176
commit 8a9d2760ef
17 changed files with 204 additions and 141 deletions

View File

@ -219,6 +219,8 @@
"InfoDialog_nowrite_foottext" : "Die Webkonfiguration wird automatisch wieder freigegeben, sobald das Problem behoben wurde!", "InfoDialog_nowrite_foottext" : "Die Webkonfiguration wird automatisch wieder freigegeben, sobald das Problem behoben wurde!",
"infoDialog_wizrgb_title" : "Erfolg!", "infoDialog_wizrgb_title" : "Erfolg!",
"infoDialog_wizrgb_text" : "Deine RGB Byte Reihenfolge ist bereits richtig eingestellt.", "infoDialog_wizrgb_text" : "Deine RGB Byte Reihenfolge ist bereits richtig eingestellt.",
"infoDialog_writeconf_error_title" : "Fehler",
"infoDialog_writeconf_error_text" : "Das speichern der Konfiguration ist fehlgeschlagen.",
"wiz_rgb_title" : "RGB Byte Reihenfolge Assistent", "wiz_rgb_title" : "RGB Byte Reihenfolge Assistent",
"wiz_rgb_intro1" : "Dieser Assisent wird dir dabei helfen die richtige Byte Reihenfolge für deine leds zu finden. Klicke auf Fortfahren um zu beginnen.", "wiz_rgb_intro1" : "Dieser Assisent wird dir dabei helfen die richtige Byte Reihenfolge für deine leds zu finden. Klicke auf Fortfahren um zu beginnen.",
"wiz_rgb_intro2" : "Wann benötigt man diesen Assistenten? Zur Erstkonfiguration oder wenn deine LEDs zb rot leuchten sollten, sie aber blau oder grün sind.", "wiz_rgb_intro2" : "Wann benötigt man diesen Assistenten? Zur Erstkonfiguration oder wenn deine LEDs zb rot leuchten sollten, sie aber blau oder grün sind.",

View File

@ -219,6 +219,8 @@
"InfoDialog_nowrite_foottext" : "The WebUI will be unlocked automatically after you solved the problem!", "InfoDialog_nowrite_foottext" : "The WebUI will be unlocked automatically after you solved the problem!",
"infoDialog_wizrgb_title" : "Success", "infoDialog_wizrgb_title" : "Success",
"infoDialog_wizrgb_text" : "Your RGB Byte Order is already well adjusted.", "infoDialog_wizrgb_text" : "Your RGB Byte Order is already well adjusted.",
"infoDialog_writeconf_error_title" : "Error",
"infoDialog_writeconf_error_text" : "Saving your configuration failed.",
"wiz_rgb_title" : "RGB Byte Order Wizard", "wiz_rgb_title" : "RGB Byte Order Wizard",
"wiz_rgb_intro1" : "This wizard will guide you through the finding process of the correct color order for your leds. Click on continue to begin.", "wiz_rgb_intro1" : "This wizard will guide you through the finding process of the correct color order for your leds. Click on continue to begin.",
"wiz_rgb_intro2" : "When do you need this wizard? Example: You set the color red, but you get green or blue. You could also use it for first configuration.", "wiz_rgb_intro2" : "When do you need this wizard? Example: You set the color red, but you get green or blue. You could also use it for first configuration.",

View File

@ -32,7 +32,7 @@ function initRestart()
function cron() function cron()
{ {
if ( watchdog > 2) if ( watchdog > 2 )
{ {
var interval_id = window.setInterval("", 9999); // Get a reference to the last var interval_id = window.setInterval("", 9999); // Get a reference to the last
for (var i = 1; i < interval_id; i++) for (var i = 1; i < interval_id; i++)
@ -229,8 +229,15 @@ function requestWriteConfig(config)
complete_config[i] = val; complete_config[i] = val;
}); });
var config_str = JSON.stringify(complete_config); var config_str = encode_utf8(JSON.stringify(complete_config));
sendToHyperion("config","setconfig", '"config":'+config_str);
$.post( "/cgi/cfg_set", { cfg: config_str })
.done(function( data ) {
$("html, body").animate({ scrollTop: 0 }, "slow");
})
.fail(function() {
showInfoDialog('error', $.i18n('infoDialog_writeconf_error_title'), $.i18n('infoDialog_writeconf_error_text'));
});
} }
function requestWriteEffect(effectName,effectPy,effectArgs) function requestWriteEffect(effectName,effectPy,effectArgs)

View File

@ -103,71 +103,56 @@ MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt
MultiColorAdjustment * adjustment = new MultiColorAdjustment(ledCnt); MultiColorAdjustment * adjustment = new MultiColorAdjustment(ledCnt);
const QJsonValue adjustmentConfig = colorConfig["channelAdjustment"]; const QJsonValue adjustmentConfig = colorConfig["channelAdjustment"];
if (adjustmentConfig.isNull()) const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
{
// Old style color transformation config (just one for all leds)
ColorAdjustment * colorAdjustment = createColorAdjustment(colorConfig);
adjustment->addAdjustment(colorAdjustment);
adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
}
else if (adjustmentConfig.isObject())
{
ColorAdjustment * colorAdjustment = createColorAdjustment(adjustmentConfig.toObject());
adjustment->addAdjustment(colorAdjustment);
adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
}
else if (adjustmentConfig.isArray())
{
const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
const QJsonArray & adjustmentConfigArray = adjustmentConfig.toArray(); const QJsonArray & adjustmentConfigArray = adjustmentConfig.toArray();
for (signed i = 0; i < adjustmentConfigArray.size(); ++i) for (signed i = 0; i < adjustmentConfigArray.size(); ++i)
{
const QJsonObject & config = adjustmentConfigArray.at(i).toObject();
ColorAdjustment * colorAdjustment = createColorAdjustment(config);
adjustment->addAdjustment(colorAdjustment);
const QString ledIndicesStr = config["leds"].toString("").trimmed();
if (ledIndicesStr.compare("*") == 0)
{ {
const QJsonObject & config = adjustmentConfigArray.at(i).toObject(); // Special case for indices '*' => all leds
ColorAdjustment * colorAdjustment = createColorAdjustment(config); adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
adjustment->addAdjustment(colorAdjustment); Info(CORE_LOGGER, "ColorAdjustment '%s' => [0; %d]", colorAdjustment->_id.c_str(), ledCnt-1);
continue;
const QString ledIndicesStr = config["leds"].toString("").trimmed();
if (ledIndicesStr.compare("*") == 0)
{
// Special case for indices '*' => all leds
adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
Info(CORE_LOGGER, "ColorAdjustment '%s' => [0; %d]", colorAdjustment->_id.c_str(), ledCnt-1);
continue;
}
if (!overallExp.exactMatch(ledIndicesStr))
{
Error(CORE_LOGGER, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str());
continue;
}
std::stringstream ss;
const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0)
{
ss << ", ";
}
if (ledIndexList[i].contains("-"))
{
QStringList ledIndices = ledIndexList[i].split("-");
int startInd = ledIndices[0].toInt();
int endInd = ledIndices[1].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd);
ss << startInd << "-" << endInd;
}
else
{
int index = ledIndexList[i].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index);
ss << index;
}
}
Info(CORE_LOGGER, "ColorAdjustment '%s' => [%s]", colorAdjustment->_id.c_str(), ss.str().c_str());
} }
if (!overallExp.exactMatch(ledIndicesStr))
{
Error(CORE_LOGGER, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str());
continue;
}
std::stringstream ss;
const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0)
{
ss << ", ";
}
if (ledIndexList[i].contains("-"))
{
QStringList ledIndices = ledIndexList[i].split("-");
int startInd = ledIndices[0].toInt();
int endInd = ledIndices[1].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd);
ss << startInd << "-" << endInd;
}
else
{
int index = ledIndexList[i].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index);
ss << index;
}
}
Info(CORE_LOGGER, "ColorAdjustment '%s' => [%s]", colorAdjustment->_id.c_str(), ss.str().c_str());
} }
return adjustment; return adjustment;
} }

View File

@ -967,10 +967,6 @@ void JsonClientConnection::handleConfigCommand(const QJsonObject& message, const
{ {
handleConfigGetCommand(message, full_command, tan); handleConfigGetCommand(message, full_command, tan);
} }
else if (subcommand == "setconfig")
{
handleConfigSetCommand(message, full_command, tan);
}
else if (subcommand == "reload") else if (subcommand == "reload")
{ {
_hyperion->freeObjects(); _hyperion->freeObjects();
@ -1098,28 +1094,6 @@ void JsonClientConnection::handleSchemaGetCommand(const QJsonObject& message, co
sendMessage(result); sendMessage(result);
} }
void JsonClientConnection::handleConfigSetCommand(const QJsonObject& message, const QString &command, const int tan)
{
if(message.size() > 0)
{
if (message.contains("config"))
{
QString errors;
if (!checkJson(message["config"].toObject(), ":/hyperion-schema", errors, true))
{
sendErrorReply("Error while validating json: " + errors, command, tan);
return;
}
QJsonObject hyperionConfig = message["config"].toObject();
QJsonFactory::writeJson(QString::fromStdString(_hyperion->getConfigFileName()), hyperionConfig);
sendSuccessReply(command, tan);
}
} else
sendErrorReply("Error while parsing json: Message size " + QString(message.size()), command, tan);
}
void JsonClientConnection::handleComponentStateCommand(const QJsonObject& message, const QString &command, const int tan) void JsonClientConnection::handleComponentStateCommand(const QJsonObject& message, const QString &command, const int tan)
{ {
const QJsonObject & componentState = message["componentstate"].toObject(); const QJsonObject & componentState = message["componentstate"].toObject();

View File

@ -234,11 +234,6 @@ private:
/// ///
void handleConfigGetCommand(const QJsonObject & message, const QString &command, const int tan); void handleConfigGetCommand(const QJsonObject & message, const QString &command, const int tan);
///
/// Handle an incoming JSON SetConfig message
///
void handleConfigSetCommand(const QJsonObject & message, const QString &command, const int tan);
/// ///
/// Handle an incoming JSON Component State message /// Handle an incoming JSON Component State message
/// ///

View File

@ -10,7 +10,7 @@
"subcommand": { "subcommand": {
"type" : "string", "type" : "string",
"required" : true, "required" : true,
"enum" : ["getconfig","setconfig","getschema","reload"] "enum" : ["getconfig","getschema","reload"]
}, },
"tan" : { "tan" : {
"type" : "integer" "type" : "integer"

View File

@ -2,15 +2,20 @@
#include <QUrlQuery> #include <QUrlQuery>
#include <QFile> #include <QFile>
#include <QByteArray> #include <QByteArray>
#include <QStringList>
#include <QJsonObject>
#include <QJsonDocument>
#include "CgiHandler.h" #include "CgiHandler.h"
#include "QtHttpHeader.h" #include "QtHttpHeader.h"
#include <utils/FileUtils.h> #include <utils/FileUtils.h>
#include <utils/Process.h> #include <utils/Process.h>
#include <utils/jsonschema/QJsonFactory.h>
CgiHandler::CgiHandler (Hyperion * hyperion, QString baseUrl, QObject * parent) CgiHandler::CgiHandler (Hyperion * hyperion, QString baseUrl, QObject * parent)
: QObject(parent) : QObject(parent)
, _hyperion(hyperion) , _hyperion(hyperion)
, _args(QStringList())
, _hyperionConfig(_hyperion->getQJsonConfig()) , _hyperionConfig(_hyperion->getQJsonConfig())
, _baseUrl(baseUrl) , _baseUrl(baseUrl)
{ {
@ -26,10 +31,13 @@ void CgiHandler::exec(const QStringList & args, QtHttpRequest * request, QtHttpR
{ {
// QByteArray header = reply->getHeader(QtHttpHeader::Host); // QByteArray header = reply->getHeader(QtHttpHeader::Host);
// QtHttpRequest::ClientInfo info = request->getClientInfo(); // QtHttpRequest::ClientInfo info = request->getClientInfo();
_args = args;
cmd_cfg_jsonserver(args,reply); _request = request;
cmd_cfg_hyperion(args,reply); _reply = reply;
cmd_runscript(args,reply); cmd_cfg_jsonserver();
cmd_cfg_get();
cmd_cfg_set();
cmd_runscript();
throw 1; throw 1;
} }
catch(int e) catch(int e)
@ -39,9 +47,9 @@ void CgiHandler::exec(const QStringList & args, QtHttpRequest * request, QtHttpR
} }
} }
void CgiHandler::cmd_cfg_jsonserver(const QStringList & args, QtHttpReply * reply) void CgiHandler::cmd_cfg_jsonserver()
{ {
if ( args.at(0) == "cfg_jsonserver" ) if ( _args.at(0) == "cfg_jsonserver" )
{ {
quint16 jsonPort = 19444; quint16 jsonPort = 19444;
if (_hyperionConfig.contains("jsonServer")) if (_hyperionConfig.contains("jsonServer"))
@ -51,24 +59,25 @@ void CgiHandler::cmd_cfg_jsonserver(const QStringList & args, QtHttpReply * repl
} }
// send result as reply // send result as reply
reply->addHeader ("Content-Type", "text/plain" ); _reply->addHeader ("Content-Type", "text/plain" );
reply->appendRawData (QByteArrayLiteral(":") % QString::number(jsonPort).toUtf8() ); _reply->appendRawData (QByteArrayLiteral(":") % QString::number(jsonPort).toUtf8() );
throw 0; throw 0;
} }
} }
void CgiHandler::cmd_cfg_hyperion(const QStringList & args, QtHttpReply * reply) void CgiHandler::cmd_cfg_get()
{ {
if ( args.at(0) == "cfg_hyperion" ) if ( _args.at(0) == "cfg_get" )
{ {
QFile file ( _hyperion->getConfigFileName().c_str() ); QFile file ( _hyperion->getConfigFileName().c_str() );
if (file.exists ()) if (file.exists ())
{ {
if (file.open (QFile::ReadOnly)) { if (file.open (QFile::ReadOnly)) {
QByteArray data = file.readAll (); QByteArray data = file.readAll ();
reply->addHeader ("Content-Type", "text/plain"); _reply->addHeader ("Content-Type", "text/plain");
reply->appendRawData (data); _reply->appendRawData (data);
file.close (); file.close ();
} }
} }
@ -76,11 +85,37 @@ void CgiHandler::cmd_cfg_hyperion(const QStringList & args, QtHttpReply * reply)
} }
} }
void CgiHandler::cmd_runscript(const QStringList & args, QtHttpReply * reply) void CgiHandler::cmd_cfg_set()
{ {
if ( args.at(0) == "run" ) _reply->addHeader ("Content-Type", "text/plain");
if ( _args.at(0) == "cfg_set" )
{ {
QStringList scriptFilePathList(args); QtHttpPostData data = _request->getPostData();
QJsonParseError error;
if (data.contains("cfg"))
{
QJsonDocument hyperionConfig = QJsonDocument::fromJson(data["cfg"], &error);
if (error.error == QJsonParseError::NoError)
{
QJsonObject hyperionConfigJsonObj = hyperionConfig.object();
QJsonFactory::writeJson(QString::fromStdString(_hyperion->getConfigFileName()), hyperionConfigJsonObj);
}
else
{
_reply->appendRawData (QString("Error while validating json: "+error.errorString()).toUtf8());
}
}
throw 0;
}
}
void CgiHandler::cmd_runscript()
{
if ( _args.at(0) == "run" )
{
QStringList scriptFilePathList(_args);
scriptFilePathList.removeAt(0); scriptFilePathList.removeAt(0);
QString scriptFilePath = scriptFilePathList.join('/'); QString scriptFilePath = scriptFilePathList.join('/');
@ -99,8 +134,8 @@ void CgiHandler::cmd_runscript(const QStringList & args, QtHttpReply * reply)
{ {
QByteArray data = Process::command_exec(QString(interpreter + " " + scriptFilePath).toUtf8().constData()).c_str(); QByteArray data = Process::command_exec(QString(interpreter + " " + scriptFilePath).toUtf8().constData()).c_str();
reply->addHeader ("Content-Type", "text/plain"); _reply->addHeader ("Content-Type", "text/plain");
reply->appendRawData (data); _reply->appendRawData (data);
throw 0; throw 0;
} }
throw 1; throw 1;

View File

@ -20,15 +20,18 @@ public:
void exec(const QStringList & args,QtHttpRequest * request, QtHttpReply * reply); void exec(const QStringList & args,QtHttpRequest * request, QtHttpReply * reply);
// cgi commands // cgi commands
void cmd_cfg_jsonserver(const QStringList & args, QtHttpReply * reply); void cmd_cfg_jsonserver();
void cmd_cfg_hyperion (const QStringList & args, QtHttpReply * reply); void cmd_cfg_get ();
void cmd_runscript (const QStringList & args, QtHttpReply * reply); void cmd_cfg_set ();
void cmd_runscript ();
private: private:
Hyperion* _hyperion; Hyperion* _hyperion;
QtHttpReply * _reply; QtHttpReply * _reply;
QtHttpRequest * _request;
QStringList _args;
const QJsonObject &_hyperionConfig; const QJsonObject &_hyperionConfig;
const QString _baseUrl; const QString _baseUrl;
}; };
#endif // CGIHANDLER_H #endif // CGIHANDLER_H

View File

@ -50,7 +50,7 @@ void QtHttpClientWrapper::onClientDataReceived (void) {
QString url = parts.at (1); QString url = parts.at (1);
QString version = parts.at (2); QString version = parts.at (2);
if (version == QtHttpServer::HTTP_VERSION) { if (version == QtHttpServer::HTTP_VERSION) {
m_currentRequest = new QtHttpRequest (m_serverHandle); m_currentRequest = new QtHttpRequest (this, m_serverHandle);
m_currentRequest->setClientInfo(m_sockClient->localAddress(), m_sockClient->peerAddress()); m_currentRequest->setClientInfo(m_sockClient->localAddress(), m_sockClient->peerAddress());
m_currentRequest->setUrl (QUrl (url)); m_currentRequest->setUrl (QUrl (url));
m_currentRequest->setCommand (command); m_currentRequest->setCommand (command);
@ -76,9 +76,8 @@ void QtHttpClientWrapper::onClientDataReceived (void) {
QByteArray value = raw.mid (pos +1).trimmed (); QByteArray value = raw.mid (pos +1).trimmed ();
m_currentRequest->addHeader (header, value); m_currentRequest->addHeader (header, value);
if (header == QtHttpHeader::ContentLength) { if (header == QtHttpHeader::ContentLength) {
int len = -1;
bool ok = false; bool ok = false;
len = value.toInt (&ok, 10); const int len = value.toInt (&ok, 10);
if (ok) { if (ok) {
m_currentRequest->addHeader (QtHttpHeader::ContentLength, QByteArray::number (len)); m_currentRequest->addHeader (QtHttpHeader::ContentLength, QByteArray::number (len));
} }
@ -110,6 +109,24 @@ void QtHttpClientWrapper::onClientDataReceived (void) {
} }
switch (m_parsingStatus) { // handle parsing status end/error switch (m_parsingStatus) { // handle parsing status end/error
case RequestParsed: { // a valid request has ben fully parsed case RequestParsed: { // a valid request has ben fully parsed
// add post data to request
if ( m_currentRequest->getCommand() == "POST")
{
QtHttpPostData postData;
QByteArray data = m_currentRequest->getRawData();
QList<QByteArray> parts = data.split('&');
for (int i = 0; i < parts.size(); ++i)
{
QList<QByteArray> keyValue = parts.at(i).split('=');
QByteArray value;
if (keyValue.size()>1)
{
value = QByteArray::fromPercentEncoding(keyValue.at(1));
}
postData.insert(QString::fromUtf8(keyValue.at(0)),value);
}
m_currentRequest->setPostData(postData);
}
QtHttpReply reply (m_serverHandle); QtHttpReply reply (m_serverHandle);
connect (&reply, &QtHttpReply::requestSendHeaders, connect (&reply, &QtHttpReply::requestSendHeaders,
this, &QtHttpClientWrapper::onReplySendHeadersRequested); this, &QtHttpClientWrapper::onReplySendHeadersRequested);

View File

@ -16,11 +16,16 @@ public:
explicit QtHttpReply (QtHttpServer * parent); explicit QtHttpReply (QtHttpServer * parent);
enum StatusCode { enum StatusCode {
Ok = 200, Ok = 200,
BadRequest = 400, SeeOther = 303,
Forbidden = 403, BadRequest = 400,
NotFound = 404, Forbidden = 403,
InternalError = 502, NotFound = 404,
MethodNotAllowed = 405,
InternalError = 500,
NotImplemented = 501,
BadGateway = 502,
ServiceUnavailable = 503,
}; };
int getRawDataSize (void) const; int getRawDataSize (void) const;

View File

@ -3,12 +3,14 @@
#include "QtHttpHeader.h" #include "QtHttpHeader.h"
#include "QtHttpServer.h" #include "QtHttpServer.h"
QtHttpRequest::QtHttpRequest (QtHttpServer * parent) QtHttpRequest::QtHttpRequest (QtHttpClientWrapper * client, QtHttpServer * parent)
: QObject (parent) : QObject (parent)
, m_url (QUrl ()) , m_url (QUrl ())
, m_command (QString ()) , m_command (QString ())
, m_data (QByteArray ()) , m_data (QByteArray ())
, m_serverHandle (parent) , m_serverHandle (parent)
, m_clientHandle (client)
, m_postData (QtHttpPostData())
{ {
// set some additional headers // set some additional headers
addHeader (QtHttpHeader::ContentLength, QByteArrayLiteral ("0")); addHeader (QtHttpHeader::ContentLength, QByteArrayLiteral ("0"));
@ -36,10 +38,18 @@ QByteArray QtHttpRequest::getRawData (void) const {
return m_data; return m_data;
} }
QtHttpPostData QtHttpRequest::getPostData (void) const {
return m_postData;
}
QList<QByteArray> QtHttpRequest::getHeadersList (void) const { QList<QByteArray> QtHttpRequest::getHeadersList (void) const {
return m_headersHash.keys (); return m_headersHash.keys ();
} }
QtHttpClientWrapper * QtHttpRequest::getClient (void) const {
return m_clientHandle;
}
QByteArray QtHttpRequest::getHeader (const QByteArray & header) const { QByteArray QtHttpRequest::getHeader (const QByteArray & header) const {
return m_headersHash.value (header, QByteArray ()); return m_headersHash.value (header, QByteArray ());
} }
@ -67,3 +77,7 @@ void QtHttpRequest::addHeader (const QByteArray & header, const QByteArray & val
void QtHttpRequest::appendRawData (const QByteArray & data) { void QtHttpRequest::appendRawData (const QByteArray & data) {
m_data.append (data); m_data.append (data);
} }
void QtHttpRequest::setPostData (const QtHttpPostData & data) {
m_postData = data;
}

View File

@ -7,28 +7,35 @@
#include <QHash> #include <QHash>
#include <QUrl> #include <QUrl>
#include <QHostAddress> #include <QHostAddress>
#include <QMap>
class QtHttpServer; class QtHttpServer;
class QtHttpClientWrapper;
using QtHttpPostData = QMap<QString,QByteArray>;
class QtHttpRequest : public QObject { class QtHttpRequest : public QObject {
Q_OBJECT Q_OBJECT
public: public:
explicit QtHttpRequest (QtHttpServer * parent); explicit QtHttpRequest (QtHttpClientWrapper * client, QtHttpServer * parent);
struct ClientInfo { struct ClientInfo {
QHostAddress serverAddress; QHostAddress serverAddress;
QHostAddress clientAddress; QHostAddress clientAddress;
}; };
int getRawDataSize (void) const; int getRawDataSize (void) const;
QUrl getUrl (void) const; QUrl getUrl (void) const;
QString getCommand (void) const; QString getCommand (void) const;
QByteArray getRawData (void) const; QByteArray getRawData (void) const;
QList<QByteArray> getHeadersList (void) const; QList<QByteArray> getHeadersList (void) const;
ClientInfo getClientInfo (void) const; QtHttpClientWrapper * getClient (void) const;
QByteArray getHeader (const QByteArray & header) const; QByteArray getHeader (const QByteArray & header) const;
QtHttpPostData getPostData (void) const;
ClientInfo getClientInfo (void) const;
public slots: public slots:
void setUrl (const QUrl & url); void setUrl (const QUrl & url);
@ -36,14 +43,17 @@ public slots:
void setClientInfo (const QHostAddress & server, const QHostAddress & client); void setClientInfo (const QHostAddress & server, const QHostAddress & client);
void addHeader (const QByteArray & header, const QByteArray & value); void addHeader (const QByteArray & header, const QByteArray & value);
void appendRawData (const QByteArray & data); void appendRawData (const QByteArray & data);
void setPostData (const QtHttpPostData & data);
private: private:
QUrl m_url; QUrl m_url;
QString m_command; QString m_command;
QByteArray m_data; QByteArray m_data;
QtHttpServer * m_serverHandle; QtHttpServer * m_serverHandle;
QtHttpClientWrapper * m_clientHandle;
QHash<QByteArray, QByteArray> m_headersHash; QHash<QByteArray, QByteArray> m_headersHash;
ClientInfo m_clientInfo; ClientInfo m_clientInfo;
QtHttpPostData m_postData;
}; };
#endif // QTHTTPREQUEST_H #endif // QTHTTPREQUEST_H

View File

@ -18,10 +18,18 @@ QtHttpServer::QtHttpServer (QObject * parent)
connect (m_sockServer, &QTcpServer::newConnection, this, &QtHttpServer::onClientConnected); connect (m_sockServer, &QTcpServer::newConnection, this, &QtHttpServer::onClientConnected);
} }
const QString QtHttpServer::getServerName (void) const { const QString & QtHttpServer::getServerName (void) const {
return m_serverName; return m_serverName;
} }
quint16 QtHttpServer::getServerPort (void) const {
return m_sockServer->serverPort ();
}
QString QtHttpServer::getErrorString (void) const {
return m_sockServer->errorString ();
}
void QtHttpServer::start (quint16 port) { void QtHttpServer::start (quint16 port) {
if (m_sockServer->listen (QHostAddress::Any, port)) { if (m_sockServer->listen (QHostAddress::Any, port)) {
emit started (m_sockServer->serverPort ()); emit started (m_sockServer->serverPort ());

View File

@ -19,8 +19,9 @@ public:
explicit QtHttpServer (QObject * parent = Q_NULLPTR); explicit QtHttpServer (QObject * parent = Q_NULLPTR);
static const QString & HTTP_VERSION; static const QString & HTTP_VERSION;
const QString & getServerName (void) const;
const QString getServerName (void) const; quint16 getServerPort (void) const;
QString getErrorString (void) const;
public slots: public slots:
void start (quint16 port = 0); void start (quint16 port = 0);

View File

@ -76,7 +76,7 @@ static inline void printErrorToReply (QtHttpReply * reply, QString errorMessage)
void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpReply * reply) void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpReply * reply)
{ {
QString command = request->getCommand (); QString command = request->getCommand ();
if (command == QStringLiteral ("GET")) if (command == QStringLiteral ("GET") || command == QStringLiteral ("POST"))
{ {
QString path = request->getUrl ().path (); QString path = request->getUrl ().path ();
QStringList uri_parts = path.split('/', QString::SkipEmptyParts); QStringList uri_parts = path.split('/', QString::SkipEmptyParts);
@ -87,6 +87,11 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl
uri_parts.removeAt(0); uri_parts.removeAt(0);
try try
{ {
if (command == QStringLiteral ("POST"))
{
QString postData = request->getRawData();
uri_parts.append(postData.split('&', QString::SkipEmptyParts));
}
_cgi.exec(uri_parts, request, reply); _cgi.exec(uri_parts, request, reply);
} }
catch(...) catch(...)
@ -134,7 +139,7 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl
} }
else else
{ {
printErrorToReply (reply, "Unhandled HTTP/1.1 method " % command % " on static file server !"); printErrorToReply (reply, "Unhandled HTTP/1.1 method " % command % " on web server !");
} }
} }