forked from me-no-dev/ESPAsyncWebServer
-
Notifications
You must be signed in to change notification settings - Fork 70
Labels
Type: BugSomething isn't workingSomething isn't working
Description
Platform
ESP32
IDE / Tooling
Arduino (IDE/CLI)
Versions
esp32 v3.3.2
Async TCP v3.4.9
ESP Async WebServer v3.8.1
What happened?
My sketch uses a AsyncAbstractResponse subclass where _sendContentLength is disabled and the _fillBuffer function has the following behavior:
- The first call returns
RESPONSE_TRY_AGAIN. - The second call fully fills the provided buffer with letter "B" and returns
buflen. - The third call fully fills the provided buffer with letter "C" and returns
buflen. - The fourth call returns
0to end the response.
With the sketch running on either ESP32 or ESP32C3, I invoke wget command to trigger the handler.
Downloaded file: 1.txt
The console log pasted below indicates that the sketch has filled 5760 "B"s and 4308 "C"s in the response.
However, the downloaded file has 5675 "B"s and 4308 "C"s.
In other words, 85 octets are truncated off the buffer filled in the second call.
Stack Trace
WiFi connected
http://192.168.5.67
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
Total Size : 301688 B ( 294.6 KB)
Free Bytes : 191032 B ( 186.6 KB)
Allocated Bytes : 103632 B ( 101.2 KB)
Minimum Free Bytes: 190772 B ( 186.3 KB)
Largest Free Block: 114676 B ( 112.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
GPIO : BUS_TYPE[bus/unit][chan]
--------------------------------------
20 : UART_RX[0]
21 : UART_TX[0]
============ After Setup End =============
_fillBuffer ch=A buflen=5675
_fillBuffer ch=B buflen=5760
_fillBuffer ch=C buflen=4308
_fillBuffer ch=D buflen=4324
Wireshark packet trace: 1.pcapng.gz
It may or may not be a coincidence, but I noticed:
- The HTTP status line and response headers have exactly 85 octets.
- The
buflenpassed to the first_fillBuffercall is 85 larger than thebuflenpassed to the second_fillBuffercall.
Minimal Reproductible Example (MRE)
#include <ESPAsyncWebServer.h>
#include <WiFi.h>
static const char* WIFI_SSID = "my-ssid";
static const char* WIFI_PASS = "my-pass";
AsyncWebServer server(80);
class MyResponse : public AsyncAbstractResponse {
public:
explicit MyResponse() {
_code = 200;
_contentType = "text/plain";
_sendContentLength = false;
}
bool _sourceValid() const override {
return true;
}
size_t _fillBuffer(uint8_t* buf, size_t buflen) override {
Serial.printf("_fillBuffer ch=%c buflen=%zu\n", m_ch, buflen);
if (m_ch == 'A') {
++m_ch;
return RESPONSE_TRY_AGAIN;
}
if (m_ch == 'D') {
return 0;
}
std::fill_n(buf, buflen, static_cast<uint8_t>(m_ch));
++m_ch;
return buflen;
}
private:
char m_ch = 'A';
};
void
setup() {
Serial.begin(115200);
Serial.println();
delay(1000);
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.printf("WiFi failure %d\n", WiFi.status());
delay(5000);
ESP.restart();
}
Serial.println("WiFi connected");
delay(1000);
Serial.print("http://");
Serial.println(WiFi.localIP());
server.on("/1.txt", HTTP_GET, [](AsyncWebServerRequest* req) {
req->send(new MyResponse());
});
server.begin();
}
void
loop() {
delay(1);
}I confirm that:
- I have read the documentation.
- I have searched for similar discussions.
- I have searched for similar issues.
- I have looked at the examples.
- I have upgraded to the lasted version of ESPAsyncWebServer (and AsyncTCP for ESP32).
Metadata
Metadata
Assignees
Labels
Type: BugSomething isn't workingSomething isn't working