summaryrefslogtreecommitdiff
path: root/libraries/ESP_Async_WebServer/src/AsyncMessagePack.h
blob: 7488b5cbaaaa64a11624357386f8af37697b3268 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// 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<JsonObject>();
    // ...
  });
  server.addHandler(handler);
*/

#if __has_include("ArduinoJson.h")
#include <ArduinoJson.h>
#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 <ESPAsyncWebServer.h>

#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<void(AsyncWebServerRequest *request, JsonVariant &json)> 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;
  }
};

#endif  // ASYNC_MSG_PACK_SUPPORT == 1