ESP-NOW packet modification
- include up to 5 segments in 1st packet - header contains total number of packets (instead of segments) web server code reorganise
This commit is contained in:
@@ -11,14 +11,6 @@
|
||||
#endif
|
||||
#include "html_cpal.h"
|
||||
|
||||
/*
|
||||
* Integrated HTTP web server page declarations
|
||||
*/
|
||||
|
||||
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request, int code, uint16_t eTagSuffix = 0);
|
||||
void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix = 0);
|
||||
void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip = true, uint16_t eTagSuffix = 0);
|
||||
|
||||
// define flash strings once (saves flash memory)
|
||||
static const char s_redirecting[] PROGMEM = "Redirecting...";
|
||||
static const char s_content_enc[] PROGMEM = "Content-Encoding";
|
||||
@@ -33,7 +25,7 @@ static const char s_plain[] PROGMEM = "text/plain";
|
||||
static const char s_css[] PROGMEM = "text/css";
|
||||
|
||||
//Is this an IP?
|
||||
bool isIp(String str) {
|
||||
static bool isIp(String str) {
|
||||
for (size_t i = 0; i < str.length(); i++) {
|
||||
int c = str.charAt(i);
|
||||
if (c != '.' && (c < '0' || c > '9')) {
|
||||
@@ -43,7 +35,128 @@ bool isIp(String str) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
/*
|
||||
* Integrated HTTP web server page declarations
|
||||
*/
|
||||
|
||||
static void generateEtag(char *etag, uint16_t eTagSuffix) {
|
||||
sprintf_P(etag, PSTR("%7d-%02x-%04x"), VERSION, cacheInvalidate, eTagSuffix);
|
||||
}
|
||||
|
||||
static void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix = 0) {
|
||||
// Only send ETag for 200 (OK) responses
|
||||
if (code != 200) return;
|
||||
|
||||
// https://medium.com/@codebyamir/a-web-developers-guide-to-browser-caching-cc41f3b73e7c
|
||||
#ifndef WLED_DEBUG
|
||||
// this header name is misleading, "no-cache" will not disable cache,
|
||||
// it just revalidates on every load using the "If-None-Match" header with the last ETag value
|
||||
response->addHeader(F("Cache-Control"), F("no-cache"));
|
||||
#else
|
||||
response->addHeader(F("Cache-Control"), F("no-store,max-age=0")); // prevent caching if debug build
|
||||
#endif
|
||||
char etag[32];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
response->addHeader(F("ETag"), etag);
|
||||
}
|
||||
|
||||
static bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest *request, int code, uint16_t eTagSuffix = 0) {
|
||||
// Only send 304 (Not Modified) if response code is 200 (OK)
|
||||
if (code != 200) return false;
|
||||
|
||||
AsyncWebHeader *header = request->getHeader(F("If-None-Match"));
|
||||
char etag[32];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
if (header && header->value() == etag) {
|
||||
AsyncWebServerResponse *response = request->beginResponse(304);
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the request for a static file.
|
||||
* If the file was found in the filesystem, it will be sent to the client.
|
||||
* Otherwise it will be checked if the browser cached the file and if so, a 304 response will be sent.
|
||||
* If the file was not found in the filesystem and not in the browser cache, the request will be handled as a 200 response with the content of the page.
|
||||
*
|
||||
* @param request The request object
|
||||
* @param path If a file with this path exists in the filesystem, it will be sent to the client. Set to "" to skip this check.
|
||||
* @param code The HTTP status code
|
||||
* @param contentType The content type of the web page
|
||||
* @param content Content of the web page
|
||||
* @param len Length of the content
|
||||
* @param gzip Optional. Defaults to true. If false, the gzip header will not be added.
|
||||
* @param eTagSuffix Optional. Defaults to 0. A suffix that will be added to the ETag header. This can be used to invalidate the cache for a specific page.
|
||||
*/
|
||||
static void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip = true, uint16_t eTagSuffix = 0) {
|
||||
if (path != "" && handleFileRead(request, path)) return;
|
||||
if (handleIfNoneMatchCacheHeader(request, code, eTagSuffix)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(code, contentType, content, len);
|
||||
if (gzip) response->addHeader(FPSTR(s_content_enc), F("gzip"));
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
#ifdef WLED_ENABLE_DMX
|
||||
static String dmxProcessor(const String& var)
|
||||
{
|
||||
String mapJS;
|
||||
if (var == F("DMXVARS")) {
|
||||
mapJS += F("\nCN=");
|
||||
mapJS += String(DMXChannels);
|
||||
mapJS += F(";\nCS=");
|
||||
mapJS += String(DMXStart);
|
||||
mapJS += F(";\nCG=");
|
||||
mapJS += String(DMXGap);
|
||||
mapJS += F(";\nLC=");
|
||||
mapJS += String(strip.getLengthTotal());
|
||||
mapJS += F(";\nvar CH=[");
|
||||
for (int i=0; i<15; i++) {
|
||||
mapJS += String(DMXFixtureMap[i]) + ',';
|
||||
}
|
||||
mapJS += F("0];");
|
||||
}
|
||||
return mapJS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static String msgProcessor(const String& var)
|
||||
{
|
||||
if (var == "MSG") {
|
||||
String messageBody = messageHead;
|
||||
messageBody += F("</h2>");
|
||||
messageBody += messageSub;
|
||||
uint32_t optt = optionType;
|
||||
|
||||
if (optt < 60) //redirect to settings after optionType seconds
|
||||
{
|
||||
messageBody += F("<script>setTimeout(RS,");
|
||||
messageBody +=String(optt*1000);
|
||||
messageBody += F(")</script>");
|
||||
} else if (optt < 120) //redirect back after optionType-60 seconds, unused
|
||||
{
|
||||
//messageBody += "<script>setTimeout(B," + String((optt-60)*1000) + ")</script>";
|
||||
} else if (optt < 180) //reload parent after optionType-120 seconds
|
||||
{
|
||||
messageBody += F("<script>setTimeout(RP,");
|
||||
messageBody += String((optt-120)*1000);
|
||||
messageBody += F(")</script>");
|
||||
} else if (optt == 253)
|
||||
{
|
||||
messageBody += F("<br><br><form action=/settings><button class=\"bt\" type=submit>Back</button></form>"); //button to settings
|
||||
} else if (optt == 254)
|
||||
{
|
||||
messageBody += F("<br><br><button type=\"button\" class=\"bt\" onclick=\"B()\">Back</button>");
|
||||
}
|
||||
return messageBody;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
static void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
if (!correctPIN) {
|
||||
if (final) request->send(401, FPSTR(s_plain), FPSTR(s_unlock_cfg));
|
||||
return;
|
||||
@@ -96,7 +209,7 @@ void createEditHandler(bool enable) {
|
||||
}
|
||||
}
|
||||
|
||||
bool captivePortal(AsyncWebServerRequest *request)
|
||||
static bool captivePortal(AsyncWebServerRequest *request)
|
||||
{
|
||||
if (!apActive) return false; //only serve captive in AP mode
|
||||
if (!request->hasHeader("Host")) return false;
|
||||
@@ -368,102 +481,6 @@ void initServer()
|
||||
});
|
||||
}
|
||||
|
||||
void generateEtag(char *etag, uint16_t eTagSuffix) {
|
||||
sprintf_P(etag, PSTR("%7d-%02x-%04x"), VERSION, cacheInvalidate, eTagSuffix);
|
||||
}
|
||||
|
||||
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest *request, int code, uint16_t eTagSuffix) {
|
||||
// Only send 304 (Not Modified) if response code is 200 (OK)
|
||||
if (code != 200) return false;
|
||||
|
||||
AsyncWebHeader *header = request->getHeader(F("If-None-Match"));
|
||||
char etag[32];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
if (header && header->value() == etag) {
|
||||
AsyncWebServerResponse *response = request->beginResponse(304);
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix) {
|
||||
// Only send ETag for 200 (OK) responses
|
||||
if (code != 200) return;
|
||||
|
||||
// https://medium.com/@codebyamir/a-web-developers-guide-to-browser-caching-cc41f3b73e7c
|
||||
#ifndef WLED_DEBUG
|
||||
// this header name is misleading, "no-cache" will not disable cache,
|
||||
// it just revalidates on every load using the "If-None-Match" header with the last ETag value
|
||||
response->addHeader(F("Cache-Control"), F("no-cache"));
|
||||
#else
|
||||
response->addHeader(F("Cache-Control"), F("no-store,max-age=0")); // prevent caching if debug build
|
||||
#endif
|
||||
char etag[32];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
response->addHeader(F("ETag"), etag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handels the request for a static file.
|
||||
* If the file was found in the filesystem, it will be sent to the client.
|
||||
* Otherwise it will be checked if the browser cached the file and if so, a 304 response will be sent.
|
||||
* If the file was not found in the filesystem and not in the browser cache, the request will be handled as a 200 response with the content of the page.
|
||||
*
|
||||
* @param request The request object
|
||||
* @param path If a file with this path exists in the filesystem, it will be sent to the client. Set to "" to skip this check.
|
||||
* @param code The HTTP status code
|
||||
* @param contentType The content type of the web page
|
||||
* @param content Content of the web page
|
||||
* @param len Length of the content
|
||||
* @param gzip Optional. Defaults to true. If false, the gzip header will not be added.
|
||||
* @param eTagSuffix Optional. Defaults to 0. A suffix that will be added to the ETag header. This can be used to invalidate the cache for a specific page.
|
||||
*/
|
||||
void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip, uint16_t eTagSuffix) {
|
||||
if (path != "" && handleFileRead(request, path)) return;
|
||||
if (handleIfNoneMatchCacheHeader(request, code, eTagSuffix)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(code, contentType, content, len);
|
||||
if (gzip) response->addHeader(FPSTR(s_content_enc), F("gzip"));
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
String msgProcessor(const String& var)
|
||||
{
|
||||
if (var == "MSG") {
|
||||
String messageBody = messageHead;
|
||||
messageBody += F("</h2>");
|
||||
messageBody += messageSub;
|
||||
uint32_t optt = optionType;
|
||||
|
||||
if (optt < 60) //redirect to settings after optionType seconds
|
||||
{
|
||||
messageBody += F("<script>setTimeout(RS,");
|
||||
messageBody +=String(optt*1000);
|
||||
messageBody += F(")</script>");
|
||||
} else if (optt < 120) //redirect back after optionType-60 seconds, unused
|
||||
{
|
||||
//messageBody += "<script>setTimeout(B," + String((optt-60)*1000) + ")</script>";
|
||||
} else if (optt < 180) //reload parent after optionType-120 seconds
|
||||
{
|
||||
messageBody += F("<script>setTimeout(RP,");
|
||||
messageBody += String((optt-120)*1000);
|
||||
messageBody += F(")</script>");
|
||||
} else if (optt == 253)
|
||||
{
|
||||
messageBody += F("<br><br><form action=/settings><button class=\"bt\" type=submit>Back</button></form>"); //button to settings
|
||||
} else if (optt == 254)
|
||||
{
|
||||
messageBody += F("<br><br><button type=\"button\" class=\"bt\" onclick=\"B()\">Back</button>");
|
||||
}
|
||||
return messageBody;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
|
||||
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl, byte optionT)
|
||||
{
|
||||
@@ -487,29 +504,6 @@ void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t erro
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
#ifdef WLED_ENABLE_DMX
|
||||
String dmxProcessor(const String& var)
|
||||
{
|
||||
String mapJS;
|
||||
if (var == F("DMXVARS")) {
|
||||
mapJS += F("\nCN=");
|
||||
mapJS += String(DMXChannels);
|
||||
mapJS += F(";\nCS=");
|
||||
mapJS += String(DMXStart);
|
||||
mapJS += F(";\nCG=");
|
||||
mapJS += String(DMXGap);
|
||||
mapJS += F(";\nLC=");
|
||||
mapJS += String(strip.getLengthTotal());
|
||||
mapJS += F(";\nvar CH=[");
|
||||
for (int i=0; i<15; i++) {
|
||||
mapJS += String(DMXFixtureMap[i]) + ',';
|
||||
}
|
||||
mapJS += F("0];");
|
||||
}
|
||||
return mapJS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void serveSettingsJS(AsyncWebServerRequest* request)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user