From d157103a686e71ed35753686ba03e03a35079844 Mon Sep 17 00:00:00 2001 From: Slavasil Date: Fri, 15 Nov 2024 10:57:52 +0300 Subject: [PATCH] fix HttpClient destructor and remove its demo in main() --- http.cpp | 40 +++++++++++++++++++++++++++++++--------- http.h | 2 ++ main.cpp | 9 --------- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/http.cpp b/http.cpp index af53837..089932b 100644 --- a/http.cpp +++ b/http.cpp @@ -23,10 +23,26 @@ HttpClient::HttpClient(uv_loop_t *loop): m_eventLoop(loop) { } HttpClient::~HttpClient() { + while (m_requests.size() > 0) { + auto i = m_requests.begin(); + m_logger->warn("canceling request while destructing"); + if (i->second.socketData) { + m_logger->debug("removing request handle"); + curl_multi_remove_handle(m_curlMulti, i->second.curl); + } + m_logger->debug("closing poll handle"); + if (i->second.socketData->pollHandle) { + uv_poll_stop(i->second.socketData->pollHandle); + uv_close((uv_handle_t*)i->second.socketData->pollHandle, [](uv_handle_t *h){ + delete h; + }); + } + m_requests.erase(i->first); + } + m_logger->debug("closing timer handle"); uv_close((uv_handle_t*)m_curlTimer, [](uv_handle_t *h){ delete h; }); - spdlog::warn("freeing curl structures is not yet implemented!"); } bool HttpClient::send_request(std::string method, std::string url, HttpOptions opts, ResponseCallback cb) { @@ -39,6 +55,7 @@ bool HttpClient::send_request(std::string method, std::string url, HttpOptions o } auto requestData = insertResult.first; requestData->second.callback = cb; + requestData->second.curl = requestHandle; requestData->second.response = std::make_unique(); curl_easy_setopt(requestHandle, CURLOPT_WRITEFUNCTION, &HttpClient::curl_data_cb); curl_easy_setopt(requestHandle, CURLOPT_WRITEDATA, requestHandle); @@ -85,6 +102,7 @@ int HttpClient::curl_socket_cb(CURL *curl, curl_socket_t curlSocket, int action, data->pollHandle = new uv_poll_t; uv_poll_init(self->m_eventLoop, data->pollHandle, curlSocket); data->pollHandle->data = data; + self->m_requests.at(curl).socketData = data; } else { data = reinterpret_cast(socketPtr); } @@ -97,10 +115,12 @@ int HttpClient::curl_socket_cb(CURL *curl, curl_socket_t curlSocket, int action, if (socketPtr) { self->m_logger->debug("removing socket {}", curlSocket); data = reinterpret_cast(socketPtr); - uv_poll_stop(data->pollHandle); + uv_poll_t *pollHandle = data->pollHandle; + data->pollHandle = nullptr; + uv_poll_stop(pollHandle); curl_multi_assign(self->m_curlMulti, curlSocket, nullptr); - data->pollHandle->data = nullptr; - uv_close((uv_handle_t*)data->pollHandle, [](uv_handle_t *h){ delete h; }); + pollHandle->data = nullptr; + uv_close((uv_handle_t*)pollHandle, [](uv_handle_t *h){ delete h; }); delete data; } } @@ -148,22 +168,24 @@ void HttpClient::check_curl_messages() { switch (msg->msg) { case CURLMSG_DONE: { CURLcode r = msg->data.result; - auto &request = m_requests.at(msg->easy_handle); + CURL *curl = msg->easy_handle; + auto &request = m_requests.at(curl); if (r == CURLE_OK) { m_logger->debug("curl transfer done"); long statusCode = 0; - curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &statusCode); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode); request.response->status = statusCode; request.callback(std::move(request.response), CURLE_OK); } else { m_logger->error("curl transfer error: {}", (int)r); request.callback(nullptr, r); } - curl_multi_remove_handle(m_curlMulti, msg->easy_handle); - curl_easy_cleanup(msg->easy_handle); + curl_multi_remove_handle(m_curlMulti, curl); + curl_easy_cleanup(curl); if (request.requestHeaders) curl_slist_free_all(request.requestHeaders); - m_requests.erase(msg->easy_handle); + m_logger->debug("removing request"); + m_requests.erase(curl); break; } default: diff --git a/http.h b/http.h index 374547c..13cba3a 100644 --- a/http.h +++ b/http.h @@ -47,7 +47,9 @@ namespace http { struct HttpRequestData_ { HttpClient *client; + CURL *curl; curl_slist *requestHeaders = nullptr; + CurlSocketData_ *socketData = nullptr; ResponseCallback callback; std::unique_ptr response; HttpRequestData_(HttpClient *client) { diff --git a/main.cpp b/main.cpp index 4a3c4d1..39f7c4a 100644 --- a/main.cpp +++ b/main.cpp @@ -10,15 +10,6 @@ void on_signal(uv_signal_t *h, int signum) { int main() { uv_loop_t *loop = uv_default_loop(); - http::HttpClient httpClient(loop); - spdlog::info("sending request"); - httpClient.send_request("GET", "https://slavasil.ru/", {}, [](auto resp, CURLcode code){ - if (code == 0) { - spdlog::info("got response! {} {}", resp->status, resp->body); - } else { - spdlog::error("got error!"); - } - }); uv_signal_t signalHandles[2] = {}; uv_signal_init(loop, signalHandles); uv_signal_start(signalHandles, on_signal, SIGINT);