简体   繁体   中英

c++ libcurl progress callback with download not working

I'm using curl for uploads and downloads and also try to include the provided progress bar from curl. I managed to get the progress bar working when uploading files, but unfortunately the callback function only receives 0 values on the download.

Here are the options that are set for the download:

::curl_easy_reset( m_pimpl->curl ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_SSL_VERIFYPEER,  0L ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_SSL_VERIFYHOST,  0L ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_HEADERFUNCTION,  &CurlAgent::HeaderCallback ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_HEADERDATA,      this ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_HEADER,          0L ) ;
::curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method.c_str() ); // "GET" in download

::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER,   error ) ;
::curl_easy_setopt(curl, CURLOPT_URL,           url.c_str());
::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlAgent::Receive ) ;
::curl_easy_setopt(curl, CURLOPT_WRITEDATA,     this ) ;

//setting the progress callback function
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, this);

CURLcode curl_code = ::curl_easy_perform(curl);

ANd this is the callback used for the progress bar:

static int progress_callback(void *ptr,   curl_off_t TotalDownloadSize,   curl_off_t finishedDownloadSize,   curl_off_t TotalToUpload,   curl_off_t NowUploaded) {

    curl_off_t processed = (TotalDownloadSize > TotalToUpload) ? finishedDownloadSize : NowUploaded;
    curl_off_t total = (TotalDownloadSize > TotalToUpload) ? TotalDownloadSize : TotalToUpload;

    ...

    return 0;
}

As mentioned when I perform uploads of files the parameters TotalToUpload and NowUploaded contain the correct values. But when downloading all four parameters contain 0 !? Do I have to set another option when downloading files to receive the correct sizes?

Alternative solution

I found an alternative solution, buy using another request that delivers information about the files on the drive which also contains the file size. In the set callback write function

   ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlAgent::Receive )

the current downloaded size is given as parameter with which it is then possible to create the progress bar.

Here is also the documentation of the used service and the requests:

Per the libcurl documentation:

CURLOPT_XFERINFOFUNCTION explained

Unknown/unused argument values passed to the callback will be set to zero (like if you only download data, the upload size will remain 0). Many times the callback will be called one or more times first, before it knows the data sizes so a program must be made to handle that.

If the callback is never giving you non-zero values during a download, then either:

  1. there is a bug in libcurl (less likely)

  2. libcurl simply doesn't know the sizes (more likely), such as if the download is encoded in such a way that prevents calculating the sizes effectively.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM