Add resource enable/disable handling

This commit is contained in:
Simon Stürz 2025-11-12 10:51:19 +01:00
parent 2a309ce596
commit 29ba4625e8
9 changed files with 66 additions and 11 deletions

View File

@ -51,14 +51,9 @@ DebugServerHandler::DebugServerHandler(QObject *parent) :
onDebugServerEnabledChanged(NymeaCore::instance()->configuration()->debugServerEnabled());
}
bool DebugServerHandler::authenticationRequired() const
{
return false;
}
HttpReply *DebugServerHandler::processRequest(const HttpRequest &request)
{
if (NymeaCore::instance()->configuration()->debugServerEnabled()) {
if (m_enabled) {
// Verify methods
if (request.method() != HttpRequest::Get && request.method() != HttpRequest::Options) {
@ -658,6 +653,8 @@ void DebugServerHandler::onDebugServerEnabledChanged(bool enabled)
m_websocketServer = nullptr;
}
}
setEnabled(enabled);
}
void DebugServerHandler::onWebsocketClientConnected()

View File

@ -43,8 +43,6 @@ class DebugServerHandler : public WebServerResource
public:
explicit DebugServerHandler(QObject *parent = nullptr);
bool authenticationRequired() const override;
HttpReply *processRequest(const HttpRequest &request) override;
private:

View File

@ -379,7 +379,14 @@ void WebServer::readClient()
// Verify if we habe a resource for this request
foreach (WebServerResource *resource, m_resources) {
if (request.url().path().startsWith(resource->basePath())) {
qCDebug(dcWebServer()) << "Let the resource handle this request";
if (!resource->enabled()) {
qCDebug(dcWebServer()) << "The corresponding resource exists but is not enabled. Respond with 404 Not Found.";
HttpReply *reply = HttpReply::createErrorReply(HttpReply::NotFound);
reply->setClientId(clientId);
sendHttpReply(reply);
reply->deleteLater();
}
qCDebug(dcDebugServer()) << "Request:" << request.url().toString();
HttpReply *reply = resource->processRequest(request);
reply->setClientId(clientId);

View File

@ -317,6 +317,15 @@ States Thing::states() const
return m_states;
}
/*! Returns true, a \l{Param} with the given \a paramTypeId exists for this thing. */
bool Thing::hasParam(const QString &paramName) const
{
ParamTypeId paramTypeId = m_thingClass.paramTypes().findByName(paramName).id();
return m_params.hasParam(paramTypeId);
}
/*! Returns true, a \l{Param} with the given \a paramTypeId exists for this thing. */
bool Thing::hasParam(const ParamTypeId &paramTypeId) const
{

View File

@ -112,6 +112,7 @@ public:
ParamList params() const;
bool hasParam(const ParamTypeId &paramTypeId) const;
bool hasParam(const QString &paramName) const;
void setParams(const ParamList &params);
QVariant paramValue(const ParamTypeId &paramTypeId) const;

View File

@ -197,6 +197,14 @@ HttpReply *HttpReply::createSuccessReply()
return reply;
}
HttpReply *HttpReply::createJsonReply(const QJsonDocument &jsonDoc, const HttpReply::HttpStatusCode &statusCode)
{
HttpReply *reply = new HttpReply(statusCode, HttpReply::TypeSync);
reply->setPayload(jsonDoc.toJson(QJsonDocument::Compact));
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
return reply;
}
HttpReply *HttpReply::createErrorReply(const HttpReply::HttpStatusCode &statusCode)
{
HttpReply *reply = new HttpReply(statusCode, HttpReply::TypeSync);
@ -389,6 +397,12 @@ QByteArray HttpReply::getHttpReasonPhrase(const HttpReply::HttpStatusCode &statu
case BadRequest:
response = QString("Bad Request").toUtf8();
break;
case Unauthorized:
response = QString("Unauthorized").toUtf8();
break;
case PaymentRequired:
response = QString("Payment required").toUtf8();
break;
case Forbidden:
response = QString("Forbidden").toUtf8();
break;
@ -398,6 +412,9 @@ QByteArray HttpReply::getHttpReasonPhrase(const HttpReply::HttpStatusCode &statu
case MethodNotAllowed:
response = QString("Method Not Allowed").toUtf8();
break;
case NotAcceptable:
response = QString("Not Acceptable").toUtf8();
break;
case RequestTimeout:
response = QString("Request Timeout").toUtf8();
break;

View File

@ -30,6 +30,7 @@
#include <QHash>
#include <QTimer>
#include <QUuid>
#include <QJsonDocument>
// Note: RFC 7231 HTTP/1.1 Semantics and Content -> http://tools.ietf.org/html/rfc7231
@ -45,9 +46,12 @@ public:
Found = 302,
PermanentRedirect = 308,
BadRequest = 400,
Unauthorized = 401,
PaymentRequired = 402,
Forbidden = 403,
NotFound = 404,
MethodNotAllowed = 405,
NotAcceptable = 406,
RequestTimeout = 408,
Conflict = 409,
InternalServerError = 500,
@ -80,6 +84,7 @@ public:
static HttpReply *createSuccessReply();
static HttpReply *createErrorReply(const HttpReply::HttpStatusCode &statusCode);
static HttpReply *createJsonReply(const QJsonDocument &jsonDoc, const HttpReply::HttpStatusCode &statusCode = HttpStatusCode::Ok);
static HttpReply *createAsyncReply();
void setHttpStatusCode(const HttpStatusCode &statusCode);

View File

@ -45,10 +45,24 @@ QString WebServerResource::basePath() const
return m_basePath;
}
bool WebServerResource::enabled() const
{
return m_enabled;
}
void WebServerResource::setEnabled(bool enabled)
{
if (m_enabled == enabled)
return;
qCDebug(dcWebServer()) << "The resource" << m_basePath << "is now" << (enabled ? "enabled" : "disabled");
m_enabled = enabled;
emit enabledChanged(m_enabled);
}
HttpReply *WebServerResource::createFileReply(const QString fileName)
{
qCDebug(dcWebServer()) << "Create file reply for" << fileName;
HttpReply *reply = HttpReply::createSuccessReply();
QFile file(fileName);
if (!file.open(QFile::ReadOnly)) {
@ -56,6 +70,8 @@ HttpReply *WebServerResource::createFileReply(const QString fileName)
return HttpReply::createErrorReply(HttpReply::Forbidden);
}
HttpReply *reply = HttpReply::createSuccessReply();
// Check content type
if (file.fileName().endsWith(".html")) {
reply->setHeader(HttpReply::ContentTypeHeader, "text/html; charset=\"utf-8\";");

View File

@ -46,14 +46,19 @@ public:
QString basePath() const;
virtual bool authenticationRequired() const = 0;
bool enabled() const;
void setEnabled(bool enabled);
virtual HttpReply *processRequest(const HttpRequest &request) = 0;
static HttpReply *createFileReply(const QString fileName);
signals:
void enabledChanged(bool enabled);
protected:
QString m_basePath;
bool m_enabled = true;
};