Support multi-chunk encrypted uploads in web interface - #2821
Open
sergarsilla wants to merge 1 commit into
Open
Conversation
Ninja-jr
pushed a commit
to Ninja-jr/Bruce_firmware
that referenced
this pull request
Aug 22, 2026
Ninja-jr
pushed a commit
to Ninja-jr/Bruce_firmware
that referenced
this pull request
Aug 24, 2026
Ninja-jr
pushed a commit
to Ninja-jr/Bruce_firmware
that referenced
this pull request
Aug 25, 2026
Ninja-jr
pushed a commit
to Ninja-jr/Bruce_firmware
that referenced
this pull request
Aug 29, 2026
Ninja-jr
pushed a commit
to Ninja-jr/Bruce_firmware
that referenced
this pull request
Aug 30, 2026
Ninja-jr
pushed a commit
to Ninja-jr/Bruce_firmware
that referenced
this pull request
Aug 30, 2026
Ninja-jr
pushed a commit
to Ninja-jr/Bruce_firmware
that referenced
this pull request
Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed Changes
Encrypted file uploads in the web interface only processed the first chunk.
handleUploadused astatic int chunck_nocounter and returned404 "file is too big"on any second chunk, so files larger than one AsyncWebServer chunk(~1.4 KB) could never be uploaded encrypted.
The root cause was that encryption was done with
encryptString(), which writesa complete self-contained file (header + a single
Data:line) and restarts theposition-based XOR keystream at offset 0. Calling it per chunk would emit multiple
headers/
Data:lines and reset the keystream, which the reader(
readDecryptedFile) cannot decrypt — hence the hard single-chunk limit.This PR encrypts uploads incrementally instead:
encryptFileHeader()writes the encrypted-file header once (on the firstchunk), ending with the
Data:prefix.encryptChunkToHex()encrypts each chunk on its own and appends its hex bytesto that single
Data:line. It uses the chunk's absolute plaintext offset(
index, provided by AsyncWebServer) so the XOR keystream stays continuousacross chunks — the resulting file decrypts identically to a single-shot one.
Data:line is written on the finalchunk.
Only the encrypted path changed; the plain (non-encrypted) upload path is
untouched.
Types of Changes
Bugfix
Verification
is enough) with an encryption password set.
404 "file is too big". After: the full.encfile is written..encfile and enter the same password; itdecrypts to the original content (
readDecryptedFile).Builds clean for
lilygo-t-embed-cc1101; the change is board-agnostic.Testing
Not covered by automated tests (no harness for the web-upload path). Verified by
building the firmware and by tracing the encrypt/decrypt round-trip: the reader
parses the
Data:line in fixed 3-char groups and XOR-decrypts from offset 0, sothe streamed output (fixed two-digit hex per byte, keystream keyed by absolute
offset) round-trips correctly for both single- and multi-chunk uploads.
Linked Issues
Resolves the
// TODO: handle multiple chunksinsrc/core/wifi/webInterface.cpp(thehandleUploadencrypted path).User-Facing Change
Further Comments
Memory-safe by design for the ESP32: the file is never buffered whole in RAM. Each
chunk allocates only a transient hex string (~3x the chunk size) that is written
and freed before the next chunk. There is no longer a hard size limit — uploads
are bounded only by free space on the target filesystem.
As a side effect the encrypted path is more robust than before: bytes are now
emitted as fixed two-digit uppercase hex (the previous
String(byte, HEX)droppedthe leading zero for values < 0x10, which the fixed-width reader parses
incorrectly), and chunk data is read by exact length rather than through
String((char*)data), which stopped at the first null byte.