From e37ac9defd046e2da24075ef7269edcc06539c47 Mon Sep 17 00:00:00 2001 From: Pablo2048 Date: Tue, 30 Jul 2024 13:52:59 +0200 Subject: [PATCH] Verze 3.1.2 --- README.md | 23 ++-- docs/index.md | 23 ++-- examples/SimpleServer/SimpleServer.ino | 79 ++++++++++++-- library.json_ | 4 +- library.properties | 2 +- platformio.ini | 24 +++- src/AsyncJson.h | 36 +----- src/AsyncMessagePack.h | 145 +++++++++++++++++++++++++ src/ChunkPrint.h | 32 ++++++ src/ESPAsyncWebServer.h | 4 +- src/literals.h | 2 + 11 files changed, 308 insertions(+), 66 deletions(-) create mode 100644 src/AsyncMessagePack.h create mode 100644 src/ChunkPrint.h diff --git a/README.md b/README.md index 029def8..19ab602 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,20 @@ Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static Fi This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. +## Coordinate and dependencies: + +**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. + +``` +mathieucarbou/ESPAsyncWebServer @ 3.1.2 +``` + +Dependency: + +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) + ## Changes in this fork - [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add RP2040 support ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) @@ -22,11 +36,12 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.3` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.4` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable +- [@mathieucarbou](https://github.com/mathieucarbou): MessagePack Support ([#62](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/62)) - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 - [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor to reduce library size and maintainance. SPIFF si also deprecated. If you need it, please copy the files from the original repository in your project. This fork focus on maintaining the server part and the SPIFFEditor is an application which has nothing to do inside a server library. - [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. @@ -39,12 +54,6 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) - [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) -## Dependencies: - -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) -- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) -- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) - ## Documentation Usage and API stays the same as the original library. diff --git a/docs/index.md b/docs/index.md index 029def8..19ab602 100644 --- a/docs/index.md +++ b/docs/index.md @@ -9,6 +9,20 @@ Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static Fi This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. +## Coordinate and dependencies: + +**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. + +``` +mathieucarbou/ESPAsyncWebServer @ 3.1.2 +``` + +Dependency: + +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) + ## Changes in this fork - [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add RP2040 support ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) @@ -22,11 +36,12 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.3` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.4` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable +- [@mathieucarbou](https://github.com/mathieucarbou): MessagePack Support ([#62](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/62)) - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 - [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor to reduce library size and maintainance. SPIFF si also deprecated. If you need it, please copy the files from the original repository in your project. This fork focus on maintaining the server part and the SPIFFEditor is an application which has nothing to do inside a server library. - [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. @@ -39,12 +54,6 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) - [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) -## Dependencies: - -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) -- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) -- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) - ## Documentation Usage and API stays the same as the original library. diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 2472674..f3a1605 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -16,12 +16,14 @@ #include #include #endif + #include -AsyncWebServer server(80); +#include +#include +#include -const char* ssid = "YOUR_SSID"; -const char* password = "YOUR_PASSWORD"; +AsyncWebServer server(80); const char* PARAM_MESSAGE = "message"; @@ -29,18 +31,24 @@ void notFound(AsyncWebServerRequest* request) { request->send(404, "text/plain", "Not found"); } +AsyncCallbackJsonWebHandler* jsonHandler = new AsyncCallbackJsonWebHandler("/json2"); +AsyncCallbackMessagePackWebHandler* msgPackHandler = new AsyncCallbackMessagePackWebHandler("/msgpack2"); + void setup() { Serial.begin(115200); - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.printf("WiFi Failed!\n"); - return; - } - Serial.print("IP Address: "); - Serial.println(WiFi.localIP()); + // WiFi.mode(WIFI_STA); + // WiFi.begin("YOUR_SSID", "YOUR_PASSWORD"); + // if (WiFi.waitForConnectResult() != WL_CONNECTED) { + // Serial.printf("WiFi Failed!\n"); + // return; + // } + // Serial.print("IP Address: "); + // Serial.println(WiFi.localIP()); + + WiFi.mode(WIFI_AP); + WiFi.softAP("esp-captive"); server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "Hello, world"); @@ -68,6 +76,55 @@ void setup() { request->send(200, "text/plain", "Hello, POST: " + message); }); + // JSON + + // receives JSON and sends JSON + jsonHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { + JsonObject jsonObj = json.as(); + // ... + + AsyncJsonResponse* response = new AsyncJsonResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = "world"; + response->setLength(); + request->send(response); + }); + + // sends JSON + server.on("/json1", HTTP_GET, [](AsyncWebServerRequest* request) { + AsyncJsonResponse* response = new AsyncJsonResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = "world"; + response->setLength(); + request->send(response); + }); + + // MessagePack + + // receives MessagePack and sends MessagePack + msgPackHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { + JsonObject jsonObj = json.as(); + // ... + + AsyncMessagePackResponse* response = new AsyncMessagePackResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = "world"; + response->setLength(); + request->send(response); + }); + + // sends MessagePack + server.on("/msgpack1", HTTP_GET, [](AsyncWebServerRequest* request) { + AsyncMessagePackResponse* response = new AsyncMessagePackResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = "world"; + response->setLength(); + request->send(response); + }); + + server.addHandler(jsonHandler); + server.addHandler(msgPackHandler); + server.onNotFound(notFound); server.begin(); diff --git a/library.json_ b/library.json_ index 4d322f2..e2c7953 100644 --- a/library.json_ +++ b/library.json_ @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.1.1", + "version": "3.1.2", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.3", + "version": "^3.2.4", "platforms": "espressif32" }, { diff --git a/library.properties b/library.properties index f3647ad..8c610fd 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.1.1 +version=3.1.2 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/platformio.ini b/platformio.ini index 01110bf..e621af8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,25 +16,25 @@ monitor_filters = esp32_exception_decoder, log2file [platformio] lib_dir = . ; src_dir = examples/CaptivePortal -; src_dir = examples/SimpleServer +src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Draft -src_dir = examples/issues/Issue14 +; src_dir = examples/issues/Issue14 [env:arduino] platform = espressif32 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.3 + mathieucarbou/AsyncTCP @ 3.2.4 [env:arduino-2] platform = espressif32@6.7.0 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.3 + mathieucarbou/AsyncTCP @ 3.2.4 [env:arduino-3] platform = espressif32 @@ -44,7 +44,7 @@ platform_packages= board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.3 + mathieucarbou/AsyncTCP @ 3.2.4 [env:esp8266] platform = espressif8266 @@ -64,3 +64,17 @@ board = rpipicow lib_deps = bblanchon/ArduinoJson @ 7.1.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 + +[env:pioarduino-esp32dev] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +board = esp32dev +lib_deps = + bblanchon/ArduinoJson @ 7.1.0 + mathieucarbou/AsyncTCP @ 3.2.3 + +[env:pioarduino-c6] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +board = esp32-c6-devkitc-1 +lib_deps = + bblanchon/ArduinoJson @ 7.1.0 + mathieucarbou/AsyncTCP @ 3.2.4 diff --git a/src/AsyncJson.h b/src/AsyncJson.h index b85a938..bca3f24 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -26,7 +26,7 @@ AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/rest/endpoint"); handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) { - JsonObject& jsonObj = json.as(); + JsonObject jsonObj = json.as(); // ... }); server.addHandler(handler); @@ -36,7 +36,8 @@ #define ASYNC_JSON_H_ #include #include -#include + +#include "ChunkPrint.h" #if ARDUINOJSON_VERSION_MAJOR == 6 #ifndef DYNAMIC_JSON_DOCUMENT_SIZE @@ -50,33 +51,6 @@ constexpr const char* JSON_MIMETYPE = "application/json"; * Json Response * */ -class ChunkPrint : public Print { - private: - uint8_t* _destination; - size_t _to_skip; - size_t _to_write; - size_t _pos; - - public: - ChunkPrint(uint8_t* destination, size_t from, size_t len) - : _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} - virtual ~ChunkPrint() {} - size_t write(uint8_t c) { - if (_to_skip > 0) { - _to_skip--; - return 1; - } else if (_to_write > 0) { - _to_write--; - _destination[_pos++] = c; - return 1; - } - return 0; - } - size_t write(const uint8_t* buffer, size_t size) { - return this->Print::write(buffer, size); - } -}; - class AsyncJsonResponse : public AsyncAbstractResponse { protected: #if ARDUINOJSON_VERSION_MAJOR == 5 @@ -199,10 +173,10 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { public: #if ARDUINOJSON_VERSION_MAJOR == 6 - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} #else - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr) : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #endif diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h new file mode 100644 index 0000000..57a8824 --- /dev/null +++ b/src/AsyncMessagePack.h @@ -0,0 +1,145 @@ +#pragma once + +/* + server.on("/msg_pack", HTTP_ANY, [](AsyncWebServerRequest * request) { + AsyncMessagePackResponse * response = new AsyncMessagePackResponse(); + JsonObject& root = response->getRoot(); + root["key1"] = "key number one"; + JsonObject& nested = root.createNestedObject("nested"); + nested["key1"] = "key number one"; + response->setLength(); + request->send(response); + }); + + -------------------- + + AsyncCallbackMessagePackWebHandler* handler = new AsyncCallbackMessagePackWebHandler("/msg_pack/endpoint"); + handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) { + JsonObject jsonObj = json.as(); + // ... + }); + server.addHandler(handler); +*/ + +#include +#include + +#include "ChunkPrint.h" +#include "literals.h" + +class AsyncMessagePackResponse : public AsyncAbstractResponse { + protected: + JsonDocument _jsonBuffer; + JsonVariant _root; + bool _isValid; + + public: + AsyncMessagePackResponse(bool isArray = false) : _isValid{false} { + _code = 200; + _contentType = asyncsrv::T_application_msgpack; + if (isArray) + _root = _jsonBuffer.add(); + else + _root = _jsonBuffer.add(); + } + + JsonVariant& getRoot() { return _root; } + + bool _sourceValid() const { return _isValid; } + + size_t setLength() { + _contentLength = measureMsgPack(_root); + if (_contentLength) { + _isValid = true; + } + return _contentLength; + } + + size_t getSize() const { return _jsonBuffer.size(); } + + size_t _fillBuffer(uint8_t* data, size_t len) { + ChunkPrint dest(data, _sentLength, len); + serializeMsgPack(_root, dest); + return len; + } +}; + +class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { + public: + typedef std::function ArJsonRequestHandlerFunction; + + protected: + const String _uri; + WebRequestMethodComposite _method; + ArJsonRequestHandlerFunction _onRequest; + size_t _contentLength; + size_t _maxContentLength; + + public: + AsyncCallbackMessagePackWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr) + : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} + + void setMethod(WebRequestMethodComposite method) { _method = method; } + void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } + void onRequest(ArJsonRequestHandlerFunction fn) { _onRequest = fn; } + + virtual bool canHandle(AsyncWebServerRequest* request) override final { + if (!_onRequest) + return false; + + WebRequestMethodComposite request_method = request->method(); + if (!(_method & request_method)) + return false; + + if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) + return false; + + if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack)) + return false; + + request->addInterestingHeader("ANY"); + return true; + } + + virtual void handleRequest(AsyncWebServerRequest* request) override final { + if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); + + if (_onRequest) { + if (request->method() == HTTP_GET) { + JsonVariant json; + _onRequest(request, json); + return; + + } else if (request->_tempObject != NULL) { + JsonDocument jsonBuffer; + DeserializationError error = deserializeMsgPack(jsonBuffer, (uint8_t*)(request->_tempObject)); + + if (!error) { + JsonVariant json = jsonBuffer.as(); + _onRequest(request, json); + return; + } + } + request->send(_contentLength > _maxContentLength ? 413 : 400); + } else { + request->send(500); + } + } + + virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} + + virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final { + if (_onRequest) { + _contentLength = total; + if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { + request->_tempObject = malloc(total); + } + if (request->_tempObject != NULL) { + memcpy((uint8_t*)(request->_tempObject) + index, data, len); + } + } + } + + virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } +}; diff --git a/src/ChunkPrint.h b/src/ChunkPrint.h new file mode 100644 index 0000000..2f40741 --- /dev/null +++ b/src/ChunkPrint.h @@ -0,0 +1,32 @@ +#ifndef CHUNKPRINT_H +#define CHUNKPRINT_H + +#include + +class ChunkPrint : public Print { + private: + uint8_t* _destination; + size_t _to_skip; + size_t _to_write; + size_t _pos; + + public: + ChunkPrint(uint8_t* destination, size_t from, size_t len) + : _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} + virtual ~ChunkPrint() {} + size_t write(uint8_t c) { + if (_to_skip > 0) { + _to_skip--; + return 1; + } else if (_to_write > 0) { + _to_write--; + _destination[_pos++] = c; + return 1; + } + return 0; + } + size_t write(const uint8_t* buffer, size_t size) { + return this->Print::write(buffer, size); + } +}; +#endif diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 73a2c36..f729f7e 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.1.1" +#define ASYNCWEBSERVER_VERSION "3.1.2" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_REVISION 2 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX diff --git a/src/literals.h b/src/literals.h index 145d69b..c60a3eb 100644 --- a/src/literals.h +++ b/src/literals.h @@ -81,6 +81,7 @@ static constexpr const char* T__xml = ".xml"; static constexpr const char* T__zip = ".zip"; static constexpr const char* T_application_javascript = "application/javascript"; static constexpr const char* T_application_json = "application/json"; +static constexpr const char* T_application_msgpack = "application/msgpack"; static constexpr const char* T_application_pdf = "application/pdf"; static constexpr const char* T_application_x_gzip = "application/x-gzip"; static constexpr const char* T_application_zip = "application/zip"; @@ -249,6 +250,7 @@ static const char T__xml[] PROGMEM = ".xml"; static const char T__zip[] PROGMEM = ".zip"; static const char T_application_javascript[] PROGMEM = "application/javascript"; static const char T_application_json[] PROGMEM = "application/json"; +static const char T_application_msgpack[] PROGMEM = "application/msgpack"; static const char T_application_pdf[] PROGMEM = "application/pdf"; static const char T_application_x_gzip[] PROGMEM = "application/x-gzip"; static const char T_application_zip[] PROGMEM = "application/zip";