I have a /index.htm page that i'm storing in one ESP32 as a file with LITTLEFS:
<!DOCTYPE html>
<html>
<head>
<title>File Server</title>
<meta name="viewport" content="user-scalable=yes,initial-scale=1.0,width=device-width">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
%DATA%
</body>
</html>
and i'm sending it using this in setup:
asyncWebServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LITTLEFS, "/index.htm", String(), false, processor);
});
and this processor function :
String processor(const String& var){
Serial.println(var);
if(var == "DATA"){
String asyncWebPage="";
File root = LITTLEFS.open("/");
asyncWebPage += F("<table align='center'>");
asyncWebPage += F("<tr> <th style='width:fit-content'>Nom fichier</th> <th style='width:fit-content' >Taille fichier</th> <th style='width:fit-content'>Action</th> </tr>");
File file = root.openNextFile();
while(file){
asyncWebPage += "<tr><td>"+String(file.name())+"</td>";
asyncWebPage += "<td>"+String(file.size())+"</td>";
asyncWebPage +="<td> <a href='/viewFile?fileName="+String(file.name())+"'></a> </td></tr>";
file = root.openNextFile();
}
file.close();
asyncWebPage += F("</table>");
return(asyncWebPage);
}
return String();
}
Everything is working fine now , but as you can see the processor function contains asyncWebPage string which size depends on the number of files in the root directory, if there are too many files the string size can exceed the free heap memory size and result a crush, in the readme it is said that the "Respond with content coming from a File containing templates " internally uses Chunked Response, but i guess they are talking about the /index.htm file not the processor function content because as you can see in the processor function it does not return the string only after it completes concatenating all of it.
I am looking for a solution which help me send the asyncWebPage in chuncks like this for exemple :
String processor(const String& var){
Serial.println(var);
if(var == "DATA"){
String asyncWebPage="";
File root = LITTLEFS.open("/");
asyncWebPage += F("<table align='center'>");
asyncWebPage += F("<tr> <th style='width:fit-content'>Nom fichier</th> <th style='width:fit-content' >Taille fichier</th> <th style='width:fit-content'>Action</th> </tr>");
File file = root.openNextFile();
while(file){
asyncWebPage += "<tr><td>"+String(file.name())+"</td>";
asyncWebPage += "<td>"+String(file.size())+"</td>";
asyncWebPage +="<td> <a href='/viewFile?fileName="+String(file.name())+"'></a> </td></tr>";
if (asyncWebPage .length() > 1000) {
SendHTML_Content(asyncWebPage );
}
file = root.openNextFile();
}
file.close();
asyncWebPage += F("</table>");
return(asyncWebPage);
}
return String();
}
i'm stuck in this for 2 weeks and can't find a better solution than this :
const char template_header_html[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>File Server</title>
<meta name="viewport" content="user-scalable=yes,initial-scale=1.0,width=device-width">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
)=====";
const char template_footer_html[] PROGMEM = R"=====(
</body>
</html>
)=====";
asyncWebServer.on("/dir", HTTP_GET, [](AsyncWebServerRequest *request)
{
size_t max = (ESP.getFreeHeap() / 3) & 0xFFE0;
int header_index;
int footer_index;
int header_length=template_header_html_len;
int footer_length=template_footer_html_len;
File root ;
bool body_sent=false;
String asyncWebPage;
AsyncWebServerResponse *response = request->beginChunkedResponse("text/html", [max,header_length,footer_length,header_index,footer_index,body_sent,root,asyncWebPage](uint8_t *buffer, size_t maxLen, size_t index) mutable -> size_t {
//send the header
header_length = template_header_html_len- header_index;
if(header_index<template_header_html_len)
{
if (header_length > maxLen) header_length = maxLen;
if (header_length > max) header_length = max;
if (header_length > 0)
{
memcpy_P(buffer, template_header_html + header_index, header_length);
header_index+=header_length;
return header_length;
}
}
//send the body
if(!body_sent)
{
.
.
.
.
.
}
//send the footer
footer_length = template_footer_html_len- footer_index;
if( footer_index<template_footer_html_len)
{
if (footer_length > maxLen) footer_length = maxLen;
if (footer_length > max) footer_length = max;
if (footer_length > 0)
{
memcpy_P(buffer, template_footer_html + footer_index, footer_length);
footer_index+=footer_length;
return footer_length;
}
}
return header_length+footer_length;
});
request->send(response);
});
the send header and footer does work but sending the body became too complicated and requiring so many additional insctructions that i started worring about performance degradation.
Which solution can help me best and how ? and thank you a lot