Fork of the excellent esp8266-react - https://github.com/rjwats/esp8266-react
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
6.2 KiB

  1. #ifndef HttpEndpoint_h
  2. #define HttpEndpoint_h
  3. #include <functional>
  4. #include <AsyncJson.h>
  5. #include <ESPAsyncWebServer.h>
  6. #include <SecurityManager.h>
  7. #include <StatefulService.h>
  8. #define HTTP_ENDPOINT_ORIGIN_ID "http"
  9. template <class T>
  10. class HttpGetEndpoint {
  11. public:
  12. HttpGetEndpoint(JsonStateReader<T> stateReader,
  13. StatefulService<T>* statefulService,
  14. AsyncWebServer* server,
  15. const String& servicePath,
  16. SecurityManager* securityManager,
  17. AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
  18. size_t bufferSize = DEFAULT_BUFFER_SIZE) :
  19. _stateReader(stateReader), _statefulService(statefulService), _bufferSize(bufferSize) {
  20. server->on(servicePath.c_str(),
  21. HTTP_GET,
  22. securityManager->wrapRequest(std::bind(&HttpGetEndpoint::fetchSettings, this, std::placeholders::_1),
  23. authenticationPredicate));
  24. }
  25. HttpGetEndpoint(JsonStateReader<T> stateReader,
  26. StatefulService<T>* statefulService,
  27. AsyncWebServer* server,
  28. const String& servicePath,
  29. size_t bufferSize = DEFAULT_BUFFER_SIZE) :
  30. _stateReader(stateReader), _statefulService(statefulService), _bufferSize(bufferSize) {
  31. server->on(servicePath.c_str(), HTTP_GET, std::bind(&HttpGetEndpoint::fetchSettings, this, std::placeholders::_1));
  32. }
  33. protected:
  34. JsonStateReader<T> _stateReader;
  35. StatefulService<T>* _statefulService;
  36. size_t _bufferSize;
  37. void fetchSettings(AsyncWebServerRequest* request) {
  38. AsyncJsonResponse* response = new AsyncJsonResponse(false, _bufferSize);
  39. JsonObject jsonObject = response->getRoot().to<JsonObject>();
  40. _statefulService->read(jsonObject, _stateReader);
  41. response->setLength();
  42. request->send(response);
  43. }
  44. };
  45. template <class T>
  46. class HttpPostEndpoint {
  47. public:
  48. HttpPostEndpoint(JsonStateReader<T> stateReader,
  49. JsonStateUpdater<T> stateUpdater,
  50. StatefulService<T>* statefulService,
  51. AsyncWebServer* server,
  52. const String& servicePath,
  53. SecurityManager* securityManager,
  54. AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
  55. size_t bufferSize = DEFAULT_BUFFER_SIZE) :
  56. _stateReader(stateReader),
  57. _stateUpdater(stateUpdater),
  58. _statefulService(statefulService),
  59. _updateHandler(
  60. servicePath,
  61. securityManager->wrapCallback(
  62. std::bind(&HttpPostEndpoint::updateSettings, this, std::placeholders::_1, std::placeholders::_2),
  63. authenticationPredicate),
  64. bufferSize),
  65. _bufferSize(bufferSize) {
  66. _updateHandler.setMethod(HTTP_POST);
  67. server->addHandler(&_updateHandler);
  68. }
  69. HttpPostEndpoint(JsonStateReader<T> stateReader,
  70. JsonStateUpdater<T> stateUpdater,
  71. StatefulService<T>* statefulService,
  72. AsyncWebServer* server,
  73. const String& servicePath,
  74. size_t bufferSize = DEFAULT_BUFFER_SIZE) :
  75. _stateReader(stateReader),
  76. _stateUpdater(stateUpdater),
  77. _statefulService(statefulService),
  78. _updateHandler(servicePath,
  79. std::bind(&HttpPostEndpoint::updateSettings, this, std::placeholders::_1, std::placeholders::_2),
  80. bufferSize),
  81. _bufferSize(bufferSize) {
  82. _updateHandler.setMethod(HTTP_POST);
  83. server->addHandler(&_updateHandler);
  84. }
  85. protected:
  86. JsonStateReader<T> _stateReader;
  87. JsonStateUpdater<T> _stateUpdater;
  88. StatefulService<T>* _statefulService;
  89. AsyncCallbackJsonWebHandler _updateHandler;
  90. size_t _bufferSize;
  91. void updateSettings(AsyncWebServerRequest* request, JsonVariant& json) {
  92. if (!json.is<JsonObject>()) {
  93. request->send(400);
  94. return;
  95. }
  96. JsonObject jsonObject = json.as<JsonObject>();
  97. StateUpdateResult outcome = _statefulService->updateWithoutPropagation(jsonObject, _stateUpdater);
  98. if (outcome == StateUpdateResult::ERROR) {
  99. request->send(400);
  100. return;
  101. }
  102. if (outcome == StateUpdateResult::CHANGED) {
  103. request->onDisconnect([this]() { _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); });
  104. }
  105. AsyncJsonResponse* response = new AsyncJsonResponse(false, _bufferSize);
  106. jsonObject = response->getRoot().to<JsonObject>();
  107. _statefulService->read(jsonObject, _stateReader);
  108. response->setLength();
  109. request->send(response);
  110. }
  111. };
  112. template <class T>
  113. class HttpEndpoint : public HttpGetEndpoint<T>, public HttpPostEndpoint<T> {
  114. public:
  115. HttpEndpoint(JsonStateReader<T> stateReader,
  116. JsonStateUpdater<T> stateUpdater,
  117. StatefulService<T>* statefulService,
  118. AsyncWebServer* server,
  119. const String& servicePath,
  120. SecurityManager* securityManager,
  121. AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
  122. size_t bufferSize = DEFAULT_BUFFER_SIZE) :
  123. HttpGetEndpoint<T>(stateReader,
  124. statefulService,
  125. server,
  126. servicePath,
  127. securityManager,
  128. authenticationPredicate,
  129. bufferSize),
  130. HttpPostEndpoint<T>(stateReader,
  131. stateUpdater,
  132. statefulService,
  133. server,
  134. servicePath,
  135. securityManager,
  136. authenticationPredicate,
  137. bufferSize) {
  138. }
  139. HttpEndpoint(JsonStateReader<T> stateReader,
  140. JsonStateUpdater<T> stateUpdater,
  141. StatefulService<T>* statefulService,
  142. AsyncWebServer* server,
  143. const String& servicePath,
  144. size_t bufferSize = DEFAULT_BUFFER_SIZE) :
  145. HttpGetEndpoint<T>(stateReader, statefulService, server, servicePath, bufferSize),
  146. HttpPostEndpoint<T>(stateReader, stateUpdater, statefulService, server, servicePath, bufferSize) {
  147. }
  148. };
  149. #endif // end HttpEndpoint