Ich habe eigentlich gerade an einem anderen Feature gearbeitet (đ ESPuino Mediahub ). Nachdem sich dort Transferraten von 700 kB/s und mehr einstellten, habe ich die KI meines Vertrauens mal angewiesen, sich den aktuellen Mechanismus mal anzuschauen.
Rausgekommen ist dabei folgender PR, den ich direkt gemergt habe:
dev â explorer-raw-upload
offen 10:25PM - 15 Jul 26 UTC
## Summary
File-explorer uploads (drag & drop / file picker in the Web-UI's F⊠iles tab) went through one `multipart/form-data` `POST /explorer` request for the whole batch. Measured throughput topped out around **450 kB/s** regardless of buffer size or WiFi tuning.
This switches the upload to a **raw binary body** instead: each selected file is now sent as its own `POST /explorer?path=<target>` request with `Content-Type: application/octet-stream`, one request per file. No functional change from the user's perspective (still pick one or many files, or a whole folder) - same target-path resolution, same progress bar, same double-buffered write path on the ESPuino side.
**Result: ~650 kB/s**, a ~40% improvement, with no observed downsides.
## Why this is faster
Two concrete overheads that a raw body avoids:
1. **MIME boundary parsing.** `multipart/form-data` requires ESPAsyncWebServer to parse `Content-Disposition`/boundary markers out of the stream as it arrives. A raw body has none of that - every byte that arrives is payload.
2. **AsyncTCP's single shared service task.** All of ESPuino's async web traffic (of any kind) is funneled through one `async_tcp` task via one queue (`CONFIG_ASYNC_TCP_QUEUE_SIZE = 64`). This is unrelated to multipart vs. raw and wasn't changed here, but it's worth knowing this is a shared, project-wide bottleneck that a future change could address separately.
The double-buffering/writer-task machinery, 16 KB chunk size, buffered SD writes, and WiFi power-save handling were already in place before this change (from the original multipart implementation) and are unchanged - this PR is purely about the wire format, not the storage path.
## What changed
- `src/Web.cpp`: `explorerHandleFileUpload()` is now a raw-body (`onBody`) handler instead of a multipart (`onUpload`) handler. Registered on the same `POST /explorer` as before - same URL and method, different request body. The old multipart implementation is removed.
- `html/management.html`: the upload form's submit handler now loops over the selected `FileList` and sends one raw `XMLHttpRequest` POST per file sequentially (only one upload is ever in flight, matching the ESPuino's single shared upload buffer), instead of building one `FormData`/multipart request for the whole selection. Progress/ETA/final-speed reporting is aggregated across all files so the UX is unchanged.
- `REST-API.yaml`: `POST /explorer` documentation updated to describe the raw `application/octet-stream` body (one file per request) instead of `multipart/form-data`.
Habe das jetzt ein bisschen getestet und Upload-Raten bis zu 650 kB/s gesehen. Den Rest kriegen wir wegen des Webserver-Overheads nicht mehr, aber das ist ggĂŒ vorher (mit max. 450 kB/s, was ich erst die Tage verbessert hatte), eine gewaltige Verbesserung.
Vorher: multipart/form-data
Jetzt: raw application/octet-stream
Seiteneffekt: Das betrifft natĂŒrlich auch das REST-API.
Yeah!
4 âGefĂ€llt mirâ