test: build large uploads in one piece - #362
Merged
Merged
Conversation
new Array(209715).fill(0) makes a File out of 209715 separate blob parts rather than 209715 bytes, and encoding that as multipart takes about 19 seconds here. uWS wants request bodies to arrive at 16kb/s or better and resets the connection after 10 idle seconds, so the upload died with ECONNRESET before the client had finished sending it. Whether the test passes therefore depends on how fast the machine can serialise those parts, which is why it goes green on CI and red locally. A single Uint8Array uploads the same 209715 bytes, keeps the assertion unchanged, and takes the test from ~51s to under a second.
This was referenced Jul 31, 2026
new File(arr, ...) takes fileBits as an iterable of blob parts, so passing a Uint8Array directly iterates it and turns every byte into its own part, each stringified. The 128kb buffer became about 337kb of decimal digits spread over 131072 parts, which is slow enough to trip the same 16kb/s limit as the multer test. Wrapping it uploads the intended 128kb of binary, and the test goes from 51 seconds to under one.
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.
Two tests build their upload out of one blob part per byte, which is slow enough to trip a uWS limit and makes them fail depending on how fast the machine is.
multer
new Array(209715).fill(0)is an array of 209715 zeros, andFiletreats each one as its own blob part. So this builds a file out of 209715 parts rather than 209715 bytes, and undici needs about 19 seconds to encode that as a multipart body on my machine.express-fileupload with temp file
fileBitsis an iterable of blob parts, so handing it aUint8Arraydirectly iterates the buffer and stringifies every byte into its own part. The intended 128kb of binary became roughly 337kb of decimal digits across 131072 parts.Why they fail
uWS wants a request body to keep arriving at 16KB/s or better:
HttpContext.honly resets the 10 second idle timeout after anotherHTTP_RECEIVE_THROUGHPUT_BYTES * HTTP_IDLE_TIMEOUT_Sbytes, which is 160KB. Neither upload is anywhere near that rate, so the socket is reset while the client is still sending and the test fails with ECONNRESET or UND_ERR_SOCKET.Whether they pass comes down to how fast the machine can serialise all those parts, which is why they are green on CI and red here: multer failed 6 times out of 6 locally, and the run that did pass took 51 seconds.
Reduced to just the timing, with no upload machinery involved:
Fix
Pass a single part in both cases. Same bytes on the wire, assertions untouched, and both tests now upload what they claim to: multer goes from ~51s to under a second, express-fileupload from ~51s to ~0.5s, and their output matches Express 4 and Express 5 exactly.
The 16KB/s floor itself is not a bug, it is uWS refusing to hold sockets open for slow clients. #363 documents it.