From 2f784268f0a358741ee6384480d48656e159d726 Mon Sep 17 00:00:00 2001 From: Pablo Clemente Maseda Date: Wed, 24 Feb 2021 23:03:28 +0100 Subject: [PATCH 1/9] Redefine DYNAMIC_JSON_DOCUMENT_SIZE if not defined (#922) --- src/AsyncJson.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 27b4a26f6..2fa6a2d26 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -41,7 +41,9 @@ #if ARDUINOJSON_VERSION_MAJOR == 5 #define ARDUINOJSON_5_COMPATIBILITY #else - #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 + #ifndef DYNAMIC_JSON_DOCUMENT_SIZE + #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 + #endif #endif constexpr const char* JSON_MIMETYPE = "application/json"; From 5613e66f6768b5a5f1629e0931992cd020856a0a Mon Sep 17 00:00:00 2001 From: JDavid Date: Mon, 26 Jul 2021 12:40:52 -0500 Subject: [PATCH 2/9] Fix build when using latest arduino-esp32 master due to IDF update (#999) * Fix build when using latest arduino-esp32 master due to IDF update https://github.com/espressif/arduino-esp32/commit/a618fc1361b08aa968407dd81b7b065cca207f46 * Fix build when using WebSockets --- src/AsyncWebSocket.cpp | 23 +++++++---------------- src/WebAuthentication.cpp | 6 +++--- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 52dcd75f0..f76f2fc96 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -24,18 +24,7 @@ #include #ifndef ESP8266 -extern "C" { -typedef struct { - uint32_t state[5]; - uint32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); -void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); -void SHA1Final(unsigned char digest[20], SHA1_CTX* context); -} +#include "mbedtls/sha1.h" #else #include #endif @@ -1268,10 +1257,12 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket sha1(key + WS_STR_UUID, hash); #else (String&)key += WS_STR_UUID; - SHA1_CTX ctx; - SHA1Init(&ctx); - SHA1Update(&ctx, (const unsigned char*)key.c_str(), key.length()); - SHA1Final(hash, &ctx); + mbedtls_sha1_context ctx; + mbedtls_sha1_init(&ctx); + mbedtls_sha1_starts_ret(&ctx); + mbedtls_sha1_update_ret(&ctx, (const unsigned char*)key.c_str(), key.length()); + mbedtls_sha1_finish_ret(&ctx, hash); + mbedtls_sha1_free(&ctx); #endif base64_encodestate _state; base64_init_encodestate(&_state); diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 2feca5420..45246a196 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -71,9 +71,9 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo memset(_buf, 0x00, 16); #ifdef ESP32 mbedtls_md5_init(&_ctx); - mbedtls_md5_starts(&_ctx); - mbedtls_md5_update(&_ctx, data, len); - mbedtls_md5_finish(&_ctx, _buf); + mbedtls_md5_starts_ret(&_ctx); + mbedtls_md5_update_ret(&_ctx, data, len); + mbedtls_md5_finish_ret(&_ctx, _buf); #else MD5Init(&_ctx); MD5Update(&_ctx, data, len); From 1d46269cedf477661ca8a29518414f4b74e957d4 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Mon, 26 Jul 2021 20:50:50 +0300 Subject: [PATCH 3/9] Stop PIO CI --- .github/workflows/push.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index abdea4627..231dc5292 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -21,14 +21,14 @@ jobs: - name: Build Tests run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 0 1 - build-pio: - name: PlatformIO for ${{ matrix.board }} on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] - board: [esp32, esp8266] - steps: - - uses: actions/checkout@v1 - - name: Build Tests - run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 1 1 +# build-pio: +# name: PlatformIO for ${{ matrix.board }} on ${{ matrix.os }} +# runs-on: ${{ matrix.os }} +# strategy: +# matrix: +# os: [ubuntu-latest, windows-latest, macOS-latest] +# board: [esp32, esp8266] +# steps: +# - uses: actions/checkout@v1 +# - name: Build Tests +# run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 1 1 From f71e3d427b5be9791a8a2c93cf8079792c3a9a26 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 26 Mar 2022 00:02:59 +0200 Subject: [PATCH 4/9] Avoid breaking changes with strict dependencies (#1133) --- library.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library.json b/library.json index 556592793..750ca28d2 100644 --- a/library.json +++ b/library.json @@ -18,11 +18,15 @@ "platforms": ["espressif8266", "espressif32"], "dependencies": [ { + "owner": "me-no-dev", "name": "ESPAsyncTCP", + "version": "^1.2.2", "platforms": "espressif8266" }, { + "owner": "me-no-dev", "name": "AsyncTCP", + "version": "^1.1.1", "platforms": "espressif32" }, { From dfe007854e318ac0ffb4423d51f06eef820b51ed Mon Sep 17 00:00:00 2001 From: vlastahajek Date: Thu, 6 Jan 2022 11:00:17 +0100 Subject: [PATCH 5/9] feat: added global filter and global disconnect --- src/ESPAsyncWebServer.h | 9 +++++++++ src/WebServer.cpp | 29 ++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 3aff61b59..c5aabb4e7 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -409,12 +409,16 @@ typedef std::function ArRequestHandlerFunc typedef std::function ArUploadHandlerFunction; typedef std::function ArBodyHandlerFunction; +typedef std::function ASDisconnectHandler; + class AsyncWebServer { protected: AsyncServer _server; LinkedList _rewrites; LinkedList _handlers; AsyncCallbackWebHandler* _catchAllHandler; + ASDisconnectHandler _onDisconnectfn; + ArRequestFilterFunction _filter; public: AsyncWebServer(uint16_t port); @@ -435,6 +439,10 @@ class AsyncWebServer { AsyncWebHandler& addHandler(AsyncWebHandler* handler); bool removeHandler(AsyncWebHandler* handler); + // Filter returns true of request should be processed. + // In case of false is returned, filter must set own handler + AsyncWebServer& setFilter(ArRequestFilterFunction fn); + AsyncCallbackWebHandler& on(const char* uri, ArRequestHandlerFunction onRequest); AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest); AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload); @@ -445,6 +453,7 @@ class AsyncWebServer { void onNotFound(ArRequestHandlerFunction fn); //called when handler is not assigned void onFileUpload(ArUploadHandlerFunction fn); //handle file uploads void onRequestBody(ArBodyHandlerFunction fn); //handle posts with plain body content (JSON often transmitted this way as a request) + void onDisconnect (ASDisconnectHandler fn); // handle disconnect globally void reset(); //remove all writers and handlers, with onNotFound/onFileUpload/onRequestBody diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 62e85b23a..0ab84a57a 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -39,6 +39,8 @@ AsyncWebServer::AsyncWebServer(uint16_t port) : _server(port) , _rewrites(LinkedList([](AsyncWebRewrite* r){ delete r; })) , _handlers(LinkedList([](AsyncWebHandler* h){ delete h; })) + , _onDisconnectfn(nullptr) + ,_filter (nullptr) { _catchAllHandler = new AsyncCallbackWebHandler(); if(_catchAllHandler == NULL) @@ -84,6 +86,11 @@ bool AsyncWebServer::removeHandler(AsyncWebHandler *handler){ return _handlers.remove(handler); } +AsyncWebServer& AsyncWebServer::setFilter(ArRequestFilterFunction fn) { + _filter = fn; + return *this; +} + void AsyncWebServer::begin(){ _server.setNoDelay(true); _server.begin(); @@ -103,7 +110,14 @@ void AsyncWebServer::beginSecure(const char *cert, const char *key, const char * } #endif +void AsyncWebServer::onDisconnect (ASDisconnectHandler fn){ + _onDisconnectfn=fn; +} + void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest *request){ + if(_onDisconnectfn) { + _onDisconnectfn(request); + } delete request; } @@ -117,15 +131,16 @@ void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest *request){ } void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request){ - for(const auto& h: _handlers){ - if (h->filter(request) && h->canHandle(request)){ - request->setHandler(h); - return; + if(!_filter || _filter(request)) { + for(const auto& h: _handlers){ + if (h->filter(request) && h->canHandle(request)){ + request->setHandler(h); + return; + } } + request->addInterestingHeader(F("ANY")); + request->setHandler(_catchAllHandler); } - - request->addInterestingHeader(F("ANY")); - request->setHandler(_catchAllHandler); } From 9457c973ccb9372047542a07b86d7640d7281174 Mon Sep 17 00:00:00 2001 From: vlastahajek Date: Tue, 22 Feb 2022 13:08:24 +0100 Subject: [PATCH 6/9] feat: allowing all strings, including flash strings, as a URI --- src/ESPAsyncWebServer.h | 8 ++++---- src/WebServer.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index c5aabb4e7..9687f5933 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -443,10 +443,10 @@ class AsyncWebServer { // In case of false is returned, filter must set own handler AsyncWebServer& setFilter(ArRequestFilterFunction fn); - AsyncCallbackWebHandler& on(const char* uri, ArRequestHandlerFunction onRequest); - AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest); - AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload); - AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody); + AsyncCallbackWebHandler& on(const String &uri, ArRequestHandlerFunction onRequest); + AsyncCallbackWebHandler& on(const String &uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest); + AsyncCallbackWebHandler& on(const String &uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload); + AsyncCallbackWebHandler& on(const String &uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody); AsyncStaticWebHandler& serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control = NULL); diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 0ab84a57a..dff0721cf 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -144,7 +144,7 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request){ } -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody){ +AsyncCallbackWebHandler& AsyncWebServer::on(const String &uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody){ AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); handler->setMethod(method); @@ -155,7 +155,7 @@ AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodCom return *handler; } -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload){ +AsyncCallbackWebHandler& AsyncWebServer::on(const String &uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload){ AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); handler->setMethod(method); @@ -165,7 +165,7 @@ AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodCom return *handler; } -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest){ +AsyncCallbackWebHandler& AsyncWebServer::on(const String &uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest){ AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); handler->setMethod(method); @@ -174,7 +174,7 @@ AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodCom return *handler; } -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, ArRequestHandlerFunction onRequest){ +AsyncCallbackWebHandler& AsyncWebServer::on(const String &uri, ArRequestHandlerFunction onRequest){ AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); handler->onRequest(onRequest); From 7f1ec4fa0496b582da4e8fdaa9b33a30faabc63b Mon Sep 17 00:00:00 2001 From: vlastahajek Date: Wed, 6 Apr 2022 14:45:28 +0200 Subject: [PATCH 7/9] feat: begin returns status --- src/ESPAsyncWebServer.h | 2 +- src/WebServer.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 9687f5933..f021e4f34 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -424,7 +424,7 @@ class AsyncWebServer { AsyncWebServer(uint16_t port); ~AsyncWebServer(); - void begin(); + int8_t begin(); void end(); #if ASYNC_TCP_SSL_ENABLED diff --git a/src/WebServer.cpp b/src/WebServer.cpp index dff0721cf..a17f7dc57 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -91,9 +91,9 @@ AsyncWebServer& AsyncWebServer::setFilter(ArRequestFilterFunction fn) { return *this; } -void AsyncWebServer::begin(){ +int8_t AsyncWebServer::begin(){ _server.setNoDelay(true); - _server.begin(); + return _server.begin(); } void AsyncWebServer::end(){ From 1e029ff69f032b9589689f51c414489adfbccebc Mon Sep 17 00:00:00 2001 From: vlastahajek Date: Fri, 6 May 2022 08:53:52 +0200 Subject: [PATCH 8/9] feat: allow wildcard endpoint --- src/AsyncJson.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 2fa6a2d26..8ed4373bd 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -201,9 +201,15 @@ class AsyncCallbackJsonWebHandler: public AsyncWebHandler { if(!(_method & request->method())) return false; - - if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/"))) - return false; + + if (_uri.length() && _uri.endsWith("*")) { + String uriTemplate = String(_uri); + uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); + if (!request->url().startsWith(uriTemplate)) + return false; + } else + if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/"))) + return false; if ( !request->contentType().equalsIgnoreCase(JSON_MIMETYPE) ) return false; From 24c81ac3c303acc74bf8e54692379eb67dd0fbfd Mon Sep 17 00:00:00 2001 From: "mirek.malecha@bonitoo.io" Date: Mon, 24 Jul 2023 17:08:22 +0200 Subject: [PATCH 9/9] fix: IPAddress(uint32_t) support fix: NULL pointer error in SPIFFSEditor --- src/AsyncWebSocket.cpp | 2 +- src/SPIFFSEditor.cpp | 50 ++++++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index ba427ba43..a801bb0d8 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -900,7 +900,7 @@ void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) IPAddress AsyncWebSocketClient::remoteIP() { if(!_client) { - return IPAddress(0U); + return IPAddress((uint32_t)0); } return _client->remoteIP(); } diff --git a/src/SPIFFSEditor.cpp b/src/SPIFFSEditor.cpp index 343ed79e0..548776354 100644 --- a/src/SPIFFSEditor.cpp +++ b/src/SPIFFSEditor.cpp @@ -7,7 +7,7 @@ #include "edit.htm.gz.h" #endif -#ifdef ESP32 +#ifdef ESP32 #define fullName(x) name(x) #endif @@ -33,13 +33,13 @@ static bool matchWild(const char *pattern, const char *testee) { nxPat=pattern++; nxTst=testee; continue; } - if (nxPat){ + if (nxPat){ pattern = nxPat+1; testee=++nxTst; continue; } return false; } - while (*pattern=='*'){pattern++;} + while (*pattern=='*'){pattern++;} return (*pattern == 0); } @@ -200,7 +200,7 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ #endif String fname = entry.fullName(); if (fname.charAt(0) != '/') fname = "/" + fname; - + if (isExcluded(_fs, fname.c_str())) { #ifdef ESP32 entry = dir.openNextFile(); @@ -236,14 +236,16 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ if (request->header(F("If-Modified-Since")).equals(buildTime)) { request->send(304); } else { -#ifdef EDFS - AsyncWebServerResponse *response = request->beginResponse(_fs, F("/edit_gz"), F("text/html"), false); +#ifdef EDFS + AsyncWebServerResponse *response = request->beginResponse(_fs, F("/edit.htm.gz"), F("text/html"), false); #else AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), edit_htm_gz, edit_htm_gz_len); #endif - response->addHeader(F("Content-Encoding"), F("gzip")); - response->addHeader(F("Last-Modified"), buildTime); - request->send(response); + if (response) { + response->addHeader(F("Content-Encoding"), F("gzip")); + response->addHeader(F("Last-Modified"), buildTime); + request->send(response); + } } } } else if(request->method() == HTTP_DELETE){ @@ -252,45 +254,45 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ #ifdef ESP32 _fs.rmdir(request->getParam(F("path"), true)->value()); // try rmdir for littlefs #endif - } - + } + request->send(200, "", String(F("DELETE: "))+request->getParam(F("path"), true)->value()); } else request->send(404); } else if(request->method() == HTTP_POST){ if(request->hasParam(F("data"), true, true) && _fs.exists(request->getParam(F("data"), true, true)->value())) request->send(200, "", String(F("UPLOADED: "))+request->getParam(F("data"), true, true)->value()); - + else if(request->hasParam(F("rawname"), true) && request->hasParam(F("raw0"), true)){ String rawnam = request->getParam(F("rawname"), true)->value(); - + if (_fs.exists(rawnam)) _fs.remove(rawnam); // delete it to allow a mode - + int k = 0; uint16_t i = 0; fs::File f = _fs.open(rawnam, "a"); - + while (request->hasParam(String(F("raw")) + String(k), true)) { //raw0 .. raw1 if(f){ - i += f.print(request->getParam(String(F("raw")) + String(k), true)->value()); + i += f.print(request->getParam(String(F("raw")) + String(k), true)->value()); } k++; } f.close(); request->send(200, "", String(F("IPADWRITE: ")) + rawnam + ":" + String(i)); - + } else { request->send(500); - } - + } + } else if(request->method() == HTTP_PUT){ if(request->hasParam(F("path"), true)){ String filename = request->getParam(F("path"), true)->value(); if(_fs.exists(filename)){ request->send(200); - } else { + } else { /*******************************************************/ -#ifdef ESP32 +#ifdef ESP32 if (strchr(filename.c_str(), '/')) { // For file creation, silently make subdirs as needed. If any fail, // it will be caught by the real file open later on @@ -306,9 +308,9 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ } } free(pathStr); - } -#endif -/*******************************************************/ + } +#endif +/*******************************************************/ fs::File f = _fs.open(filename, "w"); if(f){ f.write((uint8_t)0x00);