summaryrefslogtreecommitdiff
path: root/libraries/ESP_Async_WebServer/examples/PartitionDownloader
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ESP_Async_WebServer/examples/PartitionDownloader')
-rw-r--r--libraries/ESP_Async_WebServer/examples/PartitionDownloader/PartitionDownloader.ino130
1 files changed, 130 insertions, 0 deletions
diff --git a/libraries/ESP_Async_WebServer/examples/PartitionDownloader/PartitionDownloader.ino b/libraries/ESP_Async_WebServer/examples/PartitionDownloader/PartitionDownloader.ino
new file mode 100644
index 0000000..3c76366
--- /dev/null
+++ b/libraries/ESP_Async_WebServer/examples/PartitionDownloader/PartitionDownloader.ino
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
+
+//
+// - Download ESP32 partition by name and/or type and/or subtype
+// - Support encrypted and non-encrypted partitions
+//
+
+#include <Arduino.h>
+#ifdef ESP32
+#include <AsyncTCP.h>
+#include <WiFi.h>
+#elif defined(ESP8266)
+#include <ESP8266WiFi.h>
+#include <ESPAsyncTCP.h>
+#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
+#include <RPAsyncTCP.h>
+#include <WiFi.h>
+#endif
+
+#include <ESPAsyncWebServer.h>
+#include <LittleFS.h>
+
+#ifndef ESP32
+// this example is only for the ESP32
+void setup() {}
+void loop() {}
+#else
+
+#include <esp_partition.h>
+
+static AsyncWebServer server(80);
+
+void setup() {
+ Serial.begin(115200);
+
+#ifndef CONFIG_IDF_TARGET_ESP32H2
+ WiFi.mode(WIFI_AP);
+ WiFi.softAP("esp-captive");
+#endif
+
+ LittleFS.begin(true);
+
+ // To upload the FS partition, run:
+ // > pio run -e arduino-3 -t buildfs
+ // > pio run -e arduino-3 -t uploadfs
+ //
+ // Examples:
+ //
+ // - Download the partition named "spiffs": http://192.168.4.1/partition?label=spiffs
+ // - Download the partition named "spiffs" with type "data": http://192.168.4.1/partition?label=spiffs&type=1
+ // - Download the partition named "spiffs" with type "data" and subtype "spiffs": http://192.168.4.1/partition?label=spiffs&type=1&subtype=130
+ // - Download the partition with subtype "nvs": http://192.168.4.1/partition?type=1&subtype=2
+ //
+ // "type" and "subtype" IDs can be found in esp_partition.h header file.
+ //
+ // Add "&raw=false" parameter to download the partition unencrypted (for encrypted partitions).
+ // By default, the raw partition is downloaded, so if a partition is encrypted, the encrypted data will be downloaded.
+ //
+ // To browse a downloaded LittleFS partition, you can use https://tniessen.github.io/littlefs-disk-img-viewer/ (block size is 4096)
+ //
+ server.on("/partition", HTTP_GET, [](AsyncWebServerRequest *request) {
+ const AsyncWebParameter *pLabel = request->getParam("label");
+ const AsyncWebParameter *pType = request->getParam("type");
+ const AsyncWebParameter *pSubtype = request->getParam("subtype");
+ const AsyncWebParameter *pRaw = request->getParam("raw");
+
+ if (!pLabel && !pType && !pSubtype) {
+ request->send(400, "text/plain", "Bad request: missing parameter");
+ return;
+ }
+
+ esp_partition_type_t type = ESP_PARTITION_TYPE_ANY;
+ esp_partition_subtype_t subtype = ESP_PARTITION_SUBTYPE_ANY;
+ const char *label = nullptr;
+ bool raw = true;
+
+ if (pLabel) {
+ label = pLabel->value().c_str();
+ }
+
+ if (pType) {
+ type = (esp_partition_type_t)pType->value().toInt();
+ }
+
+ if (pSubtype) {
+ subtype = (esp_partition_subtype_t)pSubtype->value().toInt();
+ }
+
+ if (pRaw && pRaw->value() == "false") {
+ raw = false;
+ }
+
+ const esp_partition_t *partition = esp_partition_find_first(type, subtype, label);
+
+ if (!partition) {
+ request->send(404, "text/plain", "Partition not found");
+ return;
+ }
+
+ AsyncWebServerResponse *response =
+ request->beginChunkedResponse("application/octet-stream", [partition, raw](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
+ const size_t remaining = partition->size - index;
+ if (!remaining) {
+ return 0;
+ }
+ const size_t len = std::min(maxLen, remaining);
+ if (raw && esp_partition_read_raw(partition, index, buffer, len) == ESP_OK) {
+ return len;
+ }
+ if (!raw && esp_partition_read(partition, index, buffer, len) == ESP_OK) {
+ return len;
+ }
+ return 0;
+ });
+
+ response->addHeader("Content-Disposition", "attachment; filename=" + String(partition->label) + ".bin");
+ response->setContentLength(partition->size);
+
+ request->send(response);
+ });
+
+ server.begin();
+}
+
+void loop() {
+ delay(100);
+}
+
+#endif