Replies: 8 comments
-
Reduced the scope to the changes made to void AsyncWebServerRequest::send(AsyncWebServerResponse* response) {
+ if (_sent)
+ return;
+ if (_response)
+ delete _response;
_response = response;
if (_response == NULL) {
_client->close(true);
@@ -716,15 +730,8 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse* response) {
_sent = true;
return;
}
- if (!_response->_sourceValid()) {
- delete response;
- _response = NULL;
+ if (!_response->_sourceValid())
send(500);
- } else {
- _client->setRxTimeout(0);
- _response->_respond(this);
- _sent = true;
- }
} If I keep the red(-) part, my code works. If I use the green(+) part, my code yields no files. As if my |
Beta Was this translation helpful? Give feedback.
-
thanks for the report! I appreciate the work and time spent in your findings which helps me answer more precisely about what is happening. The diff you are talking to is related to the introduction of middlewares. Before, calling send() would commit the response on the wire ( File root = fileSystem.open("/");
String txt;
bool finished; Now, The callback of The correct way of doing what you want to do is to use the Something like that would ensure that your request object becomes the owner of the states: struct States {
File root;
String txt;
bool finished;
};
server.on("/chunk", HTTP_GET, [](AsyncWebServerRequest* request) {
States* states = new States();
states.root = ...
states.txt = ...
states.finished = ...
request->_tempObject = states;
AsyncWebServerResponse* response = request->beginChunkedResponse("text/html", [request](uint8_t* buffer, size_t maxLen, size_t index) -> size_t {
States* states = (States*) request->_tempObject;
// ...
});
request->send(response);
}); You don't even need to free the |
Beta Was this translation helpful? Give feedback.
-
Hi ! Nevertheless, I did try to implement your solution, and I'm afraid it's still doing the same. struct HandleListStates {
File root;
String txt;
bool finished;
};
void handleList(AsyncWebServerRequest *request)
{
struct HandleListStates* states = new HandleListStates();
states->root = fileSystem.open("/");
request->_tempObject = states;
AsyncWebServerResponse *response = request->beginChunkedResponse(
"application/json",
[request]
(uint8_t* buffer, const size_t max_len, const size_t index) mutable -> size_t
{
struct HandleListStates* states = (struct HandleListStates*) request->_tempObject;
[...]
while (File file = states->root.openNextFile()) { // still not entering the loop
[...]
}
[...]
});
request->send(response);
} Any idea ? Regards, |
Beta Was this translation helpful? Give feedback.
-
Not on my mind... I will have to check deeper because this is supposed to work. What you did here is right. I will add an example in the SimpleServer code and get back to you so that you can complete this example in case I am not able to reproduce. |
Beta Was this translation helpful? Give feedback.
-
I tried to move the
Which should indicate us something is wrong with the context.
|
Beta Was this translation helpful? Give feedback.
-
No since the states are within the request object, which stays the same and the callback can be called multiple times until completion...
Do you have the ability to test with LittleFS instead of SD_MMC ? That's what I was goign to test anyway in the simple example... |
Beta Was this translation helpful? Give feedback.
-
I am so sorry, I just understood what went wrong. Now it works 🎉 So, in the end, I did need your solution, but I also needed to not unmount the SD card at the end of the handler ^^ There is no bug there, assuming we use a context saved in |
Beta Was this translation helpful? Give feedback.
-
Awesome!
Ahah! yes, that's right! what you can do though is unmount from within the callback in the
This thing comes from the original repo and was a little bit documented in the original doc: https://github.com/mathieucarbou/ESPAsyncWebServer?tab=readme-ov-file#body-data-handling I will move this into a discussion for reference purposes. This was an interesting use case ;-) |
Beta Was this translation helpful? Give feedback.
-
Description
I upgraded ESPAsyncWebServer from v3.1.0 to the latest v3.3.x and found out that
beginChunkedResponse
behaved differently. I am unsure what causes the exact issue, but the result is that my request acts like there is no file in the directory I am traversing.I managed to git-bisect by hand and find the problematic commit: 571eac4
Before that commit, I can traverse
File root
for files inside. After that commit, I never enter the while loop.Here is a simplified view of the function:
Result:
Result in logs:
While when using commit 741841a it works and here is the output in logs:
Full source code: Link to the source code where the issue happens
Board: esp32-pico-d4 (SD WIFI PRO)
Considering this is a dual-core ESP32, I did try to set
CONFIG_ASYNC_TCP_RUNNING_CORE
to0
or1
with no success.Beta Was this translation helpful? Give feedback.
All reactions