From 10ab75c055b2597a82b93b0e66b3af157b0c6d64 Mon Sep 17 00:00:00 2001 From: Konstantin <4959583+cstantin@users.noreply.github.com> Date: Tue, 23 Dec 2025 11:32:40 +0300 Subject: [PATCH] feat: dynamic filenames for backup/debug (#207) * feat: generate dynamic filenames for JSON file downloads (backup and debug) based on hostname and timestamp * fix: threadsafe getFilename --- src/PortalTask.h | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/PortalTask.h b/src/PortalTask.h index 0968de8..662e0e5 100644 --- a/src/PortalTask.h +++ b/src/PortalTask.h @@ -241,7 +241,17 @@ protected: doc.shrinkToFit(); - this->webServer->sendHeader(F("Content-Disposition"), F("attachment; filename=\"backup.json\"")); + char filename[64]; + getFilename(filename, sizeof(filename), "backup"); + + char contentDispositionHeaderValue[128]; + snprintf_P( + contentDispositionHeaderValue, + sizeof(contentDispositionHeaderValue), + PSTR("attachment; filename=\"%s\""), + filename + ); + this->webServer->sendHeader(F("Content-Disposition"), contentDispositionHeaderValue); this->bufferedWebServer->send(200, F("application/json"), doc); }); @@ -839,7 +849,18 @@ protected: doc.shrinkToFit(); - this->webServer->sendHeader(F("Content-Disposition"), F("attachment; filename=\"debug.json\"")); + char filename[64]; + getFilename(filename, sizeof(filename), "debug"); + + char contentDispositionHeaderValue[128]; + snprintf_P( + contentDispositionHeaderValue, + sizeof(contentDispositionHeaderValue), + PSTR("attachment; filename=\"%s\""), + filename + ); + + this->webServer->sendHeader(F("Content-Disposition"), contentDispositionHeaderValue); this->bufferedWebServer->send(200, F("application/json"), doc, true); }); @@ -1046,4 +1067,12 @@ protected: this->dnsServer->stop(); this->dnsServerEnabled = false; } + + static void getFilename(char* filename, size_t maxSizeFilename, const char* type) { + const time_t now = time(nullptr); + const tm* localNow = localtime(&now); + char localNowValue[20]; + strftime(localNowValue, sizeof(localNowValue), PSTR("%Y-%m-%d-%H-%M-%S"), localNow); + snprintf_P(filename, maxSizeFilename, PSTR("%s_%s_%s.json"), networkSettings.hostname, localNowValue, type); + } }; \ No newline at end of file