diff --git a/src/network/core/http.h b/src/network/core/http.h index ecacc95ba1..0b082ab1c7 100644 --- a/src/network/core/http.h +++ b/src/network/core/http.h @@ -13,6 +13,7 @@ #define NETWORK_CORE_HTTP_H #include "tcp.h" +#include "../../src/core/alloc_type.hpp" constexpr int HTTP_429_TOO_MANY_REQUESTS = 429; @@ -26,11 +27,11 @@ struct HTTPCallback { /** * We're receiving data. - * @param data the received data, nullptr when all data has been received. The implementation is responsible for freeing the data. + * @param data the received data, nullptr when all data has been received. * @param length the amount of received data, 0 when all data has been received. * @note When nullptr is sent the HTTP socket handler is closed/freed. */ - virtual void OnReceiveData(const char *data, size_t length) = 0; + virtual void OnReceiveData(UniqueBuffer data) = 0; /** * Check if there is a request to cancel the transfer. diff --git a/src/network/core/http_curl.cpp b/src/network/core/http_curl.cpp index 7c8ff0fc7f..d8bf73fe18 100644 --- a/src/network/core/http_curl.cpp +++ b/src/network/core/http_curl.cpp @@ -195,11 +195,11 @@ void HttpThread() HTTPThreadSafeCallback *callback = static_cast(userdata); /* Copy the buffer out of CURL. OnReceiveData() will free it when done. */ - char *buffer = size * nmemb == 0 ? nullptr : MallocT(size * nmemb); + UniqueBuffer buffer(size * nmemb); if (buffer != nullptr) { - memcpy(buffer, ptr, size * nmemb); + memcpy(buffer.get(), ptr, size * nmemb); } - callback->OnReceiveData(buffer, size * nmemb); + callback->OnReceiveData(std::move(buffer)); return size * nmemb; }); @@ -223,7 +223,7 @@ void HttpThread() if (res == CURLE_OK) { Debug(net, 1, "HTTP request succeeded"); - request->callback.OnReceiveData(nullptr, 0); + request->callback.OnReceiveData({}); } else { long status_code = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status_code); diff --git a/src/network/core/http_shared.h b/src/network/core/http_shared.h index fedcd30770..ce32c0ab8a 100644 --- a/src/network/core/http_shared.h +++ b/src/network/core/http_shared.h @@ -24,11 +24,10 @@ private: /** Entries on the queue for later handling. */ class Callback { public: - Callback(const char *data, size_t length) : data(data), length(length), failure(false) {} - Callback() : data(nullptr), length(0), failure(true) {} + Callback(UniqueBuffer data) : data(std::move(data)), failure(false) {} + Callback() : data({}), failure(true) {} - const char *data; - size_t length; + UniqueBuffer data; bool failure; }; @@ -45,10 +44,10 @@ public: /** * Similar to HTTPCallback::OnReceiveData, but thread-safe. */ - void OnReceiveData(const char *data, size_t length) + void OnReceiveData(UniqueBuffer data) { std::lock_guard lock(this->mutex); - this->queue.emplace_back(data, length); + this->queue.emplace_back(std::move(data)); } /** @@ -66,7 +65,7 @@ public: if (item.failure) { this->callback->OnFailure(); } else { - this->callback->OnReceiveData(item.data, item.length); + this->callback->OnReceiveData(std::move(item.data)); } } @@ -101,13 +100,6 @@ public: { std::lock_guard lock(this->mutex); - /* Free all data that was not handled. */ - for (auto &item : this->queue) { - if (!item.failure) { - free(item.data); - } - - } queue.clear(); queue_cv.notify_all(); } diff --git a/src/network/core/http_winhttp.cpp b/src/network/core/http_winhttp.cpp index a69b58f526..29b198a4ce 100644 --- a/src/network/core/http_winhttp.cpp +++ b/src/network/core/http_winhttp.cpp @@ -159,14 +159,14 @@ void NetworkHTTPRequest::WinHttpCallback(DWORD code, void *info, DWORD length) /* Next step: read the data in a temporary allocated buffer. * The buffer will be free'd by OnReceiveData() in the next step. */ - char *buffer = size == 0 ? nullptr : MallocT(size); + char *buffer = size == 0 ? nullptr : new char[size]; WinHttpReadData(this->request, buffer, size, 0); } break; case WINHTTP_CALLBACK_STATUS_READ_COMPLETE: Debug(net, 4, "HTTP callback: {} bytes", length); - this->callback.OnReceiveData(static_cast(info), length); + this->callback.OnReceiveData(UniqueBuffer(std::unique_ptr(static_cast(info)), length)); if (length == 0) { /* Next step: no more data available: request is finished. */ diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index e33fb29a82..b3f997f6d6 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -608,23 +608,19 @@ void ClientNetworkContentSocketHandler::OnFailure() } } -void ClientNetworkContentSocketHandler::OnReceiveData(const char *data, size_t length) +void ClientNetworkContentSocketHandler::OnReceiveData(UniqueBuffer data) { - assert(data == nullptr || length != 0); + assert(data.get() == nullptr || data.size() != 0); /* Ignore any latent data coming from a connection we closed. */ if (this->http_response_index == -2) { - if (data != nullptr) { - free(data); - } return; } if (this->http_response_index == -1) { if (data != nullptr) { /* Append the rest of the response. */ - this->http_response.insert(this->http_response.end(), data, data + length); - free(data); + this->http_response.insert(this->http_response.end(), data.get(), data.get() + data.size()); return; } else { /* Make sure the response is properly terminated. */ @@ -637,16 +633,15 @@ void ClientNetworkContentSocketHandler::OnReceiveData(const char *data, size_t l if (data != nullptr) { /* We have data, so write it to the file. */ - if (fwrite(data, 1, length, this->curFile) != length) { + if (fwrite(data.get(), 1, data.size(), this->curFile) != data.size()) { /* Writing failed somehow, let try via the old method. */ this->OnFailure(); } else { /* Just received the data. */ - this->OnDownloadProgress(this->curInfo, (int)length); + this->OnDownloadProgress(this->curInfo, (int)data.size()); } /* Nothing more to do now. */ - free(data); return; } diff --git a/src/network/network_content.h b/src/network/network_content.h index 85918bf8d3..8dcaacc3dc 100644 --- a/src/network/network_content.h +++ b/src/network/network_content.h @@ -97,7 +97,7 @@ protected: void OnDownloadComplete(ContentID cid) override; void OnFailure() override; - void OnReceiveData(const char *data, size_t length) override; + void OnReceiveData(UniqueBuffer data) override; bool IsCancelled() const override; bool BeforeDownload(); diff --git a/src/network/network_survey.cpp b/src/network/network_survey.cpp index a0fd1ee9a0..85bcf7d9e2 100644 --- a/src/network/network_survey.cpp +++ b/src/network/network_survey.cpp @@ -389,12 +389,10 @@ void NetworkSurveyHandler::OnFailure() this->loaded.notify_all(); } -void NetworkSurveyHandler::OnReceiveData(const char *data, size_t) +void NetworkSurveyHandler::OnReceiveData(UniqueBuffer data) { if (data == nullptr) { Debug(net, 1, "Survey: survey results sent"); this->loaded.notify_all(); - } else { - free(data); } } diff --git a/src/network/network_survey.h b/src/network/network_survey.h index 44ac781102..a7ee2fe7f6 100644 --- a/src/network/network_survey.h +++ b/src/network/network_survey.h @@ -20,7 +20,7 @@ class NetworkSurveyHandler : public HTTPCallback { protected: void OnFailure() override; - void OnReceiveData(const char *data, size_t length) override; + void OnReceiveData(UniqueBuffer data) override; bool IsCancelled() const override { return false; } public: