Update to version 3.9.6

This commit is contained in:
2026-02-10 12:34:12 +01:00
parent 2617252395
commit c98a476228
94 changed files with 4593 additions and 1434 deletions

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
// Copyright 2016-2026 Hristo Gochkov, Mathieu Carbou, Emil Muratov, Will Miles
//
// Shows how to serve a static and dynamic template
@@ -33,10 +33,23 @@ static const char *htmlContent PROGMEM = R"(
static const size_t htmlContentLength = strlen_P(htmlContent);
// Variables used for dynamic cacheable template
static unsigned uptimeInMinutes = 0;
static AsyncStaticWebHandler *uptimeHandler = nullptr;
// Utility function for performing that update
static void setUptimeInMinutes(unsigned t) {
uptimeInMinutes = t;
// Update caching header with a new value as well
if (uptimeHandler) {
uptimeHandler->setLastModified();
}
}
void setup() {
Serial.begin(115200);
#if SOC_WIFI_SUPPORTED || CONFIG_ESP_WIFI_REMOTE_ENABLED || LT_ARD_HAS_WIFI
#if ASYNCWEBSERVER_WIFI_SUPPORTED
WiFi.mode(WIFI_AP);
WiFi.softAP("esp-captive");
#endif
@@ -56,35 +69,68 @@ void setup() {
// Serve the static template file
//
// This call will have caching headers automatically added as it is a static file.
//
// curl -v http://192.168.4.1/template.html
server.serveStatic("/template.html", LittleFS, "/template.html");
// Serve the static template with a template processor
// Serve a template with dynamic content
//
// ServeStatic static is used to serve static output which never changes over time.
// This special endpoints automatically adds caching headers.
// If a template processor is used, it must ensure that the outputted content will always be the same over time and never changes.
// Otherwise, do not use serveStatic.
// Example below: IP never changes.
// serveStatic recognizes that template processing is in use, and will not automatically
// add caching headers.
//
// curl -v http://192.168.4.1/index.html
server.serveStatic("/index.html", LittleFS, "/template.html").setTemplateProcessor([](const String &var) -> String {
// curl -v http://192.168.4.1/dynamic.html
server.serveStatic("/dynamic.html", LittleFS, "/template.html").setTemplateProcessor([](const String &var) -> String {
if (var == "USER") {
return "Bob";
return String("Bob ") + millis();
}
return emptyString;
});
// Serve a template with dynamic content
// Serve a static template with a template processor
//
// to serve a template with dynamic content (output changes over time), use normal
// Example below: content changes over tinme do not use serveStatic.
// By explicitly calling setLastModified() on the handler object, we enable
// sending the caching headers, even when a template is in use.
// This pattern should never be used with template data that can change.
// Example below: USER never changes.
//
// curl -v http://192.168.4.1/dynamic.html
server.on("/dynamic.html", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(LittleFS, "/template.html", "text/html", false, [](const String &var) -> String {
// curl -v http://192.168.4.1/index.html
server.serveStatic("/index.html", LittleFS, "/template.html")
.setTemplateProcessor([](const String &var) -> String {
if (var == "USER") {
return String("Bob ") + millis();
return "Bob";
}
return emptyString;
})
.setLastModified("Sun, 28 Sep 2025 01:02:03 GMT");
// Serve a template with dynamic content *and* caching
//
// The data used in this template is updated in loop(). loop() is then responsible
// for calling setLastModified() on the handler object to notify any caches that
// the data has changed.
//
// curl -v http://192.168.4.1/uptime.html
uptimeHandler = &server.serveStatic("/uptime.html", LittleFS, "/template.html").setTemplateProcessor([](const String &var) -> String {
if (var == "USER") {
return String("Bob ") + uptimeInMinutes + " minutes";
}
return emptyString;
});
// Serve a template with dynamic content based on user request
//
// In this case, the template is served via a callback request. Data from the request
// is used to generate the template callback.
//
// curl -v -G -d "USER=Bob" http://192.168.4.1/user_request.html
server.on("/user_request.html", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(LittleFS, "/template.html", "text/html", false, [=](const String &var) -> String {
if (var == "USER") {
const AsyncWebParameter *param = request->getParam("USER");
if (param) {
return param->value();
}
}
return emptyString;
});
@@ -96,4 +142,11 @@ void setup() {
// not needed
void loop() {
delay(100);
// Compute uptime
unsigned currentUptimeInMinutes = millis() / (60 * 1000);
if (currentUptimeInMinutes != uptimeInMinutes) {
setUptimeInMinutes(currentUptimeInMinutes);
}
}