espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.42k stars 7.37k forks source link

httpupdateserver filesystem update "Update error: Bad Size Given" for 8MB version of ESP32 #9967

Open kapyaar opened 3 months ago

kapyaar commented 3 months ago

Board

ESP32 Dev Module, 8MB Flash

Device Description

ESP32 Dev Module, 8MB flash

Hardware Configuration

8MB ESP32 Dev Module. No attachments

Version

latest master (checkout manually)

IDE Name

Arduino IDE 2.3.2

Operating System

Windows 11

Flash frequency

40MHz

PSRAM enabled

no

Upload speed

921600

Description

I am using 8MB ESP32 Dev Module, with the following IDE settings.

image

I use arduino IDE 2.3.2 for firmware but go back to 1.8.9 to use the ESP32 Sketch Data Upload Tool using spiffs. This works fine when using the IDE. But if I take the same spiffs file that is generated using the mkspiffs tool, use the webupdater.ino example, and use the Filesystem update option, It throws

Update error: Bad Size Given

Sketch

Examples>WebUpdater.ino

Debug Message

rst:0xb (TGWDT_CPU_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1448
load:0x40078000,len:14844
ho 0 tail 12 room 4
load:0x40080400,len:4
load:0x40080404,len:3356
[     1][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RX (2) successfully set to 0x400e4838
[    12][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_TX (3) successfully set to 0x400e4808
[    26][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_CTS (4) successfully set to 0x400e47d8
[    39][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RTS (5) successfully set to 0x400e47a8
[    53][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RX (2) successfully set to 0x400e4838
[    66][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_TX (3) successfully set to 0x400e4808
[    79][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_CTS (4) successfully set to 0x400e47d8
[    93][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RTS (5) successfully set to 0x400e47a8
[   106][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RX (2) successfully set to 0x400e4838
[   120][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_TX (3) successfully set to 0x400e4808
[   133][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_CTS (4) successfully set to 0x400e47d8
[   147][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RTS (5) successfully set to 0x400e47a8
[   160][V][NetworkServer.h:41] NetworkServer(): NetworkServer::NetworkServer(port=80, ...)
[   171][V][WebServer.cpp:55] WebServer(): WebServer::Webserver(port=80)
[   181][D][esp32-hal-cpu.c:264] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
[   235][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 3 successfully set to type UART_RX (2) with bus 0x3ffbdb7c
[   246][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 1 successfully set to type UART_TX (3) with bus 0x3ffbdb7c
entry 0x4008059c
[   235][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 3 successfully set to type UART_RX (2) with bus 0x3ffbdb7c
[   246][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 1 successfully set to type UART_TX (3) with bus 0x3ffbdb7c
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32
  Package           : D0WD-Q5
  Revision          : 101
  Cores             : 2
  CPU Frequency     : 240 MHz
  XTAL Frequency    : 40 MHz
  Embedded Flash    : No
  Embedded PSRAM    : No
  2.4GHz WiFi       : Yes
  Classic BT        : Yes
  BT Low Energy     : Yes
  IEEE 802.15.4     : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   333752 B ( 325.9 KB)
  Free Bytes        :   303112 B ( 296.0 KB)
  Allocated Bytes   :    23512 B (  23.0 KB)
  Minimum Free Bytes:   297596 B ( 290.6 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
  Chip Size         :  8388608 B (8 MB)
  Block Size        :    65536 B (  64.0 KB)
  Sector Size       :     4096 B (   4.0 KB)
  Page Size         :      256 B (   0.2 KB)
  Bus Speed         : 80 MHz
  Bus Mode          : QIO
------------------------------------------
Partitions Info:
------------------------------------------
                nvs : addr: 0x00009000, size:    20.0 KB, type: DATA, subtype: NVS
            otadata : addr: 0x0000E000, size:     8.0 KB, type: DATA, subtype: OTA
               app0 : addr: 0x00010000, size:  3264.0 KB, type:  APP, subtype: OTA_0
               app1 : addr: 0x00340000, size:  3264.0 KB, type:  APP, subtype: OTA_1
             spiffs : addr: 0x00670000, size:  1536.0 KB, type: DATA, subtype: SPIFFS
           coredump : addr: 0x007F0000, size:    64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Jun 30 2024 10:49:12
  Compile Host OS   : windows
  ESP-IDF Version   : v5.1.4-358-gbd2b9390ef-dirty
  Arduino Version   : 3.0.2
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : ESP32_DEV
  Arduino Variant   : esp32
  Arduino FQBN      : espressif:esp32:esp32:UploadSpeed=921600,CPUFreq=240,FlashFreq=80,FlashMode=qio,FlashSize=8M,PartitionScheme=default_8MB,DebugLevel=verbose,PSRAM=enabled,LoopCore=1,EventsCore=1,EraseFlash=none,JTAGAdapter=default,ZigbeeMode=default
============ Before Setup End ============
[   754][V][esp32-hal-uart.c:408] uartBegin(): UART0 baud(115200) Mode(800001c) rxPin(3) txPin(1)
[   762][V][esp32-hal-uart.c:497] uartBegin(): UART0 not installed. Starting installation
[   773][V][esp32-hal-uart.c:544] uartBegin(): UART0 initialization done.

Booting Sketch...
[   804][V][NetworkEvents.cpp:119] checkForEvent(): Network Event: 9 - WIFI_READY
[   884][V][STA.cpp:184] _onStaEvent(): STA Started
[   889][V][NetworkEvents.cpp:119] checkForEvent(): Network Event: 11 - STA_START
[   890][V][AP.cpp:106] _onApEvent(): AP Started
[   901][V][STA.cpp:110] _onStaArduinoEvent(): Arduino STA Event: 11 - STA_START
[   908][V][NetworkEvents.cpp:119] checkForEvent(): Network Event: 19 - AP_START
[   915][V][AP.cpp:88] _onApArduinoEvent(): Arduino AP Event: 19 - AP_START
[   995][V][STA.cpp:204] _onStaEvent(): STA Connected: SSID: Hanger6, BSSID: d8:a7:56:00:5e:96, Channel: 1, Auth: WPA2_PSK
[  1006][V][NetworkEvents.cpp:119] checkForEvent(): Network Event: 13 - STA_CONNECTED
[  1014][V][STA.cpp:110] _onStaArduinoEvent(): Arduino STA Event: 13 - STA_CONNECTED
[  1220][V][NetworkInterface.cpp:66] _onIpEvent(): sta Got New IP: 192.168.2.44 MASK: 255.255.255.0 GW: 192.168.2.1
[  1230][V][NetworkEvents.cpp:119] checkForEvent(): Network Event: 16 - STA_GOT_IP
[  1238][V][STA.cpp:110] _onStaArduinoEvent(): Arduino STA Event: 16 - STA_GOT_IP
[  1245][V][STA.cpp:169] _onStaArduinoEvent(): STA IP: 192.168.2.44, MASK: 255.255.255.0, GW: 192.168.2.1
mDNS responder started
HTTPUpdateServer ready! Open http://esp32-webupdate.local/update in your browser
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   333752 B ( 325.9 KB)
  Free Bytes        :   237292 B ( 231.7 KB)
  Allocated Bytes   :    85500 B (  83.5 KB)
  Minimum Free Bytes:   237148 B ( 231.6 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
  GPIO : BUS_TYPE[bus/unit][chan]
  --------------------------------------  
     1 : UART_TX[0]
     3 : UART_RX[0]
============ After Setup End =============

When trying to access /update

[  9521][V][Parsing.cpp:257] _parseRequest(): headerValue: 1
[  9527][V][Parsing.cpp:256] _parseRequest(): headerName: User-Agent
[  9533][V][Parsing.cpp:257] _parseRequest(): headerValue: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
[  9548][V][Parsing.cpp:256] _parseRequest(): headerName: Accept
[  9554][V][Parsing.cpp:257] _parseRequest(): headerValue: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
[  9568][V][Parsing.cpp:256] _parseRequest(): headerName: Sec-GPC
[  9574][V][Parsing.cpp:257] _parseRequest(): headerValue: 1
[  9579][V][Parsing.cpp:256] _parseRequest(): headerName: Accept-Language
[  9586][V][Parsing.cpp:257] _parseRequest(): headerValue: en-US,en
[  9592][V][Parsing.cpp:256] _parseRequest(): headerName: Accept-Encoding
[  9599][V][Parsing.cpp:257] _parseRequest(): headerValue: gzip, deflate
[  9605][V][Parsing.cpp:284] _parseArguments(): args: 
[  9610][V][Parsing.cpp:267] _parseRequest(): Request: /update
[  9616][V][Parsing.cpp:268] _parseRequest():  Arguments: 

When selecting SPIFFS FILE and submitting

[ 22886][V][WebServer.cpp:418] handleClient(): New client: client.localIP()=192.168.2.44
[ 22895][V][Parsing.cpp:122] _parseRequest(): method: POST url: /update search: 
[ 22902][V][Parsing.cpp:157] _parseRequest(): headerName: Host
[ 22908][V][Parsing.cpp:158] _parseRequest(): headerValue: 192.168.2.44
[ 22915][V][Parsing.cpp:157] _parseRequest(): headerName: Connection
[ 22921][V][Parsing.cpp:158] _parseRequest(): headerValue: keep-alive
[ 22927][V][Parsing.cpp:157] _parseRequest(): headerName: Content-Length
[ 22934][V][Parsing.cpp:158] _parseRequest(): headerValue: 1573078
[ 22940][V][Parsing.cpp:157] _parseRequest(): headerName: Cache-Control
[ 22946][V][Parsing.cpp:158] _parseRequest(): headerValue: max-age=0
[ 22953][V][Parsing.cpp:157] _parseRequest(): headerName: Upgrade-Insecure-Requests
[ 22960][V][Parsing.cpp:158] _parseRequest(): headerValue: 1
[ 22966][V][Parsing.cpp:157] _parseRequest(): headerName: Origin
[ 22971][V][Parsing.cpp:158] _parseRequest(): headerValue: http://192.168.2.44
[ 22979][V][Parsing.cpp:157] _parseRequest(): headerName: Content-Type
[ 22985][V][Parsing.cpp:158] _parseRequest(): headerValue: multipart/form-data; boundary=----WebKitFormBoundaryy3LOPt4U4nibX6GB
[ 22997][V][Parsing.cpp:157] _parseRequest(): headerName: User-Agent
[ 23003][V][Parsing.cpp:158] _parseRequest(): headerValue: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
[ 23019][V][Parsing.cpp:157] _parseRequest(): headerName: Accept
[ 23024][V][Parsing.cpp:158] _parseRequest(): headerValue: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
[ 23038][V][Parsing.cpp:157] _parseRequest(): headerName: Sec-GPC
[ 23044][V][Parsing.cpp:158] _parseRequest(): headerValue: 1
[ 23050][V][Parsing.cpp:157] _parseRequest(): headerName: Accept-Language
[ 23056][V][Parsing.cpp:158] _parseRequest(): headerValue: en-US,en
[ 23063][V][Parsing.cpp:157] _parseRequest(): headerName: Referer
[ 23069][V][Parsing.cpp:158] _parseRequest(): headerValue: http://192.168.2.44/update
[ 23076][V][Parsing.cpp:157] _parseRequest(): headerName: Accept-Encoding
[ 23083][V][Parsing.cpp:158] _parseRequest(): headerValue: gzip, deflate
[ 23090][V][Parsing.cpp:284] _parseArguments(): args: 
[ 23095][V][Parsing.cpp:362] _parseForm(): Parse Form: Boundary: ----WebKitFormBoundaryy3LOPt4U4nibX6GB Length: 1573078
[ 23106][V][Parsing.cpp:398] _parseForm(): PostArg FileName: DataFile.bin
[ 23113][V][Parsing.cpp:404] _parseForm(): PostArg Name: filesystem
[ 23120][V][Parsing.cpp:417] _parseForm(): PostArg Type: application/octet-stream
[ 23127][V][Parsing.cpp:451] _parseForm(): Start File: DataFile.bin Type: application/octet-stream
[ 27426][V][Parsing.cpp:499] _parseForm(): End File: DataFile.bin Type: application/octet-stream Size: 1572864
[ 27436][V][Parsing.cpp:506] _parseForm(): Done Parsing POST
[ 27442][V][Parsing.cpp:267] _parseRequest(): Request: /update
[ 27447][V][Parsing.cpp:268] _parseRequest():  Arguments: 

On the webpage,

Update error: Bad Size Given

Other Steps to Reproduce

Tried on few different boards, similar result.

I have checked existing issues, online documentation and the Troubleshooting Guide

lbernstone commented 3 months ago

What does your html look like? That error happens when the file size is not provided.

kapyaar commented 3 months ago

@lbernstone It is a bunch of html files (each with html, js, css, etc), image files,json files, etc that went through the mkspiffs tool, resulting in a .bin file. This is the same .bin file that was generated and successfully uploaded to the board using the ESP32 Spiffs update tool. Not sure where the file size need to be provided?

kapyaar commented 3 months ago

@lbernstone Just checking in. Could you kindly clarify where the file size need to be provided?

lbernstone commented 3 months ago

The OTAWebUpdater example shows how to get the browser to add the file size to your request, and then have the Update library use the file size.

kapyaar commented 2 months ago

@lbernstone Thank you. I am a bit confused. Some thoughts/ findings:

  1. The OTAWebUpdater example you mentioned does show the js calculating the file size and submitting it in the post request. However, this is for the firmware update only, and not SPIFFS. The reason I clarify this is because,

a. Firmware update already works fine in the Examples>WebUpdater.ino in question, without submitting the filesize. b. The html code on /update page on that example is just a form input, no JS, no file size calculation

<!DOCTYPE html>
<html lang='en'>
   <head>
      <meta charset='utf-8'>
      <meta name='viewport' content='width=device-width,initial-scale=1'/>
   </head>
   <body>
      <form method='POST' action='' enctype='multipart/form-data'>
         Firmware:<br>
         <input type='file' accept='.bin,.bin.gz' name='firmware'>
         <input type='submit' value='Update Firmware'>
      </form>
      <form method='POST' action='' enctype='multipart/form-data'>
         FileSystem:<br>
         <input type='file' accept='.bin,.bin.gz,.image' name='filesystem'>
         <input type='submit' value='Update FileSystem'>
      </form>
   </body>
</html>
  1. I also tried Examples>httpUpdateSPIFFS.ino. Uploaded the spiffs.bin file (Same file, generated from mkspiffs, that I am using to test WebUpdater.ino) to a server, and provided the url in the sketch. It updates SPIFFS just fine. No file size provided manually. Here is the response in Terminal.
Update SPIFFS...
[  8838][V][HTTPClient.cpp:242] beginInternal(): url: http://testServer.com/spiffs.bin
[  8848][D][HTTPClient.cpp:293] beginInternal(): protocol: http, host: testServer.com port: 80 url: /spiffs.bin
[  9518][D][HTTPClient.cpp:574] sendRequest(): request type: 'GET' redirCount: 0

[  9526][D][NetworkManager.cpp:83] hostByName(): Clearing DNS cache
[  9775][D][HTTPClient.cpp:1112] connect():  connected to watchdog15.com:80
[  9864][V][HTTPClient.cpp:1201] handleHeaderResponse(): RX: 'HTTP/1.1 200 OK'
[  9872][V][HTTPClient.cpp:1201] handleHeaderResponse(): RX: 'Date: Thu, 11 Jul 2024 16:53:35 GMT'
[  9881][V][HTTPClient.cpp:1201] handleHeaderResponse(): RX: 'Server: Apache'
[  9888][V][HTTPClient.cpp:1201] handleHeaderResponse(): RX: 'Last-Modified: Thu, 11 Jul 2024 16:49:02 GMT'
[  9898][V][HTTPClient.cpp:1201] handleHeaderResponse(): RX: 'Accept-Ranges: bytes'
[  9905][V][HTTPClient.cpp:1201] handleHeaderResponse(): RX: 'Content-Length: 1572864'
[  9913][V][HTTPClient.cpp:1201] handleHeaderResponse(): RX: 'Connection: close'
[  9921][V][HTTPClient.cpp:1201] handleHeaderResponse(): RX: 'Content-Type: application/octet-stream'
[  9930][V][HTTPClient.cpp:1201] handleHeaderResponse(): RX: ''
[  9936][D][HTTPClient.cpp:1257] handleHeaderResponse(): code: 200
[  9942][D][HTTPClient.cpp:1260] handleHeaderResponse(): size: 1572864
[  9948][D][HTTPClient.cpp:618] sendRequest(): sendRequest code=200
[  9954][D][HTTPUpdate.cpp:227] handleUpdate(): Header read fin.
[  9960][D][HTTPUpdate.cpp:228] handleUpdate(): Server header:
[  9966][D][HTTPUpdate.cpp:229] handleUpdate():  - code: 200
[  9972][D][HTTPUpdate.cpp:230] handleUpdate():  - len: 1572864
[  9978][D][HTTPUpdate.cpp:242] handleUpdate(): ESP32 info:
[  9983][D][HTTPUpdate.cpp:243] handleUpdate():  - free Space: 3342336
[  9990][D][HTTPUpdate.cpp:244] handleUpdate():  - current Sketch Size: 1012448
[ 10278][D][HTTPUpdate.cpp:298] handleUpdate(): runUpdate spiffs...
[ 46235][D][HTTPUpdate.cpp:337] handleUpdate(): Update ok
[ 46240][D][NetworkClient.cpp:562] connected(): Disconnected: RES: 0, ERR: 128
[ 46247][D][HTTPClient.cpp:393] disconnect(): tcp is closed

and it goes on to

Update sketch...

So, why does Examples>WebUpdater.ino fail when updating spiffs? To me it looks like,

  1. If filesize need to be provided, then the html which in fact is part of HTTPUpdateServer.h should include the size calculating js script.
  2. In HTTPUpdateServer.h#L106 It does appear like the update is starting with max available size, so if the same spiffs.bin works through other methods, then if max size is used, It should just go through in this case as well.

Does this make sense? Or am I missing something here? Thank you again, for your time.

lbernstone commented 2 months ago

I'm not going to update that library. It probably just needs to be retired. Here's a patch for OTAWebUpdater.ino . I'll submit it as a PR once I have some time to stress test it (it seems to be a bit slower than it should be).

  if (upload.status == UPLOAD_FILE_START) {
    int otaType = upload.filename.indexOf(".spiffs.") || upload.filename.indexOf(".ffat.") ? U_SPIFFS : U_FLASH;
    Serial.printf("Receiving Update: %s, Size: %d, Type: %d\n", upload.filename.c_str(), fsize, otaType);
    if (!Update.begin(fsize, otaType)) {
kapyaar commented 1 month ago

@lbernstone Just thought I will check back on if you had the chance to perform the stress tests on this? I would like to make a suggestion. In the Examples>WebUpdater.ino it offered two different file select options, one for firmware, one for spiffs. The benefit is that the process does not make it necessary that the filename has "spiffs" or "ffat" in it. In my opinion, this would be a nice feature to keep, when you get to work on the OTAWebUpdater example.

lbernstone commented 1 month ago

These are intended to be examples of esp32 code, not html. Those filenames are the format that the file system extension uses, so will likely be the filenames anyhow.

kapyaar commented 1 month ago

Sure, I agree. It is just that, even when the spiffs spits out a file that has .spiffs in the file name, I (and possibly others) may rename the file to some naming convention that does not have the spiffs/ ffat in the name.

In my opinion, keeping them independent of file name does not look hard, we can simply update the html file to have two inputs and have the form field hold the name.

Regardless, I appreciate your/ team in all your efforts, however you find it fitting in this case :) b/r

kapyaar commented 1 month ago

@lbernstone It seems to me, SPIFFS.totalBytes() is not returning the correct value. In a use case where 1.5MB spiffs is selected, SPIFFS.totalBytes() is returning 1438481 where as the actual value should be 1572864.

lbernstone commented 1 month ago

You shouldn't use SPIFFS any more, it is highly inefficient. LittleFS has replaced it.

kapyaar commented 1 month ago

Unfortunately, I have to support an existing project, which uses spiffs. Not for a new one. Is it reasonable to expect that the issue at hand will have a resolution?

lbernstone commented 1 month ago

What issue? That SPIFFS doesn't provide the full amount of space in a partition or the original issue on this ticket? AFAIK, SPIFFS is no longer under development. Please note, I don't work for Espressif. If you have production code which is impacted by an issue here, you need to speak to a sales rep/engineer.

kapyaar commented 1 month ago

OK, Because you are the only one who responded to the issue, and you suggested that you were not going to fix WebUpdater.ino, rather, do a PR on OTAWebUpdater example, I took it that you were part of the team. Did nt know otherwise, and did nt mean to bother you with later messages had I known that :)

As to "what issue", It looks to me the same. The reason why WebUpdater.ino is failing for bad size given is because in the Updater library, SPIFFS.totalBytes() is returning incorrect value AFAIK

@me-no-dev or @SuGlider Tagging you for your kind attention. Is the issue in this thread fixable?

lbernstone commented 1 month ago

SPIFFS.totalBytes does not return the partition size, but the maximum amount of data that could be stored (this comes from upstream). The code really should be changed to get the partition information. If you just want to get it working without writing any code, then change https://github.com/espressif/arduino-esp32/blob/master/libraries/HTTPUpdateServer/src/HTTPUpdateServer.h#L107 to if (!Update.begin(UPDATE_SIZE_UNKNOWN, U_SPIFFS)) { Note, my objection to that library is that it is redundant, and extremely limiting, since it sets up a WebServer which can then not be extended by the user, and hard codes the html.

kapyaar commented 1 month ago

Thanks, I do understand the workaround. Even If I move to littleFS, the filesystem update method would still be the same, and need this workaround, correct? In that case, If you are recommending that I just make this change locally, everytime there is a new release, I have to keep making this custom modification. Not a good situation to have. If the general agreement is that SPIFFS.totalbytes() is not going to work, and will not be updated, would it make sense to update to the source to reflect the change you mentioned in L107?

lbernstone commented 1 month ago

LittleFS gives the partition size for LittleFS.totalBytes(), so it should just work. If you want to submit a PR to fix this library, then please take into consideration my comments about the limitations and match it more closely to OTAWebUpdater.ino so that it will be maintainable in the future (maybe even to the point of using the same html.h file).