Repository navigation
fix: drain final response buffers before completing - #497
Draft
atomicdeploy wants to merge 1 commit into
Draft
atomicdeploy wants to merge 1 commit into
atomicdeploy wants to merge 1 commit into
Conversation
41 of 100 tasks
mathieucarbou
marked this pull request as draft
October 19, 2026 06:37
Member
|
@atomicdeploy please open an issue first describing the bug you saw and an MRE to reproduce it. Ideally written similar to a project exemple. |
lvschouwen
added a commit
to lvschouwen/split-flap
that referenced
this pull request
Oct 20, 2026
ESPAsyncWebServer 3.12.1 marks a response ended as soon as its last piece is read from the source. When the TCP queue then refuses that piece (tcp_write ERR_MEM, likely with the ESP-01's 536-byte segments), the next ACK closes the connection with the piece still in the send buffer: the row got a clean close 439 bytes short of the row image, three offers in a row. patch_asyncweb.py now keeps the source's end apart from the response's and takes an in-flight credit only for a pass that sent bytes. Every anchor must occur exactly once. The test runs the patches on the pinned v3.12.1 excerpts. Upstream PR ESP32Async/ESPAsyncWebServer#497 is the same bug. Refs #631
This branch has not been deployed
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.
Summary
Keep
AsyncAbstractResponse's final local buffer alive until its bytes have actually been admitted to the TCP queue, and finish only after admitted header/body bytes have been acknowledged.The current implementation marks
RESPONSE_ENDwhile filling the final source buffer. A shortAsyncClient::add()can leave a tail in_send_buffer; the next request ACK then considers the response finished and closes it. Partial body adds also bypass_writtenLengthaccounting, while headers can be counted twice.Changes
RESPONSE_TRY_AGAINcredit fix and avoid spending a header credit when zero bytes were admitted.Reproduction and verification
Prepared against exact upstream main
4d4eaca1833c3c11940a988fc8a6c0bdf734bbd2.tests/run-response-backpressure.mjsextracts and compiles the actualwrite_send_buffsimplementation fromsrc/WebResponses.cppwith small transport/source doubles. It is not a separately rewritten response algorithm. Requires Node.js and a C++17g++(orCXX).The optional
--baseline SOURCE --output EXECUTABLEmode verifies the pinned original source hash before reproduction. The original method fails deterministically with an eight-byte final source buffer, one admitted body byte and seven pending bytes while already exposingRESPONSE_END. Both in-flight-credit configurations reproduce the failure. Both patched configurations pass:RESPONSE_TRY_AGAIN, failed sends and invalid sources.This is focused host/mocked-transport evidence, not a full Arduino/lwIP build, packet-level measurement, hardware/Wi-Fi soak or proof that every reported network failure has this cause. No installed SDK was modified; this upstream patch follows a downstream immutable-response workaround and its reproducible short-add regression.