File upload improvements: "/ufsu" api mode, no interrupts disanling, cleaner confirmation page (#24521)

This commit is contained in:
s-hadinger
2026-03-04 10:43:14 +01:00
committed by GitHub
parent 7568d932f3
commit 78af45cfda
4 changed files with 42 additions and 10 deletions
+11
View File
@@ -386,6 +386,17 @@ enum EmulationOptions {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
enum TopicOptions { CMND, STAT, TELE, nu1, RESULT_OR_CMND, RESULT_OR_STAT, RESULT_OR_TELE };
// Upload type used by HandleUploadLoop() to route incoming data.
// Value 0 is invalid/unset. Each upload endpoint must set the appropriate
// type before HandleUploadLoop() processes the first data block.
// UPL_TASMOTA - OTA firmware update (/u2)
// UPL_SETTINGS - Settings backup restore (/u2)
// UPL_EFM8BB1 - Sonoff RF bridge EFM8BB1 firmware
// UPL_TASMOTACLIENT - Tasmota client (Arduino) hex file
// UPL_EFR32 - Zigbee EZSP (EFR32) firmware
// UPL_SHD - Shelly dimmer firmware
// UPL_CCL - CC2530 Zigbee firmware via CCLoader
// UPL_UFSFILE - Filesystem file upload (/ufsu)
enum UploadTypes { UPL_TASMOTA = 1, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT, UPL_EFR32, UPL_SHD, UPL_CCL, UPL_UFSFILE };
enum ExecuteCommandPowerOptions { POWER_OFF, POWER_ON, POWER_TOGGLE, POWER_BLINK, POWER_BLINK_STOP, POWER_OFF_FORCE,
@@ -3502,7 +3502,9 @@ void HandleUploadLoop(void) {
if (Web.upload_error) {
if (!upload_error_signalled) {
if (UPL_TASMOTA == Web.upload_file_type) { Update.end(); }
UploadServices(1);
if (UPL_UFSFILE != Web.upload_file_type) {
UploadServices(1);
}
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "Upload error %d"), Web.upload_error);
@@ -3522,7 +3524,10 @@ void HandleUploadLoop(void) {
WebGetArg("fsz", tmp, sizeof(tmp)); // filesize
upload_size = (!strlen(tmp)) ? 0 : atoi(tmp);
UploadServices(0);
// Filesystem uploads don't need to disable interrupts/services
if (UPL_UFSFILE != Web.upload_file_type) {
UploadServices(0);
}
if (0 == upload.filename.c_str()[0]) {
Web.upload_error = 1; // No file selected
@@ -3667,7 +3672,9 @@ void HandleUploadLoop(void) {
// ***** Step3: Finish upload file
else if (UPLOAD_FILE_END == upload.status) {
UploadServices(1);
if (UPL_UFSFILE != Web.upload_file_type) {
UploadServices(1);
}
if (UPL_SETTINGS == Web.upload_file_type) {
if (!SettingsConfigRestore()) {
Web.upload_error = 8; // File invalid
@@ -3733,7 +3740,9 @@ void HandleUploadLoop(void) {
// ***** Step4: Abort upload file
else {
UploadServices(1);
if (UPL_UFSFILE != Web.upload_file_type) {
UploadServices(1);
}
Web.upload_error = 7; // Upload aborted
if (UPL_TASMOTA == Web.upload_file_type) { Update.end(); }
}
@@ -1353,6 +1353,21 @@ const char HTTP_EDITOR_FORM_END[] PROGMEM =
#endif // #ifdef GUI_EDIT_FILE
// Wrapper around HandleUploadLoop() for /ufsu file uploads.
// HandleUploadLoop() is shared between OTA firmware updates (/u2) and filesystem
// uploads (/ufsu), and uses Web.upload_file_type to distinguish them.
// When uploading via the web UI, the browser first does a GET which calls
// UfsDirectory() and sets upload_file_type = UPL_UFSFILE. But direct POST
// requests (e.g. curl -F "file=@..." /ufsu) skip the GET, leaving
// upload_file_type unset and causing HandleUploadLoop() to treat the file
// as a firmware image, which fails.
// This wrapper ensures upload_file_type is always set before entering the
// shared upload handler.
void HandleUploadUFSLoop(void) {
Web.upload_file_type = UPL_UFSFILE;
HandleUploadLoop();
}
void HandleUploadUFSDone(void) {
if (!HttpCheckPriviledgedAccess()) { return; }
@@ -1382,7 +1397,7 @@ void HandleUploadUFSDone(void) {
}
WSContentSend_P(PSTR("</div><br>"));
XdrvCall(FUNC_WEB_ADD_MANAGEMENT_BUTTON);
WSContentSend_PD(UFS_WEB_DIR, "/", PSTR(D_MANAGE_FILE_SYSTEM));
WSContentStop();
}
@@ -1974,13 +1989,9 @@ bool Xdrv50(uint32_t function) {
}
break;
case FUNC_WEB_ADD_HANDLER:
// Webserver->on(F("/ufsd"), UfsDirectory);
// Webserver->on(F("/ufsu"), HTTP_GET, UfsDirectory);
// Webserver->on(F("/ufsu"), HTTP_POST,[](){Webserver->sendHeader(F("Location"),F("/ufsu"));Webserver->send(303);}, HandleUploadLoop);
Webserver->on("/ufsd", UfsDirectory);
Webserver->on("/ufsu", HTTP_GET, UfsDirectory);
//Webserver->on("/ufsu", HTTP_POST,[](){Webserver->sendHeader(F("Location"),F("/ufsu"));Webserver->send(303);}, HandleUploadLoop);
Webserver->on("/ufsu", HTTP_POST, HandleUploadUFSDone, HandleUploadLoop);
Webserver->on("/ufsu", HTTP_POST, HandleUploadUFSDone, HandleUploadUFSLoop);
#ifdef GUI_EDIT_FILE
Webserver->on("/ufse", HTTP_GET, UfsEditor);
Webserver->on("/ufse", HTTP_POST, UfsEditorUpload);