#pragma once #include #include #include #include #include #include #include #include namespace http { struct HttpResponse { int status; std::string body; }; struct HttpRequestData_; struct HttpOptions; typedef std::function, CURLcode)> ResponseCallback; class HttpClient { public: HttpClient(uv_loop_t *loop); HttpClient(HttpClient&&) = delete; HttpClient(HttpClient&) = delete; ~HttpClient(); bool send_request(std::string method, std::string url, HttpOptions opts, ResponseCallback cb); private: void check_curl_messages(); static int curl_socket_cb(CURL *curl, curl_socket_t curlSocket, int action, HttpClient *self, void *socketPtr); static int curl_timer_cb(CURLM *curl, long timeout, HttpClient *self); static size_t curl_data_cb(char *ptr, size_t size, size_t nmemb, CURL *userdata); static void uv_socket_cb(uv_poll_t *h, int status, int events); static void uv_timeout_cb(uv_timer_t *h); uv_loop_t *m_eventLoop; uv_timer_t *m_curlTimer; CURLM *m_curlMulti; std::shared_ptr m_logger; std::map m_requests; }; struct CurlSocketData_ { HttpClient *client; curl_socket_t curlSocket; uv_poll_t *pollHandle; }; struct HttpRequestData_ { HttpClient *client; CURL *curl; curl_slist *requestHeaders = nullptr; CurlSocketData_ *socketData = nullptr; ResponseCallback callback; std::unique_ptr response; inline HttpRequestData_(HttpClient *client) { this->client = client; } }; struct HttpOptions { std::optional>> headers; std::optional body; }; }