Fix: avoid deprecated setAuthentication() to fix memory exhaustion
with ESPAsyncWebServer 3.3.0, the setAuthentication() method became
deprecated and a replacement method was provided which acts as a shim
and uses the new middleware-based approach to setup authentication. in
order to eventually apply a changed "read-only access allowed" setting,
the setAuthentication() method was called periodically. the shim
implementation each time allocates a new AuthenticationMiddleware and
adds it to the chain of middlewares, eventually exhausting the memory.
we now use the new middleware-based approach ourselves and only add the
respective AuthenticatonMiddleware instance once to the respective
websocket server instance.
a regression where enabling unauthenticated read-only access is not
applied until reboot is also fixed. all the AuthenticationMiddleware
instances were never removed from the chain of middlewares when calling
setAuthentication("", "").
This commit is contained in:
parent
b206cee820
commit
ebb225f6c0
@ -30,6 +30,7 @@ class WebApiClass {
|
|||||||
public:
|
public:
|
||||||
WebApiClass();
|
WebApiClass();
|
||||||
void init(Scheduler& scheduler);
|
void init(Scheduler& scheduler);
|
||||||
|
void reload();
|
||||||
|
|
||||||
static bool checkCredentials(AsyncWebServerRequest* request);
|
static bool checkCredentials(AsyncWebServerRequest* request);
|
||||||
static bool checkCredentialsReadonly(AsyncWebServerRequest* request);
|
static bool checkCredentialsReadonly(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -8,9 +8,11 @@ class WebApiWsConsoleClass {
|
|||||||
public:
|
public:
|
||||||
WebApiWsConsoleClass();
|
WebApiWsConsoleClass();
|
||||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
|
void reload();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AsyncWebSocket _ws;
|
AsyncWebSocket _ws;
|
||||||
|
AuthenticationMiddleware _simpleDigestAuth;
|
||||||
|
|
||||||
Task _wsCleanupTask;
|
Task _wsCleanupTask;
|
||||||
void wsCleanupTaskCb();
|
void wsCleanupTaskCb();
|
||||||
|
|||||||
@ -11,6 +11,7 @@ class WebApiWsLiveClass {
|
|||||||
public:
|
public:
|
||||||
WebApiWsLiveClass();
|
WebApiWsLiveClass();
|
||||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
|
void reload();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void generateInverterCommonJsonResponse(JsonObject& root, std::shared_ptr<InverterAbstract> inv);
|
static void generateInverterCommonJsonResponse(JsonObject& root, std::shared_ptr<InverterAbstract> inv);
|
||||||
@ -24,6 +25,7 @@ private:
|
|||||||
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
|
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
|
||||||
|
|
||||||
AsyncWebSocket _ws;
|
AsyncWebSocket _ws;
|
||||||
|
AuthenticationMiddleware _simpleDigestAuth;
|
||||||
|
|
||||||
uint32_t _lastPublishStats[INV_MAX_COUNT] = { 0 };
|
uint32_t _lastPublishStats[INV_MAX_COUNT] = { 0 };
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,12 @@ void WebApiClass::init(Scheduler& scheduler)
|
|||||||
_server.begin();
|
_server.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebApiClass::reload()
|
||||||
|
{
|
||||||
|
_webApiWsConsole.reload();
|
||||||
|
_webApiWsLive.reload();
|
||||||
|
}
|
||||||
|
|
||||||
bool WebApiClass::checkCredentials(AsyncWebServerRequest* request)
|
bool WebApiClass::checkCredentials(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
CONFIG_T& config = Configuration.get();
|
CONFIG_T& config = Configuration.get();
|
||||||
|
|||||||
@ -71,6 +71,8 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request)
|
|||||||
WebApi.writeConfig(retMsg);
|
WebApi.writeConfig(retMsg);
|
||||||
|
|
||||||
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
||||||
|
|
||||||
|
WebApi.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiSecurityClass::onAuthenticateGet(AsyncWebServerRequest* request)
|
void WebApiSecurityClass::onAuthenticateGet(AsyncWebServerRequest* request)
|
||||||
|
|||||||
@ -21,16 +21,27 @@ void WebApiWsConsoleClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
|||||||
|
|
||||||
scheduler.addTask(_wsCleanupTask);
|
scheduler.addTask(_wsCleanupTask);
|
||||||
_wsCleanupTask.enable();
|
_wsCleanupTask.enable();
|
||||||
|
|
||||||
|
_simpleDigestAuth.setUsername(AUTH_USERNAME);
|
||||||
|
_simpleDigestAuth.setRealm("console websocket");
|
||||||
|
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebApiWsConsoleClass::reload()
|
||||||
|
{
|
||||||
|
_ws.removeMiddleware(&_simpleDigestAuth);
|
||||||
|
|
||||||
|
auto const& config = Configuration.get();
|
||||||
|
|
||||||
|
if (config.Security.AllowReadonly) { return; }
|
||||||
|
|
||||||
|
_simpleDigestAuth.setPassword(config.Security.Password);
|
||||||
|
_ws.addMiddleware(&_simpleDigestAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsConsoleClass::wsCleanupTaskCb()
|
void WebApiWsConsoleClass::wsCleanupTaskCb()
|
||||||
{
|
{
|
||||||
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
||||||
_ws.cleanupClients();
|
_ws.cleanupClients();
|
||||||
|
|
||||||
if (Configuration.get().Security.AllowReadonly) {
|
|
||||||
_ws.setAuthentication("", "");
|
|
||||||
} else {
|
|
||||||
_ws.setAuthentication(AUTH_USERNAME, Configuration.get().Security.Password);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,18 +36,28 @@ void WebApiWsLiveClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
|||||||
|
|
||||||
scheduler.addTask(_sendDataTask);
|
scheduler.addTask(_sendDataTask);
|
||||||
_sendDataTask.enable();
|
_sendDataTask.enable();
|
||||||
|
_simpleDigestAuth.setUsername(AUTH_USERNAME);
|
||||||
|
_simpleDigestAuth.setRealm("live websocket");
|
||||||
|
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebApiWsLiveClass::reload()
|
||||||
|
{
|
||||||
|
_ws.removeMiddleware(&_simpleDigestAuth);
|
||||||
|
|
||||||
|
auto const& config = Configuration.get();
|
||||||
|
|
||||||
|
if (config.Security.AllowReadonly) { return; }
|
||||||
|
|
||||||
|
_simpleDigestAuth.setPassword(config.Security.Password);
|
||||||
|
_ws.addMiddleware(&_simpleDigestAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsLiveClass::wsCleanupTaskCb()
|
void WebApiWsLiveClass::wsCleanupTaskCb()
|
||||||
{
|
{
|
||||||
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
||||||
_ws.cleanupClients();
|
_ws.cleanupClients();
|
||||||
|
|
||||||
if (Configuration.get().Security.AllowReadonly) {
|
|
||||||
_ws.setAuthentication("", "");
|
|
||||||
} else {
|
|
||||||
_ws.setAuthentication(AUTH_USERNAME, Configuration.get().Security.Password);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsLiveClass::sendDataTaskCb()
|
void WebApiWsLiveClass::sendDataTaskCb()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user