[Web UI] Do not POST rules parameters to save memory

The `rules` parameter is disabled when changing the rules set.
Otherwise it might create a POST request the size of the current rule page, which does consume at least twice the size of it in RAM.
This commit is contained in:
TD-er
2021-08-12 20:07:04 +02:00
parent ca778ad788
commit 5634f4eabf
10 changed files with 70 additions and 122 deletions
-4
View File
@@ -25,10 +25,6 @@ unsigned long timerAwakeFromDeepSleep = 0;
float vcc = -1.0f;
#endif
boolean WebLoggedIn = false;
int WebLoggedInTimer = 300;
IPAddress WebLoggedInClientIP;
String dummyString; // FIXME @TD-er This may take a lot of memory over time, since long-lived Strings only tend to grow.
-4
View File
@@ -92,10 +92,6 @@ extern unsigned long timerAwakeFromDeepSleep;
extern float vcc;
#endif
extern boolean WebLoggedIn;
extern int WebLoggedInTimer;
extern IPAddress WebLoggedInClientIP;
extern String dummyString; // FIXME @TD-er This may take a lot of memory over time, since long-lived Strings only tend to grow.
-10
View File
@@ -172,16 +172,6 @@ void runOncePerSecond()
// unsigned long elapsed = micros() - start;
if (SecuritySettings.Password[0] != 0)
{
if (WebLoggedIn)
WebLoggedInTimer++;
if (WebLoggedInTimer > 300) {
WebLoggedIn = false;
WebLoggedInClientIP = IPAddress();
}
}
// I2C Watchdog feed
if (Settings.WDI2CAddress != 0)
{
+1
View File
@@ -272,6 +272,7 @@ void html_add_form() {
void html_add_autosubmit_form() {
addHtml(F("<script><!--\n"
"function dept_onchange(frmselect) {frmselect.submit();}"
"function rules_set_onchange(rulesselect) {document.getElementById('rules').disabled = true; rulesselect.submit();}"
"\n//--></script>"));
}
-13
View File
@@ -1,13 +0,0 @@
#ifndef WEBSERVER_WEBSERVER_LOGIN_H
#define WEBSERVER_WEBSERVER_LOGIN_H
#include "../WebServer/common.h"
// ********************************************************************************
// Web Interface login page
// ********************************************************************************
void handle_login();
#endif
+27
View File
@@ -90,6 +90,33 @@ void addSelector(const String & id,
addSelector_Foot();
}
void addSelector_reloadOnChange(
const String& id,
int optionCount,
const String options[],
const int indices[],
const String attr[],
int selectedIndex,
const String& onChangeCall,
bool enabled,
const String& classname
#ifdef ENABLE_TOOLTIPS
,
const String& tooltip
#endif // ifdef ENABLE_TOOLTIPS
)
{
// FIXME TD-er Change boolean to disabled
do_addSelector_Head(id, classname, onChangeCall, !enabled
#ifdef ENABLE_TOOLTIPS
, tooltip
#endif // ifdef ENABLE_TOOLTIPS
);
addSelector_options(optionCount, options, indices, attr, selectedIndex);
addSelector_Foot();
}
void addSelector(const String & id,
int optionCount,
const String options[],
+17
View File
@@ -71,6 +71,23 @@ void addSelector(const String& id,
#endif // ifdef ENABLE_TOOLTIPS
);
void addSelector_reloadOnChange(
const String& id,
int optionCount,
const String options[],
const int indices[],
const String attr[],
int selectedIndex,
const String& onChangeCall,
bool enabled,
const String& classname
#ifdef ENABLE_TOOLTIPS
,
const String& tooltip = EMPTY_STRING
#endif // ifdef ENABLE_TOOLTIPS
);
void addSelector_options(int optionCount,
const __FlashStringHelper *options[],
const int indices[],
+14 -2
View File
@@ -66,7 +66,10 @@ void handle_rules() {
html_table_header(F("Rules"));
html_TR_TD();
html_add_form();
// Need a separate script to only include the 'set' attribute and not also
// send the 'rules' as that will need a lot of memory on the ESP to process.
addHtml(F("<form id='rulesselect' name='rulesselect' method='get'>"));
{
// Place combo box in its own scope to release these arrays as soon as possible
uint8_t choice = rulesSet;
@@ -80,7 +83,16 @@ void handle_rules() {
optionValues[x] = x + 1;
}
addSelector(F("set"), RULESETS_MAX, options, optionValues, NULL, choice, true, true);
addSelector_reloadOnChange(
F("set"),
RULESETS_MAX,
options,
optionValues,
NULL,
choice,
F("return rules_set_onchange(rulesselect)"),
true,
F("wide"));
addHelpButton(F("Tutorial_Rules"));
addRTDHelpButton(F("Rules/Rules.html"));
}
+11 -10
View File
@@ -19,7 +19,6 @@
#include "../WebServer/JSON.h"
#include "../WebServer/LoadFromFS.h"
#include "../WebServer/Log.h"
#include "../WebServer/Login.h"
#include "../WebServer/Markup.h"
#include "../WebServer/Markup_Buttons.h"
#include "../WebServer/Markup_Forms.h"
@@ -47,6 +46,7 @@
#include "../DataTypes/SettingsType.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
#include "../ESPEasyCore/ESPEasyRules.h"
#include "../ESPEasyCore/ESPEasyWifi.h"
#include "../Globals/CPlugins.h"
@@ -347,7 +347,6 @@ void WebServerInit()
web_server.on(F("/json"), handle_json); // Also part of WEBSERVER_NEW_UI
web_server.on(F("/csv"), handle_csvval);
web_server.on(F("/log"), handle_log);
web_server.on(F("/login"), handle_login);
web_server.on(F("/logjson"), handle_log_JSON); // Also part of WEBSERVER_NEW_UI
#ifdef USES_NOTIFIER
web_server.on(F("/notifications"), handle_notifications);
@@ -969,6 +968,7 @@ void addTaskValueSelect(const String& name, int choice, taskIndex_t TaskIndex)
}
}
// ********************************************************************************
// Login state check
// ********************************************************************************
@@ -977,11 +977,6 @@ bool isLoggedIn(bool mustProvideLogin)
if (!clientIPallowed()) { return false; }
if (SecuritySettings.Password[0] == 0) { return true; }
if (WebLoggedIn && WebLoggedInClientIP == web_server.client().remoteIP()) {
WebLoggedInTimer = 0;
return true;
}
{
String www_username = F(DEFAULT_ADMIN_USERNAME);
if (!web_server.authenticate(www_username.c_str(), SecuritySettings.Password))
@@ -1005,12 +1000,18 @@ bool isLoggedIn(bool mustProvideLogin)
message += www_username;
message += ')';
web_server.requestAuthentication(mode, message.c_str());
if (Settings.UseRules)
{
String event = F("Login#Failed");
// TD-er: Do not add to the eventQueue, but execute right now.
rulesProcessing(event);
}
return false;
}
}
WebLoggedIn = true;
WebLoggedInTimer = 0;
WebLoggedInClientIP = web_server.client().remoteIP();
return true;
}
-79
View File
@@ -1,79 +0,0 @@
#include "../WebServer/Login.h"
#include "../WebServer/WebServer.h"
#include "../WebServer/AccessControl.h"
#include "../WebServer/HTML_wrappers.h"
#include "../WebServer/Markup.h"
#include "../WebServer/Markup_Buttons.h"
#include "../ESPEasyCore/ESPEasyRules.h"
#include "../Globals/SecuritySettings.h"
#include "../Globals/Settings.h"
#include "../../ESPEasy-Globals.h"
// ********************************************************************************
// Web Interface login page
// ********************************************************************************
void handle_login() {
#ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("handle_login"));
#endif // ifndef BUILD_NO_RAM_TRACKER
if (!clientIPallowed()) { return; }
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
String webrequest = webArg(F("password"));
addHtml(F("<form method='post'>"));
html_table_class_normal();
addHtml(F("<TR><TD>Password<TD>"));
addHtml(F("<input "));
addHtmlAttribute(F("class"), F("wide"));
addHtmlAttribute(F("type"), F("password"));
addHtmlAttribute(F("name"), F("password"));
addHtmlAttribute(F("value"), webrequest);
addHtml('>');
html_TR_TD();
html_TD();
addSubmitButton();
html_TR_TD();
html_end_table();
html_end_form();
if (!webrequest.isEmpty())
{
char command[80];
command[0] = 0;
webrequest.toCharArray(command, 80);
// compare with stored password and set timer if there's a match
if ((strcasecmp(command, SecuritySettings.Password) == 0) || (SecuritySettings.Password[0] == 0))
{
WebLoggedIn = true;
WebLoggedInTimer = 0;
WebLoggedInClientIP = web_server.client().remoteIP();
addHtml(F("<script>window.location = '.'</script>"));
}
else
{
addHtml(F("Invalid password!"));
if (Settings.UseRules)
{
String event = F("Login#Failed");
// TD-er: Do not add to the eventQueue, but execute right now.
rulesProcessing(event);
}
}
}
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
printWebString = "";
printToWeb = false;
}