Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
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
8 changes: 1 addition & 7 deletions examples/ChunkRetryResponse/ChunkRetryResponse.ino
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@

#include <ESPAsyncWebServer.h>

#if __has_include("ArduinoJson.h")
#include <ArduinoJson.h>
#include <AsyncJson.h>
#include <AsyncMessagePack.h>
#endif

static const char *htmlContent PROGMEM = R"(
<!DOCTYPE html>
<html>
Expand Down Expand Up @@ -107,7 +101,7 @@ void setup() {

server.addMiddleware(&requestLogger);

#if __has_include("ArduinoJson.h")
#if ASYNC_JSON_SUPPORT == 1

//
// HOW TO RUN THIS EXAMPLE:
Expand Down
24 changes: 16 additions & 8 deletions examples/Json/Json.ino
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,9 @@

#include <ESPAsyncWebServer.h>

#if __has_include("ArduinoJson.h")
#include <ArduinoJson.h>
#include <AsyncJson.h>
#include <AsyncMessagePack.h>
#endif

static AsyncWebServer server(80);

#if __has_include("ArduinoJson.h")
#if ASYNC_JSON_SUPPORT == 1
static AsyncCallbackJsonWebHandler *handler = new AsyncCallbackJsonWebHandler("/json2");
#endif

Expand All @@ -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
//
Expand Down Expand Up @@ -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<JsonObject>();
root["hello"] = json.as<JsonObject>()["name"];
response->setLength();
request->send(response);
});
#endif

server.begin();
Expand Down
38 changes: 28 additions & 10 deletions examples/MessagePack/MessagePack.ino
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,10 @@

#include <ESPAsyncWebServer.h>

#if __has_include("ArduinoJson.h")
#include <ArduinoJson.h>
#include <AsyncJson.h>
#include <AsyncMessagePack.h>
#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() {
Expand All @@ -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
//
Expand All @@ -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<JsonObject>();
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<JsonObject>();
root["hello"] = json.as<JsonObject>()["name"];
Expand All @@ -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<JsonObject>();
root["hello"] = json.as<JsonObject>()["name"];
response->setLength();
request->send(response);
});
#endif

server.begin();
Expand Down
2 changes: 2 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
68 changes: 49 additions & 19 deletions src/AsyncJson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {}
Expand All @@ -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) {
Expand All @@ -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<JsonVariant>();
DynamicJsonDocument doc(this->maxJsonBufferSize);
#else
JsonDocument jsonBuffer;
DeserializationError error = deserializeJson(jsonBuffer, (const char *)request->_tempObject);
if (!error) {
JsonVariant json = jsonBuffer.as<JsonVariant>();
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<JsonVariant>();
_onRequest(request, json);
return;
}
#endif

// error parsing the body
request->send(400);
}
}

Expand Down
50 changes: 30 additions & 20 deletions src/AsyncJson.h
Original file line number Diff line number Diff line change
@@ -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 <ArduinoJson.h>
#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 <ESPAsyncWebServer.h>

#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
Expand All @@ -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();
Expand All @@ -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<void(AsyncWebServerRequest *request, JsonVariant &json)> 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:
Expand Down Expand Up @@ -114,5 +126,3 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler {
};

#endif // ASYNC_JSON_SUPPORT == 1

#endif // ASYNC_JSON_H_
Loading