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

View File

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

View File

@ -379,7 +379,14 @@ void WebServer::readClient()
// Verify if we habe a resource for this request // Verify if we habe a resource for this request
foreach (WebServerResource *resource, m_resources) { foreach (WebServerResource *resource, m_resources) {
if (request.url().path().startsWith(resource->basePath())) { 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(); qCDebug(dcDebugServer()) << "Request:" << request.url().toString();
HttpReply *reply = resource->processRequest(request); HttpReply *reply = resource->processRequest(request);
reply->setClientId(clientId); reply->setClientId(clientId);

View File

@ -317,6 +317,15 @@ States Thing::states() const
return m_states; 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. */ /*! Returns true, a \l{Param} with the given \a paramTypeId exists for this thing. */
bool Thing::hasParam(const ParamTypeId &paramTypeId) const bool Thing::hasParam(const ParamTypeId &paramTypeId) const
{ {

View File

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

View File

@ -197,6 +197,14 @@ HttpReply *HttpReply::createSuccessReply()
return reply; 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 *HttpReply::createErrorReply(const HttpReply::HttpStatusCode &statusCode)
{ {
HttpReply *reply = new HttpReply(statusCode, HttpReply::TypeSync); HttpReply *reply = new HttpReply(statusCode, HttpReply::TypeSync);
@ -389,6 +397,12 @@ QByteArray HttpReply::getHttpReasonPhrase(const HttpReply::HttpStatusCode &statu
case BadRequest: case BadRequest:
response = QString("Bad Request").toUtf8(); response = QString("Bad Request").toUtf8();
break; break;
case Unauthorized:
response = QString("Unauthorized").toUtf8();
break;
case PaymentRequired:
response = QString("Payment required").toUtf8();
break;
case Forbidden: case Forbidden:
response = QString("Forbidden").toUtf8(); response = QString("Forbidden").toUtf8();
break; break;
@ -398,6 +412,9 @@ QByteArray HttpReply::getHttpReasonPhrase(const HttpReply::HttpStatusCode &statu
case MethodNotAllowed: case MethodNotAllowed:
response = QString("Method Not Allowed").toUtf8(); response = QString("Method Not Allowed").toUtf8();
break; break;
case NotAcceptable:
response = QString("Not Acceptable").toUtf8();
break;
case RequestTimeout: case RequestTimeout:
response = QString("Request Timeout").toUtf8(); response = QString("Request Timeout").toUtf8();
break; break;

View File

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

View File

@ -45,10 +45,24 @@ QString WebServerResource::basePath() const
return m_basePath; 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) HttpReply *WebServerResource::createFileReply(const QString fileName)
{ {
qCDebug(dcWebServer()) << "Create file reply for" << fileName; qCDebug(dcWebServer()) << "Create file reply for" << fileName;
HttpReply *reply = HttpReply::createSuccessReply();
QFile file(fileName); QFile file(fileName);
if (!file.open(QFile::ReadOnly)) { if (!file.open(QFile::ReadOnly)) {
@ -56,6 +70,8 @@ HttpReply *WebServerResource::createFileReply(const QString fileName)
return HttpReply::createErrorReply(HttpReply::Forbidden); return HttpReply::createErrorReply(HttpReply::Forbidden);
} }
HttpReply *reply = HttpReply::createSuccessReply();
// Check content type // Check content type
if (file.fileName().endsWith(".html")) { if (file.fileName().endsWith(".html")) {
reply->setHeader(HttpReply::ContentTypeHeader, "text/html; charset=\"utf-8\";"); reply->setHeader(HttpReply::ContentTypeHeader, "text/html; charset=\"utf-8\";");

View File

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