fix HttpClient destructor and remove its demo in main()
This commit is contained in:
parent
5b84472864
commit
d157103a68
40
http.cpp
40
http.cpp
@ -23,10 +23,26 @@ HttpClient::HttpClient(uv_loop_t *loop): m_eventLoop(loop) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HttpClient::~HttpClient() {
|
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){
|
uv_close((uv_handle_t*)m_curlTimer, [](uv_handle_t *h){
|
||||||
delete 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) {
|
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;
|
auto requestData = insertResult.first;
|
||||||
requestData->second.callback = cb;
|
requestData->second.callback = cb;
|
||||||
|
requestData->second.curl = requestHandle;
|
||||||
requestData->second.response = std::make_unique<HttpResponse>();
|
requestData->second.response = std::make_unique<HttpResponse>();
|
||||||
curl_easy_setopt(requestHandle, CURLOPT_WRITEFUNCTION, &HttpClient::curl_data_cb);
|
curl_easy_setopt(requestHandle, CURLOPT_WRITEFUNCTION, &HttpClient::curl_data_cb);
|
||||||
curl_easy_setopt(requestHandle, CURLOPT_WRITEDATA, requestHandle);
|
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;
|
data->pollHandle = new uv_poll_t;
|
||||||
uv_poll_init(self->m_eventLoop, data->pollHandle, curlSocket);
|
uv_poll_init(self->m_eventLoop, data->pollHandle, curlSocket);
|
||||||
data->pollHandle->data = data;
|
data->pollHandle->data = data;
|
||||||
|
self->m_requests.at(curl).socketData = data;
|
||||||
} else {
|
} else {
|
||||||
data = reinterpret_cast<CurlSocketData_*>(socketPtr);
|
data = reinterpret_cast<CurlSocketData_*>(socketPtr);
|
||||||
}
|
}
|
||||||
@ -97,10 +115,12 @@ int HttpClient::curl_socket_cb(CURL *curl, curl_socket_t curlSocket, int action,
|
|||||||
if (socketPtr) {
|
if (socketPtr) {
|
||||||
self->m_logger->debug("removing socket {}", curlSocket);
|
self->m_logger->debug("removing socket {}", curlSocket);
|
||||||
data = reinterpret_cast<CurlSocketData_*>(socketPtr);
|
data = reinterpret_cast<CurlSocketData_*>(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);
|
curl_multi_assign(self->m_curlMulti, curlSocket, nullptr);
|
||||||
data->pollHandle->data = nullptr;
|
pollHandle->data = nullptr;
|
||||||
uv_close((uv_handle_t*)data->pollHandle, [](uv_handle_t *h){ delete h; });
|
uv_close((uv_handle_t*)pollHandle, [](uv_handle_t *h){ delete h; });
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,22 +168,24 @@ void HttpClient::check_curl_messages() {
|
|||||||
switch (msg->msg) {
|
switch (msg->msg) {
|
||||||
case CURLMSG_DONE: {
|
case CURLMSG_DONE: {
|
||||||
CURLcode r = msg->data.result;
|
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) {
|
if (r == CURLE_OK) {
|
||||||
m_logger->debug("curl transfer done");
|
m_logger->debug("curl transfer done");
|
||||||
long statusCode = 0;
|
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.response->status = statusCode;
|
||||||
request.callback(std::move(request.response), CURLE_OK);
|
request.callback(std::move(request.response), CURLE_OK);
|
||||||
} else {
|
} else {
|
||||||
m_logger->error("curl transfer error: {}", (int)r);
|
m_logger->error("curl transfer error: {}", (int)r);
|
||||||
request.callback(nullptr, r);
|
request.callback(nullptr, r);
|
||||||
}
|
}
|
||||||
curl_multi_remove_handle(m_curlMulti, msg->easy_handle);
|
curl_multi_remove_handle(m_curlMulti, curl);
|
||||||
curl_easy_cleanup(msg->easy_handle);
|
curl_easy_cleanup(curl);
|
||||||
if (request.requestHeaders)
|
if (request.requestHeaders)
|
||||||
curl_slist_free_all(request.requestHeaders);
|
curl_slist_free_all(request.requestHeaders);
|
||||||
m_requests.erase(msg->easy_handle);
|
m_logger->debug("removing request");
|
||||||
|
m_requests.erase(curl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
2
http.h
2
http.h
@ -47,7 +47,9 @@ namespace http {
|
|||||||
|
|
||||||
struct HttpRequestData_ {
|
struct HttpRequestData_ {
|
||||||
HttpClient *client;
|
HttpClient *client;
|
||||||
|
CURL *curl;
|
||||||
curl_slist *requestHeaders = nullptr;
|
curl_slist *requestHeaders = nullptr;
|
||||||
|
CurlSocketData_ *socketData = nullptr;
|
||||||
ResponseCallback callback;
|
ResponseCallback callback;
|
||||||
std::unique_ptr<HttpResponse> response;
|
std::unique_ptr<HttpResponse> response;
|
||||||
HttpRequestData_(HttpClient *client) {
|
HttpRequestData_(HttpClient *client) {
|
||||||
|
9
main.cpp
9
main.cpp
@ -10,15 +10,6 @@ void on_signal(uv_signal_t *h, int signum) {
|
|||||||
int main() {
|
int main() {
|
||||||
uv_loop_t *loop = uv_default_loop();
|
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_t signalHandles[2] = {};
|
||||||
uv_signal_init(loop, signalHandles);
|
uv_signal_init(loop, signalHandles);
|
||||||
uv_signal_start(signalHandles, on_signal, SIGINT);
|
uv_signal_start(signalHandles, on_signal, SIGINT);
|
||||||
|
Loading…
Reference in New Issue
Block a user