Mirror of espurna firmware for wireless switches and more
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.

104 lines
2.2 KiB

  1. /*
  2. Part of WEBSERVER MODULE
  3. Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #pragma once
  6. #include "espurna.h"
  7. #include <ESPAsyncWebServer.h>
  8. #include <functional>
  9. #include <list>
  10. #include <vector>
  11. namespace espurna {
  12. namespace web {
  13. namespace print {
  14. struct Config {
  15. struct Backlog {
  16. size_t count;
  17. size_t size;
  18. duration::Seconds timeout;
  19. };
  20. const char* const mimeType;
  21. Backlog backlog;
  22. };
  23. class RequestPrint : public Print {
  24. public:
  25. enum class State {
  26. None,
  27. Sending,
  28. Done,
  29. Error
  30. };
  31. using BufferType = std::vector<uint8_t>;
  32. using TimeSource = espurna::time::CoreClock;
  33. // To be able to safely output data right from the request callback,
  34. // we schedule a 'printer' task that will print into the request response buffer via AsyncChunkedResponse
  35. // Note: implementation must be included in the header
  36. template <typename CallbackType>
  37. static void scheduleFromRequest(Config config, AsyncWebServerRequest*, CallbackType);
  38. template <typename CallbackType>
  39. static void scheduleFromRequest(AsyncWebServerRequest*, CallbackType);
  40. void flush() final override;
  41. size_t write(uint8_t) final override;
  42. size_t write(const uint8_t *buffer, size_t size) final override;
  43. State state() const {
  44. return _state;
  45. }
  46. void state(State state) {
  47. _state = state;
  48. }
  49. AsyncWebServerRequest* request() const {
  50. return _request;
  51. }
  52. private:
  53. Config _config;
  54. std::list<BufferType> _buffers;
  55. AsyncWebServerRequest* const _request;
  56. State _state;
  57. RequestPrint(Config config, AsyncWebServerRequest* request) :
  58. _config(config),
  59. _request(request),
  60. _state(State::None)
  61. {}
  62. bool _addBuffer();
  63. bool _exhaustBuffers();
  64. void _prepareRequest();
  65. size_t _handleRequest(uint8_t* data, size_t maxLen);
  66. void _onDisconnect();
  67. template <typename CallbackType>
  68. void _callback(CallbackType&&);
  69. };
  70. template <typename T>
  71. void scheduleFromRequest(AsyncWebServerRequest* request, T&& callback) {
  72. RequestPrint::scheduleFromRequest(request, std::forward<T>(callback));
  73. }
  74. } // namespace print
  75. } // namespace web
  76. } // namespace espurna