From 545399536d82c404ef985c4d96d6b9a9c2fbf134 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 2 Oct 2025 15:18:14 +0200 Subject: [PATCH] Backward-compatible refactoring of the Json and MessagePack integration . This PR: - refactors the macros to activate or not Json and MessagePack support - regroups the code for both since it is similar in many ways - add deprecations where applicable - add the ability to easily add a JsonVariant callback with `server.on("/testJsonPost", HTTP_POST, [](AsyncWebServerRequest *request, JsonVariant &json)` - Improve examples This PR is tested. --- .../ChunkRetryResponse/ChunkRetryResponse.ino | 8 +- examples/Json/Json.ino | 24 ++-- examples/MessagePack/MessagePack.ino | 38 ++++-- platformio.ini | 2 + src/AsyncJson.cpp | 68 +++++++--- src/AsyncJson.h | 50 ++++--- src/AsyncMessagePack.cpp | 118 ----------------- src/AsyncMessagePack.h | 123 +----------------- src/ESPAsyncWebServer.h | 39 ++++++ src/WebServer.cpp | 9 ++ 10 files changed, 176 insertions(+), 303 deletions(-) delete mode 100644 src/AsyncMessagePack.cpp diff --git a/examples/ChunkRetryResponse/ChunkRetryResponse.ino b/examples/ChunkRetryResponse/ChunkRetryResponse.ino index 30a2649f..4dde65ec 100644 --- a/examples/ChunkRetryResponse/ChunkRetryResponse.ino +++ b/examples/ChunkRetryResponse/ChunkRetryResponse.ino @@ -19,12 +19,6 @@ #include -#if __has_include("ArduinoJson.h") -#include -#include -#include -#endif - static const char *htmlContent PROGMEM = R"( @@ -107,7 +101,7 @@ void setup() { server.addMiddleware(&requestLogger); -#if __has_include("ArduinoJson.h") +#if ASYNC_JSON_SUPPORT == 1 // // HOW TO RUN THIS EXAMPLE: diff --git a/examples/Json/Json.ino b/examples/Json/Json.ino index a29fec1b..69ab251e 100644 --- a/examples/Json/Json.ino +++ b/examples/Json/Json.ino @@ -19,15 +19,9 @@ #include -#if __has_include("ArduinoJson.h") -#include -#include -#include -#endif - static AsyncWebServer server(80); -#if __has_include("ArduinoJson.h") +#if ASYNC_JSON_SUPPORT == 1 static AsyncCallbackJsonWebHandler *handler = new AsyncCallbackJsonWebHandler("/json2"); #endif @@ -39,7 +33,7 @@ void setup() { WiFi.softAP("esp-captive"); #endif -#if __has_include("ArduinoJson.h") +#if ASYNC_JSON_SUPPORT == 1 // // sends JSON using AsyncJsonResponse // @@ -92,6 +86,20 @@ void setup() { }); server.addHandler(handler); + + // New Json API since 3.8.2, which works for both Json and MessagePack bodies + // curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json3 + + server.on("/json3", HTTP_POST, [](AsyncWebServerRequest *request, JsonVariant &json) { + Serial.printf("Body request : "); + serializeJson(json, Serial); + Serial.println(); + AsyncJsonResponse *response = new AsyncJsonResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = json.as()["name"]; + response->setLength(); + request->send(response); + }); #endif server.begin(); diff --git a/examples/MessagePack/MessagePack.ino b/examples/MessagePack/MessagePack.ino index e038d03c..18ff6e97 100644 --- a/examples/MessagePack/MessagePack.ino +++ b/examples/MessagePack/MessagePack.ino @@ -19,16 +19,10 @@ #include -#if __has_include("ArduinoJson.h") -#include -#include -#include -#endif - static AsyncWebServer server(80); -#if __has_include("ArduinoJson.h") -static AsyncCallbackMessagePackWebHandler *handler = new AsyncCallbackMessagePackWebHandler("/msgpack2"); +#if ASYNC_JSON_SUPPORT == 1 +static AsyncCallbackJsonWebHandler *handler = new AsyncCallbackJsonWebHandler("/msgpack2"); #endif void setup() { @@ -39,7 +33,7 @@ void setup() { WiFi.softAP("esp-captive"); #endif -#if __has_include("ArduinoJson.h") +#if ASYNC_JSON_SUPPORT == 1 // // sends MessagePack using AsyncMessagePackResponse // @@ -57,18 +51,26 @@ void setup() { // // curl -v http://192.168.4.1/msgpack2 // + // Save file: curl -v http://192.168.4.1/msgpack2 -o msgpack.bin + // server.on("/msgpack2", HTTP_GET, [](AsyncWebServerRequest *request) { AsyncResponseStream *response = request->beginResponseStream("application/msgpack"); JsonDocument doc; JsonObject root = doc.to(); - root["foo"] = "bar"; + root["name"] = "Bob"; serializeMsgPack(root, *response); request->send(response); }); + // POST file: + // + // curl -v -X POST -H 'Content-Type: application/msgpack' --data-binary @msgpack.bin http://192.168.4.1/msgpack2 + // handler->setMethod(HTTP_POST | HTTP_PUT); handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) { + Serial.printf("Body request /msgpack2 : "); // should print: Body request /msgpack2 : {"name":"Bob"} serializeJson(json, Serial); + Serial.println(); AsyncMessagePackResponse *response = new AsyncMessagePackResponse(); JsonObject root = response->getRoot().to(); root["hello"] = json.as()["name"]; @@ -77,6 +79,22 @@ void setup() { }); server.addHandler(handler); + + // New Json API since 3.8.2, which works for both Json and MessagePack bodies + // + // curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/msgpack3 + // curl -v -X POST -H 'Content-Type: application/msgpack' --data-binary @msgpack.bin http://192.168.4.1/msgpack3 + // + server.on("/msgpack3", HTTP_POST, [](AsyncWebServerRequest *request, JsonVariant &json) { + Serial.printf("Body request /msgpack3 : "); // should print: Body request /msgpack3 : {"name":"Bob"} + serializeJson(json, Serial); + Serial.println(); + AsyncJsonResponse *response = new AsyncJsonResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = json.as()["name"]; + response->setLength(); + request->send(response); + }); #endif server.begin(); diff --git a/platformio.ini b/platformio.ini index 7e2bc381..e961548d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -66,6 +66,8 @@ lib_compat_mode = strict lib_ldf_mode = chain lib_deps = bblanchon/ArduinoJson @ 7.4.2 + ; bblanchon/ArduinoJson @ 6.21.5 + ; bblanchon/ArduinoJson @ 5.13.4 ESP32Async/AsyncTCP @ 3.4.9 board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs diff --git a/src/AsyncJson.cpp b/src/AsyncJson.cpp index 03e0015b..c6643f76 100644 --- a/src/AsyncJson.cpp +++ b/src/AsyncJson.cpp @@ -6,6 +6,8 @@ #if ASYNC_JSON_SUPPORT == 1 +// Json content type response classes + #if ARDUINOJSON_VERSION_MAJOR == 5 AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { _code = 200; @@ -88,6 +90,27 @@ size_t PrettyAsyncJsonResponse::_fillBuffer(uint8_t *data, size_t len) { return len; } +// MessagePack content type response +#if ASYNC_MSG_PACK_SUPPORT == 1 + +size_t AsyncMessagePackResponse::setLength() { + _contentLength = measureMsgPack(_root); + if (_contentLength) { + _isValid = true; + } + return _contentLength; +} + +size_t AsyncMessagePackResponse::_fillBuffer(uint8_t *data, size_t len) { + ChunkPrint dest(data, _sentLength, len); + serializeMsgPack(_root, dest); + return len; +} + +#endif + +// Body handler supporting both content types: JSON and MessagePack + #if ARDUINOJSON_VERSION_MAJOR == 6 AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(const String &uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize) : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} @@ -105,11 +128,12 @@ bool AsyncCallbackJsonWebHandler::canHandle(AsyncWebServerRequest *request) cons return false; } - if (request->method() != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_json)) { - return false; - } - - return true; +#if ASYNC_MSG_PACK_SUPPORT == 1 + return request->method() == HTTP_GET || request->contentType().equalsIgnoreCase(asyncsrv::T_application_json) + || request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack); +#else + return request->method() == HTTP_GET || request->contentType().equalsIgnoreCase(asyncsrv::T_application_json); +#endif } void AsyncCallbackJsonWebHandler::handleRequest(AsyncWebServerRequest *request) { @@ -136,26 +160,32 @@ void AsyncCallbackJsonWebHandler::handleRequest(AsyncWebServerRequest *request) } #if ARDUINOJSON_VERSION_MAJOR == 5 - DynamicJsonBuffer jsonBuffer; - JsonVariant json = jsonBuffer.parse((const char *)request->_tempObject); - if (json.success()) { + DynamicJsonBuffer doc; #elif ARDUINOJSON_VERSION_MAJOR == 6 - DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); - DeserializationError error = deserializeJson(jsonBuffer, (const char *)request->_tempObject); - if (!error) { - JsonVariant json = jsonBuffer.as(); + DynamicJsonDocument doc(this->maxJsonBufferSize); #else - JsonDocument jsonBuffer; - DeserializationError error = deserializeJson(jsonBuffer, (const char *)request->_tempObject); - if (!error) { - JsonVariant json = jsonBuffer.as(); + JsonDocument doc; #endif +#if ARDUINOJSON_VERSION_MAJOR == 5 + JsonVariant json = doc.parse((const char *)request->_tempObject); + if (json.success()) { _onRequest(request, json); - } else { - // error parsing the body - request->send(400); + return; + } +#else + DeserializationError error = request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack) + ? deserializeMsgPack(doc, (uint8_t *)(request->_tempObject)) + : deserializeJson(doc, (const char *)request->_tempObject); + if (!error) { + JsonVariant json = doc.as(); + _onRequest(request, json); + return; } +#endif + + // error parsing the body + request->send(400); } } diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 2194069d..42ec7b5e 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -1,29 +1,21 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov -#ifndef ASYNC_JSON_H_ -#define ASYNC_JSON_H_ +#pragma once -#if __has_include("ArduinoJson.h") -#include -#if ARDUINOJSON_VERSION_MAJOR >= 5 -#define ASYNC_JSON_SUPPORT 1 -#else -#define ASYNC_JSON_SUPPORT 0 -#endif // ARDUINOJSON_VERSION_MAJOR >= 5 -#endif // __has_include("ArduinoJson.h") - -#if ASYNC_JSON_SUPPORT == 1 #include - #include "ChunkPrint.h" +#if ASYNC_JSON_SUPPORT == 1 + #if ARDUINOJSON_VERSION_MAJOR == 6 #ifndef DYNAMIC_JSON_DOCUMENT_SIZE #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 #endif #endif +// Json content type response classes + class AsyncJsonResponse : public AsyncAbstractResponse { protected: #if ARDUINOJSON_VERSION_MAJOR == 5 @@ -49,11 +41,11 @@ class AsyncJsonResponse : public AsyncAbstractResponse { bool _sourceValid() const { return _isValid; } - size_t setLength(); + virtual size_t setLength(); size_t getSize() const { return _jsonBuffer.size(); } - size_t _fillBuffer(uint8_t *data, size_t len); + virtual size_t _fillBuffer(uint8_t *data, size_t len); #if ARDUINOJSON_VERSION_MAJOR >= 6 bool overflowed() const { return _jsonBuffer.overflowed(); @@ -68,11 +60,31 @@ class PrettyAsyncJsonResponse : public AsyncJsonResponse { #else PrettyAsyncJsonResponse(bool isArray = false); #endif - size_t setLength(); - size_t _fillBuffer(uint8_t *data, size_t len); + size_t setLength() override; + size_t _fillBuffer(uint8_t *data, size_t len) override; }; -typedef std::function ArJsonRequestHandlerFunction; +// MessagePack content type response +#if ASYNC_MSG_PACK_SUPPORT == 1 + +class AsyncMessagePackResponse : public AsyncJsonResponse { +public: +#if ARDUINOJSON_VERSION_MAJOR == 6 + AsyncMessagePackResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse(isArray, maxJsonBufferSize) { + _contentType = asyncsrv::T_application_msgpack; + } +#else + AsyncMessagePackResponse(bool isArray = false) : AsyncJsonResponse(isArray) { + _contentType = asyncsrv::T_application_msgpack; + } +#endif + size_t setLength() override; + size_t _fillBuffer(uint8_t *data, size_t len) override; +}; + +#endif + +// Body handler supporting both content types: JSON and MessagePack class AsyncCallbackJsonWebHandler : public AsyncWebHandler { protected: @@ -114,5 +126,3 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { }; #endif // ASYNC_JSON_SUPPORT == 1 - -#endif // ASYNC_JSON_H_ diff --git a/src/AsyncMessagePack.cpp b/src/AsyncMessagePack.cpp deleted file mode 100644 index f833d8e9..00000000 --- a/src/AsyncMessagePack.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov - -#include "AsyncMessagePack.h" -#include "AsyncWebServerLogging.h" - -#if ASYNC_MSG_PACK_SUPPORT == 1 - -#if ARDUINOJSON_VERSION_MAJOR == 6 -AsyncMessagePackResponse::AsyncMessagePackResponse(bool isArray, size_t maxJsonBufferSize) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { - _code = 200; - _contentType = asyncsrv::T_application_msgpack; - if (isArray) { - _root = _jsonBuffer.createNestedArray(); - } else { - _root = _jsonBuffer.createNestedObject(); - } -} -#else -AsyncMessagePackResponse::AsyncMessagePackResponse(bool isArray) : _isValid{false} { - _code = 200; - _contentType = asyncsrv::T_application_msgpack; - if (isArray) { - _root = _jsonBuffer.add(); - } else { - _root = _jsonBuffer.add(); - } -} -#endif - -size_t AsyncMessagePackResponse::setLength() { - _contentLength = measureMsgPack(_root); - if (_contentLength) { - _isValid = true; - } - return _contentLength; -} - -size_t AsyncMessagePackResponse::_fillBuffer(uint8_t *data, size_t len) { - ChunkPrint dest(data, _sentLength, len); - serializeMsgPack(_root, dest); - return len; -} - -#if ARDUINOJSON_VERSION_MAJOR == 6 -AsyncCallbackMessagePackWebHandler::AsyncCallbackMessagePackWebHandler( - const String &uri, ArMessagePackRequestHandlerFunction onRequest, size_t maxJsonBufferSize -) - : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} -#else -AsyncCallbackMessagePackWebHandler::AsyncCallbackMessagePackWebHandler(const String &uri, ArMessagePackRequestHandlerFunction onRequest) - : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} -#endif - -bool AsyncCallbackMessagePackWebHandler::canHandle(AsyncWebServerRequest *request) const { - if (!_onRequest || !request->isHTTP() || !(_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; - } - - return true; -} - -void AsyncCallbackMessagePackWebHandler::handleRequest(AsyncWebServerRequest *request) { - if (_onRequest) { - if (request->method() == HTTP_GET) { - JsonVariant json; - _onRequest(request, json); - return; - } else if (request->_tempObject != NULL) { - -#if ARDUINOJSON_VERSION_MAJOR == 6 - DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); - DeserializationError error = deserializeMsgPack(jsonBuffer, (uint8_t *)(request->_tempObject)); - if (!error) { - JsonVariant json = jsonBuffer.as(); -#else - JsonDocument jsonBuffer; - DeserializationError error = deserializeMsgPack(jsonBuffer, (uint8_t *)(request->_tempObject)); - if (!error) { - JsonVariant json = jsonBuffer.as(); -#endif - - _onRequest(request, json); - return; - } - } - request->send(_contentLength > _maxContentLength ? 413 : 400); - } else { - request->send(500); - } -} - -void AsyncCallbackMessagePackWebHandler::handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) { - if (_onRequest) { - _contentLength = total; - if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { - request->_tempObject = malloc(total); - if (request->_tempObject == NULL) { - async_ws_log_e("Failed to allocate"); - request->abort(); - return; - } - } - if (request->_tempObject != NULL) { - memcpy((uint8_t *)(request->_tempObject) + index, data, len); - } - } -} - -#endif // ASYNC_MSG_PACK_SUPPORT diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index 7488b5cb..a0ea58c9 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -1,126 +1,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov - #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); -*/ - -#if __has_include("ArduinoJson.h") -#include -#if ARDUINOJSON_VERSION_MAJOR >= 6 -#define ASYNC_MSG_PACK_SUPPORT 1 -#else -#define ASYNC_MSG_PACK_SUPPORT 0 -#endif // ARDUINOJSON_VERSION_MAJOR >= 6 -#endif // __has_include("ArduinoJson.h") - -#if ASYNC_MSG_PACK_SUPPORT == 1 -#include - -#include "ChunkPrint.h" - -#if ARDUINOJSON_VERSION_MAJOR == 6 -#ifndef DYNAMIC_JSON_DOCUMENT_SIZE -#define DYNAMIC_JSON_DOCUMENT_SIZE 1024 -#endif -#endif - -class AsyncMessagePackResponse : public AsyncAbstractResponse { -protected: -#if ARDUINOJSON_VERSION_MAJOR == 6 - DynamicJsonDocument _jsonBuffer; -#else - JsonDocument _jsonBuffer; -#endif - - JsonVariant _root; - bool _isValid; - -public: -#if ARDUINOJSON_VERSION_MAJOR == 6 - AsyncMessagePackResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE); -#else - AsyncMessagePackResponse(bool isArray = false); -#endif - JsonVariant &getRoot() { - return _root; - } - bool _sourceValid() const { - return _isValid; - } - size_t setLength(); - size_t getSize() const { - return _jsonBuffer.size(); - } - size_t _fillBuffer(uint8_t *data, size_t len); -#if ARDUINOJSON_VERSION_MAJOR >= 6 - bool overflowed() const { - return _jsonBuffer.overflowed(); - } -#endif -}; - -typedef std::function ArMessagePackRequestHandlerFunction; - -class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { -protected: - String _uri; - WebRequestMethodComposite _method; - ArMessagePackRequestHandlerFunction _onRequest; - size_t _contentLength; -#if ARDUINOJSON_VERSION_MAJOR == 6 - size_t maxJsonBufferSize; -#endif - size_t _maxContentLength; - -public: -#if ARDUINOJSON_VERSION_MAJOR == 6 - AsyncCallbackMessagePackWebHandler( - const String &uri, ArMessagePackRequestHandlerFunction onRequest = nullptr, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE - ); -#else - AsyncCallbackMessagePackWebHandler(const String &uri, ArMessagePackRequestHandlerFunction onRequest = nullptr); -#endif - - void setMethod(WebRequestMethodComposite method) { - _method = method; - } - void setMaxContentLength(int maxContentLength) { - _maxContentLength = maxContentLength; - } - void onRequest(ArMessagePackRequestHandlerFunction fn) { - _onRequest = fn; - } - - bool canHandle(AsyncWebServerRequest *request) const override final; - void handleRequest(AsyncWebServerRequest *request) override final; - 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 {} - void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final; - bool isRequestHandlerTrivial() const override final { - return !_onRequest; - } -}; +#warning "AsyncMessagePack.h is deprecated, just include ESPAsyncWebServer.h from now on" -#endif // ASYNC_MSG_PACK_SUPPORT == 1 +#include "AsyncJson.h" diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index bb046743..d0b20c19 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -15,6 +15,23 @@ #include #include +#if __has_include("ArduinoJson.h") +#include + +#if ARDUINOJSON_VERSION_MAJOR >= 5 +#define ASYNC_JSON_SUPPORT 1 +#else +#define ASYNC_JSON_SUPPORT 0 +#endif // ARDUINOJSON_VERSION_MAJOR >= 5 + +#if ARDUINOJSON_VERSION_MAJOR >= 6 +#define ASYNC_MSG_PACK_SUPPORT 1 +#else +#define ASYNC_MSG_PACK_SUPPORT 0 +#endif // ARDUINOJSON_VERSION_MAJOR >= 6 + +#endif // __has_include("ArduinoJson.h") + #if defined(ESP32) || defined(LIBRETINY) #include #elif defined(ESP8266) @@ -1109,6 +1126,20 @@ typedef std::function ArBodyHandlerFunction; +#if ASYNC_JSON_SUPPORT == 1 + +class AsyncCallbackJsonWebHandler; +typedef std::function ArJsonRequestHandlerFunction; + +#if ASYNC_MSG_PACK_SUPPORT == 1 +#ifndef ESP8266 +[[deprecated("Replaced by AsyncCallbackJsonWebHandler")]] +#endif +typedef AsyncCallbackJsonWebHandler AsyncCallbackMessagePackWebHandler; +#endif // ASYNC_MSG_PACK_SUPPORT + +#endif + class AsyncWebServer : public AsyncMiddlewareChain { protected: AsyncServer _server; @@ -1189,6 +1220,10 @@ class AsyncWebServer : public AsyncMiddlewareChain { ArBodyHandlerFunction onBody = nullptr ); +#if ASYNC_JSON_SUPPORT == 1 + AsyncCallbackJsonWebHandler &on(const char *uri, WebRequestMethodComposite method, ArJsonRequestHandlerFunction onBody); +#endif + AsyncStaticWebHandler &serveStatic(const char *uri, fs::FS &fs, const char *path, const char *cache_control = NULL); void onNotFound(ArRequestHandlerFunction fn); // called when handler is not assigned @@ -1238,4 +1273,8 @@ class DefaultHeaders { #include "WebHandlerImpl.h" #include "WebResponseImpl.h" +#if ASYNC_JSON_SUPPORT == 1 +#include +#endif + #endif /* _AsyncWebServer_H_ */ diff --git a/src/WebServer.cpp b/src/WebServer.cpp index c3c3ee73..657acbfa 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -163,6 +163,15 @@ AsyncCallbackWebHandler &AsyncWebServer::on( return *handler; } +#if ASYNC_JSON_SUPPORT == 1 +AsyncCallbackJsonWebHandler &AsyncWebServer::on(const char *uri, WebRequestMethodComposite method, ArJsonRequestHandlerFunction onBody) { + AsyncCallbackJsonWebHandler *handler = new AsyncCallbackJsonWebHandler(uri, onBody); + handler->setMethod(method); + addHandler(handler); + return *handler; +} +#endif + AsyncStaticWebHandler &AsyncWebServer::serveStatic(const char *uri, fs::FS &fs, const char *path, const char *cache_control) { AsyncStaticWebHandler *handler = new AsyncStaticWebHandler(uri, fs, path, cache_control); addHandler(handler);