mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
add http error pages (#381)
* implement 404 for webserver - this is a quick hack, should be refactored later * add http error pages ... design is more a placebo ;-) * tune errorpages fix some cgi related stuff, now only python is possible executing and reading python file is possilbe, but it cannot receive any data from webui * fix typo * fix another typo
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QStringList>
|
||||
#include <string>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
@@ -37,21 +38,21 @@ void restartHyperion(bool asNewProcess)
|
||||
Error(log, "error while restarting hyperion");
|
||||
}
|
||||
|
||||
std::string command_exec(const char* cmd)
|
||||
QByteArray command_exec(QString cmd, QByteArray data)
|
||||
{
|
||||
char buffer[128];
|
||||
std::string result = "";
|
||||
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
|
||||
|
||||
std::shared_ptr<FILE> pipe(popen(cmd.toLocal8Bit().constData(), "r"), pclose);
|
||||
if (pipe)
|
||||
{
|
||||
while (!feof(pipe.get()))
|
||||
{
|
||||
if (fgets(buffer, 128, pipe.get()) != NULL)
|
||||
result += buffer;
|
||||
while (!feof(pipe.get()))
|
||||
{
|
||||
if (fgets(buffer, 128, pipe.get()) != NULL)
|
||||
result += buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result.c_str();
|
||||
}
|
||||
|
||||
};
|
@@ -5,6 +5,7 @@
|
||||
#include <QStringList>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QProcess>
|
||||
|
||||
#include "CgiHandler.h"
|
||||
#include "QtHttpHeader.h"
|
||||
@@ -18,6 +19,7 @@ CgiHandler::CgiHandler (Hyperion * hyperion, QString baseUrl, QObject * parent)
|
||||
, _args(QStringList())
|
||||
, _hyperionConfig(_hyperion->getQJsonConfig())
|
||||
, _baseUrl(baseUrl)
|
||||
, _log(Logger::getInstance("WEBSERVER"))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -123,22 +125,26 @@ void CgiHandler::cmd_runscript()
|
||||
// relative path not allowed
|
||||
if (scriptFilePath.indexOf("..") >=0)
|
||||
{
|
||||
Error( _log, "relative path not allowed (%s)", scriptFilePath.toStdString().c_str());
|
||||
throw 1;
|
||||
}
|
||||
|
||||
scriptFilePath = _baseUrl+"/server_scripts/"+scriptFilePath;
|
||||
QString interpreter = "";
|
||||
if (scriptFilePath.endsWith(".sh")) interpreter = "sh";
|
||||
if (scriptFilePath.endsWith(".py")) interpreter = "python";
|
||||
|
||||
if (QFile::exists(scriptFilePath) && !interpreter.isEmpty())
|
||||
|
||||
if (QFile::exists(scriptFilePath) && scriptFilePath.endsWith(".py") )
|
||||
{
|
||||
QByteArray data = Process::command_exec(QString(interpreter + " " + scriptFilePath).toUtf8().constData()).c_str();
|
||||
|
||||
QtHttpPostData postData = _request->getPostData();
|
||||
QByteArray inputData; // should be filled with post data
|
||||
QByteArray data = Process::command_exec("python " + scriptFilePath, inputData);
|
||||
_reply->addHeader ("Content-Type", "text/plain");
|
||||
_reply->appendRawData (data);
|
||||
throw 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error( _log, "script %s doesn't exists or is no python file", scriptFilePath.toStdString().c_str());
|
||||
}
|
||||
|
||||
throw 1;
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include <QStringList>
|
||||
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <utils/Logger.h>
|
||||
|
||||
#include "QtHttpReply.h"
|
||||
#include "QtHttpRequest.h"
|
||||
@@ -26,12 +27,13 @@ public:
|
||||
void cmd_runscript ();
|
||||
|
||||
private:
|
||||
Hyperion* _hyperion;
|
||||
QtHttpReply * _reply;
|
||||
QtHttpRequest * _request;
|
||||
QStringList _args;
|
||||
const QJsonObject &_hyperionConfig;
|
||||
const QString _baseUrl;
|
||||
Hyperion* _hyperion;
|
||||
QtHttpReply * _reply;
|
||||
QtHttpRequest * _request;
|
||||
QStringList _args;
|
||||
const QJsonObject & _hyperionConfig;
|
||||
const QString _baseUrl;
|
||||
Logger * _log;
|
||||
};
|
||||
|
||||
#endif // CGIHANDLER_H
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#include <QHostInfo>
|
||||
#include <bonjour/bonjourserviceregister.h>
|
||||
#include <bonjour/bonjourrecord.h>
|
||||
|
||||
#include <exception>
|
||||
|
||||
StaticFileServing::StaticFileServing (Hyperion *hyperion, QString baseUrl, quint16 port, QObject * parent)
|
||||
: QObject (parent)
|
||||
@@ -45,10 +45,7 @@ void StaticFileServing::onServerStarted (quint16 port)
|
||||
{
|
||||
Info(_log, "started on port %d name \"%s\"", port ,_server->getServerName().toStdString().c_str());
|
||||
|
||||
const std::string mDNSDescr = ( _server->getServerName().toStdString()
|
||||
+ "@" +
|
||||
QHostInfo::localHostName().toStdString()
|
||||
);
|
||||
const std::string mDNSDescr = (_server->getServerName().toStdString() + "@" + QHostInfo::localHostName().toStdString());
|
||||
|
||||
BonjourServiceRegister *bonjourRegister_http = new BonjourServiceRegister();
|
||||
bonjourRegister_http->registerService(
|
||||
@@ -67,17 +64,39 @@ void StaticFileServing::onServerError (QString msg)
|
||||
Error(_log, "%s", msg.toStdString().c_str());
|
||||
}
|
||||
|
||||
static inline void printErrorToReply (QtHttpReply * reply, QString errorMessage)
|
||||
void StaticFileServing::printErrorToReply (QtHttpReply * reply, QtHttpReply::StatusCode code, QString errorMessage)
|
||||
{
|
||||
reply->addHeader ("Content-Type", QByteArrayLiteral ("text/plain"));
|
||||
reply->appendRawData (errorMessage.toLocal8Bit ());
|
||||
}
|
||||
reply->setStatusCode(code);
|
||||
reply->addHeader ("Content-Type", QByteArrayLiteral ("text/html"));
|
||||
QFile errorPageHeader(_baseUrl % "/errorpages/header.html" );
|
||||
QFile errorPageFooter(_baseUrl % "/errorpages/footer.html" );
|
||||
QFile errorPage (_baseUrl % "/errorpages/" % QString::number((int)code) % ".html" );
|
||||
|
||||
static inline void printError404ToReply (QtHttpReply * reply, QString errorMessage)
|
||||
{
|
||||
reply->setStatusCode(QtHttpReply::NotFound);
|
||||
reply->addHeader ("Content-Type", QByteArrayLiteral ("text/plain"));
|
||||
reply->appendRawData (errorMessage.toLocal8Bit ());
|
||||
if (errorPageHeader.open (QFile::ReadOnly))
|
||||
{
|
||||
QByteArray data = errorPageHeader.readAll();
|
||||
reply->appendRawData (data);
|
||||
errorPageHeader.close ();
|
||||
}
|
||||
|
||||
if (errorPage.open (QFile::ReadOnly))
|
||||
{
|
||||
QByteArray data = errorPage.readAll();
|
||||
data = data.replace("{MESSAGE}", errorMessage.toLocal8Bit() );
|
||||
reply->appendRawData (data);
|
||||
errorPage.close ();
|
||||
}
|
||||
else
|
||||
{
|
||||
reply->appendRawData (QString(QString::number(code) + " - " +errorMessage).toLocal8Bit());
|
||||
}
|
||||
|
||||
if (errorPageFooter.open (QFile::ReadOnly))
|
||||
{
|
||||
QByteArray data = errorPageFooter.readAll ();
|
||||
reply->appendRawData (data);
|
||||
errorPageFooter.close ();
|
||||
}
|
||||
}
|
||||
|
||||
void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpReply * reply)
|
||||
@@ -94,16 +113,17 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl
|
||||
uri_parts.removeAt(0);
|
||||
try
|
||||
{
|
||||
if (command == QStringLiteral ("POST"))
|
||||
{
|
||||
QString postData = request->getRawData();
|
||||
uri_parts.append(postData.split('&', QString::SkipEmptyParts));
|
||||
}
|
||||
_cgi.exec(uri_parts, request, reply);
|
||||
}
|
||||
catch(...)
|
||||
catch(int err)
|
||||
{
|
||||
printErrorToReply (reply, "script failed (" % path % ")");
|
||||
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;
|
||||
}
|
||||
@@ -136,17 +156,17 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl
|
||||
}
|
||||
else
|
||||
{
|
||||
printErrorToReply (reply, "Requested file " % path % " couldn't be open for reading !");
|
||||
printErrorToReply (reply, QtHttpReply::Forbidden ,"Requested file: " % path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printError404ToReply (reply, "404 Not Found\n" % path % " couldn't be found !");
|
||||
printErrorToReply (reply, QtHttpReply::NotFound, "Requested file: " % path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printErrorToReply (reply, "Unhandled HTTP/1.1 method " % command % " on web server !");
|
||||
printErrorToReply (reply, QtHttpReply::MethodNotAllowed,"Unhandled HTTP/1.1 method " % command);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,8 @@ private:
|
||||
CgiHandler _cgi;
|
||||
Logger * _log;
|
||||
|
||||
void printErrorToReply (QtHttpReply * reply, QtHttpReply::StatusCode code, QString errorMessage);
|
||||
|
||||
};
|
||||
|
||||
#endif // STATICFILESERVING_H
|
||||
|
Reference in New Issue
Block a user