mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
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:
parent
0ee52d6d9f
commit
3d45ba59c1
8 changed files with 97 additions and 18 deletions
|
|
@ -93,7 +93,11 @@ void registerHttpRoutes(AsyncWebServer &server) {
|
|||
|
||||
server.on(AsyncURIMatcher::exact("/restore"), HTTP_POST,
|
||||
[](AsyncWebServerRequest *request) {
|
||||
if(webServer.uploadSuccess) {
|
||||
// An upload is restored once: a later /restore without a file must not
|
||||
// find this one.
|
||||
const bool uploaded = webServer.uploadSuccess;
|
||||
webServer.uploadSuccess = false;
|
||||
if(uploaded) {
|
||||
restore_options_t opts;
|
||||
if(asyncHasParam(request, "data")) {
|
||||
String dataStr = asyncParam(request, "data");
|
||||
|
|
@ -101,6 +105,7 @@ void registerHttpRoutes(AsyncWebServer &server) {
|
|||
JsonDocument doc;
|
||||
DeserializationError err = deserializeJson(doc, dataStr);
|
||||
if(err) {
|
||||
LittleFS.remove("/shades.tmp");
|
||||
request->send(500, _encoding_json, "{\"status\":\"ERROR\",\"desc\":\"JSON parse error\"}");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 --
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ extern const char _encoding_json[];
|
|||
// Hands an item to loop(), which owns the shades. When it can't be the
|
||||
// request is answered with the reason and false is returned.
|
||||
bool queueLoopItem(AsyncWebServerRequest *request, const loop_item_t &item);
|
||||
// A query parameter, or an empty string when it is missing.
|
||||
// A query parameter or form field, or an empty string when it is missing.
|
||||
String asyncParam(AsyncWebServerRequest *request, const char *name);
|
||||
bool asyncHasParam(AsyncWebServerRequest *request, const char *name);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue