fix: restore reads the options the web UI ticks

The web UI sends the restore options as the form field "data". The
param helpers looked up query parameters only, so /restore never saw
them and restored the shades alone, since 3.0.0. The helpers now take a
form field too.

/restore uses an upload once, and drops the file when the options aren't
JSON.

e2e: test_restore.py, a probe that the field is read and, with --reboot,
a settings-only round trip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-28 21:02:39 +01:00
parent 0ee52d6d9f
commit 3d45ba59c1
8 changed files with 97 additions and 18 deletions

View file

@ -143,13 +143,18 @@ bool Web::createAPIToken(const IPAddress ipAddress, char *token) {
// =====================================================
// Async API Handlers
// =====================================================
// Helper: get a query param as String, or empty if missing
// The library keeps query parameters and form fields apart, and looks up only
// the first unless asked. /restore's options come as a form field.
static const AsyncWebParameter *queryOrFormParam(AsyncWebServerRequest *request, const char *name) {
const AsyncWebParameter *p = request->getParam(name);
return p ? p : request->getParam(name, true);
}
String asyncParam(AsyncWebServerRequest *request, const char *name) {
if(request->hasParam(name)) return request->getParam(name)->value();
return String();
const AsyncWebParameter *p = queryOrFormParam(request, name);
return p ? p->value() : String();
}
bool asyncHasParam(AsyncWebServerRequest *request, const char *name) {
return request->hasParam(name);
return queryOrFormParam(request, name) != nullptr;
}
// -- Serialization helpers --