Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0 15 asyncwebserver 2.1.0 features #3799

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion wled00/fcn_declare.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@ void handleSerial();
void updateBaudRate(uint32_t rate);

//wled_server.cpp
String getFileContentType(String &filename);
void createEditHandler(bool enable);
void initServer();
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl="", byte optionT=255);
Expand Down
4 changes: 2 additions & 2 deletions wled00/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ void updateFSInfo() {
#endif
}


#if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
// caching presets in PSRAM may prevent occasional flashes seen when HomeAssitant polls WLED
// original idea by @akaricchi (https://github.com/Akaricchi)
Expand Down Expand Up @@ -420,8 +421,7 @@ bool handleFileRead(AsyncWebServerRequest* request, String path){
DEBUG_PRINT(F("WS FileRead: ")); DEBUG_PRINTLN(path);
if(path.endsWith("/")) path += "index.htm";
if(path.indexOf(F("sec")) > -1) return false;
String contentType = getFileContentType(path);
if(request->hasArg(F("download"))) contentType = F("application/octet-stream");
String contentType = request->hasArg(F("download")) ? F("application/octet-stream") : contentTypeFor(path);
/*String pathWithGz = path + ".gz";
if(WLED_FS.exists(pathWithGz)){
request->send(WLED_FS, pathWithGz, contentType);
Expand Down
4 changes: 2 additions & 2 deletions wled00/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,7 @@ void serveJson(AsyncWebServerRequest* request)
}
#endif
else if (url.indexOf("pal") > 0) {
request->send_P(200, "application/json", JSON_palette_names); // contentType defined in AsyncJson-v6.h
request->send_P(200, FPSTR(CONTENT_TYPE_JSON), JSON_palette_names);
return;
}
else if (url.indexOf(F("cfg")) > 0 && handleFileRead(request, F("/cfg.json"))) {
Expand Down Expand Up @@ -1185,7 +1185,7 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
#endif
oappend("}");
if (request) {
request->send(200, "application/json", buffer); // contentType defined in AsyncJson-v6.h
request->send(200, FPSTR(CONTENT_TYPE_JSON), buffer);
}
#ifdef WLED_ENABLE_WEBSOCKETS
else {
Expand Down
8 changes: 4 additions & 4 deletions wled00/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,16 +705,16 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
// so checkboxes have one or two fields (first is always "false", existence of second depends on checkmark and may be "true")
if (subObj[name].isNull()) {
// the first occurrence of the field describes the parameter type (used in next loop)
if (value == "false") subObj[name] = false; // checkboxes may have only one field
if (value == F("false")) subObj[name] = false; // checkboxes may have only one field
else subObj[name] = value;
} else {
String type = subObj[name].as<String>(); // get previously stored value as a type
if (subObj[name].is<bool>()) subObj[name] = true; // checkbox/boolean
else if (type == "number") {
else if (type == F("number")) {
value.replace(",","."); // just in case conversion
if (value.indexOf(".") >= 0) subObj[name] = value.toFloat(); // we do have a float
else subObj[name] = value.toInt(); // we may have an int
} else if (type == "int") subObj[name] = value.toInt();
} else if (type == F("int")) subObj[name] = value.toInt();
else subObj[name] = value; // text fields
}
DEBUG_PRINT(F(" = ")); DEBUG_PRINTLN(value);
Expand Down Expand Up @@ -775,7 +775,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
//HTTP API request parser
bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
{
if (!(req.indexOf("win") >= 0)) return false;
if (!(req.indexOf(F("win")) >= 0)) return false;

int pos = 0;
DEBUG_PRINT(F("API req: "));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ AsyncMqttClient::AsyncMqttClient()
sprintf(_generatedClientId, "esp32%06x", (uint32_t)ESP.getEfuseMac());
_xSemaphore = xSemaphoreCreateMutex();
#elif defined(ESP8266)
sprintf(_generatedClientId, "esp8266%06x", (uint32_t)ESP.getChipId());
sprintf_P(_generatedClientId, PSTR("esp8266%06x"), (uint32_t)ESP.getChipId());
#endif
_clientId = _generatedClientId;

Expand Down
6 changes: 2 additions & 4 deletions wled00/src/dependencies/json/AsyncJson-v6.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
#define DYNAMIC_JSON_DOCUMENT_SIZE 16384
#endif

constexpr const char* JSON_MIMETYPE = "application/json";

/*
* Json Response
* */
Expand Down Expand Up @@ -66,7 +64,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {

AsyncJsonResponse(JsonDocument *ref, bool isArray=false) : _jsonBuffer(1), _isValid{false} {
_code = 200;
_contentType = JSON_MIMETYPE;
_contentType = FPSTR(CONTENT_TYPE_JSON);
if(isArray)
_root = ref->to<JsonArray>();
else
Expand All @@ -75,7 +73,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {

AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
_code = 200;
_contentType = JSON_MIMETYPE;
_contentType = FPSTR(CONTENT_TYPE_JSON);
if(isArray)
_root = _jsonBuffer.createNestedArray();
else
Expand Down
62 changes: 19 additions & 43 deletions wled00/wled_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,11 @@ static const char s_unlock_ota [] PROGMEM = "Please unlock OTA in security setti
static const char s_unlock_cfg [] PROGMEM = "Please unlock settings using PIN code!";
static const char s_notimplemented[] PROGMEM = "Not implemented";
static const char s_accessdenied[] PROGMEM = "Access Denied";
static const char s_javascript[] PROGMEM = "application/javascript";
static const char s_json[] = "application/json"; // AsyncJson-v6.h
static const char s_html[] PROGMEM = "text/html";
static const char s_plain[] = "text/plain"; // Espalexa.h
static const char s_css[] PROGMEM = "text/css";
static const char s_png[] PROGMEM = "image/png";
static const char s_gif[] PROGMEM = "image/gif";
static const char s_jpg[] PROGMEM = "image/jpeg";
static const char s_ico[] PROGMEM = "image/x-icon";
//static const char s_xml[] PROGMEM = "text/xml";
//static const char s_pdf[] PROGMEM = "application/x-pdf";
//static const char s_zip[] PROGMEM = "application/x-zip";
//static const char s_gz[] PROGMEM = "application/x-gzip";

String getFileContentType(String &filename) {
if (filename.endsWith(F(".htm"))) return FPSTR(s_html);
else if (filename.endsWith(F(".html"))) return FPSTR(s_html);
else if (filename.endsWith(F(".css"))) return FPSTR(s_css);
else if (filename.endsWith(F(".js"))) return FPSTR(s_javascript);
else if (filename.endsWith(F(".json"))) return s_json;
else if (filename.endsWith(F(".png"))) return FPSTR(s_png);
else if (filename.endsWith(F(".gif"))) return FPSTR(s_gif);
else if (filename.endsWith(F(".jpg"))) return FPSTR(s_jpg);
else if (filename.endsWith(F(".ico"))) return FPSTR(s_ico);
// else if (filename.endsWith(F(".xml"))) return FPSTR(s_xml);
// else if (filename.endsWith(F(".pdf"))) return FPSTR(s_pdf);
// else if (filename.endsWith(F(".zip"))) return FPSTR(s_zip);
// else if (filename.endsWith(F(".gz"))) return FPSTR(s_gz);
return s_plain;
}
static const char* s_javascript = CONTENT_TYPE_JAVASCRIPT;
static const char* s_json = CONTENT_TYPE_JSON;
static const char* s_html = CONTENT_TYPE_HTML;
static const char* s_plain = CONTENT_TYPE_PLAIN;
static const char* s_css = CONTENT_TYPE_CSS;

//Is this an IP?
static bool isIp(String str) {
Expand Down Expand Up @@ -259,17 +234,17 @@ void initServer()

#ifdef WLED_ENABLE_WEBSOCKETS
#ifndef WLED_DISABLE_2D
server.on(SET_F("/liveview2D"), HTTP_GET, [](AsyncWebServerRequest *request) {
server.on(F("/liveview2D"), HTTP_GET, [](AsyncWebServerRequest *request) {
handleStaticContent(request, "", 200, FPSTR(s_html), PAGE_liveviewws2D, PAGE_liveviewws2D_length);
});
#endif
#endif
server.on(SET_F("/liveview"), HTTP_GET, [](AsyncWebServerRequest *request) {
server.on(F("/liveview"), HTTP_GET, [](AsyncWebServerRequest *request) {
handleStaticContent(request, "", 200, FPSTR(s_html), PAGE_liveview, PAGE_liveview_length);
});

//settings page
server.on(SET_F("/settings"), HTTP_GET, [](AsyncWebServerRequest *request){
server.on(F("/settings"), HTTP_GET, [](AsyncWebServerRequest *request){
serveSettings(request);
});

Expand All @@ -291,24 +266,25 @@ void initServer()
request->send(response);
});

server.on(SET_F("/welcome"), HTTP_GET, [](AsyncWebServerRequest *request){
server.on(F("/welcome"), HTTP_GET, [](AsyncWebServerRequest *request){
serveSettings(request);
});

server.on(SET_F("/reset"), HTTP_GET, [](AsyncWebServerRequest *request){
server.on(F("/reset"), HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 200,F("Rebooting now..."),F("Please wait ~10 seconds..."),129);
doReboot = true;
});

server.on(SET_F("/settings"), HTTP_POST, [](AsyncWebServerRequest *request){
server.on(F("/settings"), HTTP_POST, [](AsyncWebServerRequest *request){
serveSettings(request, true);
});

server.on(SET_F("/json"), HTTP_GET, [](AsyncWebServerRequest *request){
const static char _json[] PROGMEM = "/json";
server.on(FPSTR(_json), HTTP_GET, [](AsyncWebServerRequest *request){
serveJson(request);
});

AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler(F("/json"), [](AsyncWebServerRequest *request) {
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler(FPSTR(_json), [](AsyncWebServerRequest *request) {
bool verboseResponse = false;
bool isConfig = false;

Expand Down Expand Up @@ -360,15 +336,15 @@ void initServer()
}, JSON_BUFFER_SIZE);
server.addHandler(handler);

server.on(SET_F("/version"), HTTP_GET, [](AsyncWebServerRequest *request){
server.on(F("/version"), HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, FPSTR(s_plain), (String)VERSION);
});

server.on(SET_F("/uptime"), HTTP_GET, [](AsyncWebServerRequest *request){
server.on(F("/uptime"), HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, FPSTR(s_plain), (String)millis());
});

server.on(SET_F("/freeheap"), HTTP_GET, [](AsyncWebServerRequest *request){
server.on(F("/freeheap"), HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, FPSTR(s_plain), (String)ESP.getFreeHeap());
});

Expand All @@ -378,11 +354,11 @@ void initServer()
});
#endif

server.on(SET_F("/teapot"), HTTP_GET, [](AsyncWebServerRequest *request){
server.on(F("/teapot"), HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 418, F("418. I'm a teapot."), F("(Tangible Embedded Advanced Project Of Twinkling)"), 254);
});

server.on(SET_F("/upload"), HTTP_POST, [](AsyncWebServerRequest *request) {},
server.on(F("/upload"), HTTP_POST, [](AsyncWebServerRequest *request) {},
[](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data,
size_t len, bool final) {handleUpload(request, filename, index, data, len, final);}
);
Expand Down
21 changes: 6 additions & 15 deletions wled00/ws.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
void sendDataWs(AsyncWebSocketClient * client)
{
if (!ws.count()) return;
AsyncWebSocketMessageBuffer * buffer;

if (!requestJSONBufferLock(12)) {
if (client) {
Expand All @@ -129,7 +128,7 @@ void sendDataWs(AsyncWebSocketClient * client)
return;
}
#endif
buffer = ws.makeBuffer(len); // will not allocate correct memory sometimes on ESP8266
AsyncWebSocketSharedBuffer buffer(len); // will not allocate correct memory sometimes on ESP8266
#ifdef ESP8266
size_t heap2 = ESP.getFreeHeap();
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
Expand All @@ -141,23 +140,18 @@ void sendDataWs(AsyncWebSocketClient * client)
DEBUG_PRINTLN(F("WS buffer allocation failed."));
ws.closeAll(1013); //code 1013 = temporary overload, try again later
ws.cleanupClients(0); //disconnect all clients to release memory
ws._cleanBuffers();
return; //out of memory
}

buffer->lock();
serializeJson(*pDoc, (char *)buffer->get(), len);
serializeJson(*pDoc, (char *)buffer.data(), len);

DEBUG_PRINT(F("Sending WS data "));
if (client) {
client->text(buffer);
client->text(std::move(buffer));
DEBUG_PRINTLN(F("to a single client."));
} else {
ws.textAll(buffer);
DEBUG_PRINTLN(F("to multiple clients."));
}
buffer->unlock();
ws._cleanBuffers();

releaseJSONBufferLock();
}
Expand Down Expand Up @@ -187,11 +181,10 @@ bool sendLiveLedsWs(uint32_t wsClient)
#endif
size_t bufSize = pos + (used/n)*3;

AsyncWebSocketMessageBuffer * wsBuf = ws.makeBuffer(bufSize);
AsyncWebSocketSharedBuffer wsBuf(bufSize);
if (!wsBuf) return false; //out of memory
uint8_t* buffer = wsBuf->get();
uint8_t* buffer = reinterpret_cast<uint8_t*>(wsBuf.data());
if (!buffer) return false; //out of memory
wsBuf->lock(); // protect buffer from being cleaned by another WS instance
buffer[0] = 'L';
buffer[1] = 1; //version

Expand All @@ -218,9 +211,7 @@ bool sendLiveLedsWs(uint32_t wsClient)
buffer[pos++] = scale8(qadd8(w, b), strip.getBrightness()); //B
}

wsc->binary(wsBuf);
wsBuf->unlock(); // un-protect buffer
ws._cleanBuffers();
wsc->binary(std::move(wsBuf));
return true;
}

Expand Down