1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-19 09:30:06 +02:00

Adds callback to report the download and upload progress (#1202)

* Adds callback to report the download and upload progress

* Fixes upload progress
This commit is contained in:
Dmitry Vedenko 2021-07-13 21:47:07 +03:00 committed by GitHub
parent 06eae90100
commit 1bcc98230d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 0 deletions

View File

@ -44,10 +44,15 @@ enum class NetworkError
HTTPError HTTPError
}; };
//! Interface, that provides access to the data from the HTTP response
class NETWORK_MANAGER_API IResponse class NETWORK_MANAGER_API IResponse
{ {
public: public:
using RequestCallback = std::function<void (IResponse*)>; using RequestCallback = std::function<void (IResponse*)>;
//! Called when download or upload progress changes. Expected can be zero when
//! transfer encoding does not allow to calculate the size
using ProgressCallback = std::function<void(int64_t current, int64_t expected)>;
virtual ~IResponse () = default; virtual ~IResponse () = default;
@ -74,6 +79,11 @@ public:
virtual void setOnDataReceivedCallback (RequestCallback callback) = 0; virtual void setOnDataReceivedCallback (RequestCallback callback) = 0;
virtual void setRequestFinishedCallback (RequestCallback callback) = 0; virtual void setRequestFinishedCallback (RequestCallback callback) = 0;
//! Set the download progress callback
virtual void setDownloadProgressCallback(ProgressCallback callback) = 0;
//! Set the upload progress callback
virtual void setUploadProgressCallback(ProgressCallback callback) = 0;
// The total bytes available to read by readData // The total bytes available to read by readData
virtual uint64_t getBytesAvailable () const noexcept = 0; virtual uint64_t getBytesAvailable () const noexcept = 0;

View File

@ -203,6 +203,18 @@ void CurlResponse::setRequestFinishedCallback (RequestCallback callback)
mRequestFinishedCallback (this); mRequestFinishedCallback (this);
} }
void CurlResponse::setDownloadProgressCallback(ProgressCallback callback)
{
std::lock_guard<std::mutex> callbackLock(mCallbackMutex);
mDownloadProgressCallback = std::move(callback);
}
void CurlResponse::setUploadProgressCallback(ProgressCallback callback)
{
std::lock_guard<std::mutex> callbackLock(mCallbackMutex);
mUploadProgressCallback = std::move(callback);
}
uint64_t CurlResponse::getBytesAvailable () const noexcept uint64_t CurlResponse::getBytesAvailable () const noexcept
{ {
std::lock_guard<std::mutex> lock (mDataBufferMutex); std::lock_guard<std::mutex> lock (mDataBufferMutex);
@ -241,9 +253,14 @@ void CurlResponse::perform (const void* ptr, size_t size)
handle.setOption (CURLOPT_HEADERFUNCTION, HeaderCallback); handle.setOption (CURLOPT_HEADERFUNCTION, HeaderCallback);
handle.setOption (CURLOPT_HEADERDATA, this); handle.setOption (CURLOPT_HEADERDATA, this);
handle.setOption (CURLOPT_XFERINFOFUNCTION, CurlProgressCallback);
handle.setOption (CURLOPT_XFERINFODATA, this);
handle.setOption (CURLOPT_FOLLOWLOCATION, mRequest.getMaxRedirects () == 0 ? 0 : 1); handle.setOption (CURLOPT_FOLLOWLOCATION, mRequest.getMaxRedirects () == 0 ? 0 : 1);
handle.setOption (CURLOPT_MAXREDIRS, mRequest.getMaxRedirects ()); handle.setOption (CURLOPT_MAXREDIRS, mRequest.getMaxRedirects ());
handle.setOption (CURLOPT_NOPROGRESS, 0L);
handle.setOption (CURLOPT_CONNECTTIMEOUT_MS, handle.setOption (CURLOPT_CONNECTTIMEOUT_MS,
std::chrono::duration_cast<std::chrono::milliseconds> (mRequest.getTimeout()).count () std::chrono::duration_cast<std::chrono::milliseconds> (mRequest.getTimeout()).count ()
); );
@ -301,6 +318,8 @@ void CurlResponse::perform (const void* ptr, size_t size)
mRequestFinishedCallback = {}; mRequestFinishedCallback = {};
mOnDataReceivedCallback = {}; mOnDataReceivedCallback = {};
mDownloadProgressCallback = {};
mUploadProgressCallback = {};
} }
@ -378,5 +397,20 @@ size_t CurlResponse::HeaderCallback (const char* buffer, size_t size, size_t nit
return size; return size;
} }
int CurlResponse::CurlProgressCallback(
CurlResponse* clientp, curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow) noexcept
{
std::lock_guard<std::mutex> callbackLock(clientp->mCallbackMutex);
if (dltotal > 0 && clientp->mDownloadProgressCallback)
clientp->mDownloadProgressCallback(dlnow, dltotal);
if (ultotal > 0 && clientp->mUploadProgressCallback)
clientp->mUploadProgressCallback(ulnow, ultotal);
return CURLE_OK;
}
} }
} }

View File

@ -56,6 +56,11 @@ public:
void setRequestFinishedCallback (RequestCallback callback) override; void setRequestFinishedCallback (RequestCallback callback) override;
//! Set the download progress callback
virtual void setDownloadProgressCallback(ProgressCallback callback) override;
//! Set the upload progress callback
virtual void setUploadProgressCallback(ProgressCallback callback) override;
uint64_t getBytesAvailable () const noexcept override; uint64_t getBytesAvailable () const noexcept override;
uint64_t readData (void* buffer, uint64_t maxBytesCount) override; uint64_t readData (void* buffer, uint64_t maxBytesCount) override;
@ -71,6 +76,8 @@ private:
mutable std::mutex mCallbackMutex; mutable std::mutex mCallbackMutex;
RequestCallback mOnDataReceivedCallback; RequestCallback mOnDataReceivedCallback;
RequestCallback mRequestFinishedCallback; RequestCallback mRequestFinishedCallback;
ProgressCallback mDownloadProgressCallback;
ProgressCallback mUploadProgressCallback;
mutable std::mutex mHeadersMutex; mutable std::mutex mHeadersMutex;
HeadersList mResponseHeaders; HeadersList mResponseHeaders;
@ -92,6 +99,10 @@ private:
static size_t WriteCallback (const uint8_t* ptr, size_t size, size_t nmemb, CurlResponse* userdata) noexcept; static size_t WriteCallback (const uint8_t* ptr, size_t size, size_t nmemb, CurlResponse* userdata) noexcept;
static size_t HeaderCallback (const char* buffer, size_t size, size_t nitems, CurlResponse* userdata) noexcept; static size_t HeaderCallback (const char* buffer, size_t size, size_t nitems, CurlResponse* userdata) noexcept;
static int CurlProgressCallback(
CurlResponse* clientp, curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal,
curl_off_t ulnow) noexcept;
}; };
} }