Skip to content

WebUI effects list is (sometimes) incomplete or broken when using a slow connection (PPP over UART) #5813

Description

@aenertia

WLED pins Aircoookie/ESPAsyncWebServer at ac44e32. In AsyncAbstractResponse::_ack() (WebResponses.cpp), the RESPONSE_WAIT_ACK exit condition:

} else if (_state == RESPONSE_WAIT_ACK) {
    if (!_sendContentLength || _ackedLength >= _writtenLength) {
        _state = RESPONSE_END;
        if (!_chunked && !_sendContentLength)
            request->client()->close(true);
    }
}

On the chunked path (_sendContentLength=false), !_sendContentLength is unconditionally true — close() fires as soon as the final zero-length chunk lands in the lwIP send buffer, not when it's ACKed. On fast WiFi the gap is negligible. On slow or high-latency transports (PPP/UART, congested WiFi with retransmissions) the response is truncated before the tail bytes drain.

AsyncBasicResponse::_ack() in the same file already uses _ackedLength >= _writtenLength unconditionally (lines 320-323). AsyncAbstractResponse was never updated to match.

Fork comparison

Fork AsyncAbstractResponse WAIT_ACK condition Status
Aircoookie ac44e32 (pinned) !_sendContentLength || _ackedLength >= _writtenLength Buggy
me-no-dev AsyncAbstractResponse !_sendContentLength || _ackedLength >= _writtenLength Buggy
me-no-dev AsyncBasicResponse lines 320-323 _ackedLength >= _writtenLength Fixed — inconsistent in same file
mathieucarbou !_sendContentLength || _ackedLength >= _writtenLength Buggy
ESP32Async 747223f02f8e Unconditional _state = RESPONSE_END Addressed — relies on _onAck for graceful close

Workaround

#5808 avoids the buggy path at the WLED level by switching respondModeData() and respondModeNames() from sendChunked() to request->send() with a pre-computed Content-Length. Not a fix — other endpoints using sendChunked() remain exposed.

Fix options

Match AsyncBasicResponse — drop the !_sendContentLength shortcut:

} else if (_state == RESPONSE_WAIT_ACK) {
    if (_ackedLength >= _writtenLength) {
        _state = RESPONSE_END;
    }
}

Or pull the ESP32Async approach (747223f02f8e) into the Aircoookie pin.

Discussion filed at ESP32Async: ESP32Async/ESPAsyncWebServer#472

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    AIPartly generated by an AI. Make sure that the contributor fully understands the code!cannot reproduceDevelopers are not able reproduce. Might be fixed already, or report is missing important detailsenhancementneeds investigationThe bug has not yet been reproduced by me. Analysis or more details are needed.use-as-isexpected behaviour, not a bug, no change planned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions