client.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #ifndef KBF_HTTP_CLIENT_H
  2. #define KBF_HTTP_CLIENT_H
  3. #include <string>
  4. #include <memory>
  5. #include <esp_err.h>
  6. #include <esp_http_client.h>
  7. #include <nlohmann_json/json.hpp>
  8. #include "kbf/http/common.h"
  9. namespace kbf::http {
  10. /**
  11. * @brief HTTP Client.
  12. *
  13. * @note May only perform 1 request at a time, but can be (and should be) reused afterwards.
  14. */
  15. class Client {
  16. public:
  17. /** @brief Tag used for logging. */
  18. static constexpr const char *TAG = "kbf::http::Client";
  19. /**
  20. * @brief Constructor.
  21. *
  22. * @warning Async mode is only supported by IDF for HTTPS.
  23. *
  24. * @param timeoutMs request timeout in milliseconds; 0 means no timeout; default is 0
  25. * @param async perform request asynchronously; default is false
  26. */
  27. explicit Client(int timeoutMs = 0, bool async = false);
  28. /**
  29. * @brief Destructor.
  30. *
  31. * Calls esp_http_client_cleanup().
  32. */
  33. ~Client();
  34. /**
  35. * @brief Performs an HTTP GET.
  36. *
  37. * Calls onSuccess() when a response is received (even if it's a HTTP 4XX), or onError() on failure
  38. * (e.g. socket error)
  39. *
  40. * @param url url to fetch
  41. * @param headers optional map<string, string> of headers
  42. * @return HTTP response
  43. */
  44. std::shared_ptr<Response>
  45. get(const std::string &url,
  46. const std::optional<const std::map<std::string, std::string>> &headers = std::nullopt);
  47. /**
  48. * @brief Performs an HTTP POST.
  49. *
  50. * @param url url to post to
  51. * @param data JSON data
  52. * @param headers optional map<string, string> of headers
  53. * @return HTTP response
  54. */
  55. std::shared_ptr<Response>
  56. post(const std::string &url, const nlohmann::json &data,
  57. const std::optional<const std::map<std::string, std::string>> &headers = std::nullopt);
  58. /**
  59. * @brief Called after the response is received.
  60. *
  61. * @note "Success" here means that the request went through and a response was received.
  62. * This method will be called even if the server returned an error status (HTTP 4XX)
  63. *
  64. * @param client reference to the Client that issued the request
  65. * @param response struct containing the HTTP response data
  66. */
  67. void (*onSuccess)(Client &client, const Response &response) = nullptr;
  68. /**
  69. * @brief Returns whether a request is currently in progress.
  70. *
  71. * @return true if a request is currently in progress; false otherwise
  72. */
  73. [[nodiscard]] bool isRunning() const { return running; }
  74. /**
  75. * @brief Closes the connection if it was persistent (i.e. keep-alive or HTTP/1.1).
  76. */
  77. void disconnect();
  78. /**
  79. * @brief Adds a certificate to the global CA store.
  80. *
  81. * @param start
  82. * @param end
  83. */
  84. static void addCert(const unsigned char *start, const unsigned char *const end);
  85. /**
  86. * @brief Frees the global CA store.
  87. *
  88. * @warning Calling this will result in heap corruption when disconnecting if there are any open connections.
  89. * Make sure to disconnect() all clients before calling this.
  90. */
  91. static void clearCerts();
  92. /** @brief Request timeout in milliseconds. */
  93. const int timeoutMs;
  94. /** @brief Async mode */
  95. const bool async;
  96. private:
  97. void init();
  98. std::shared_ptr<kbf::http::Response>
  99. performRequest(kbf::http::Method method, const std::string &url, const nlohmann::json *postData,
  100. const std::optional<const std::map<std::string, std::string>> &headers = std::nullopt);
  101. static void updateResponse(Client &client);
  102. /**
  103. * @brief Processes events from esp_http_client.
  104. *
  105. * @return
  106. */
  107. static esp_err_t handleHttpEvent(esp_http_client_event_t *);
  108. esp_http_client_handle_t handle{};
  109. std::string buffer;
  110. std::shared_ptr<Response> response;
  111. bool running = false;
  112. bool retry = false;
  113. };
  114. }
  115. #endif //KBF_HTTP_CLIENT_H