Greetings everyone read this topic, my platform is win32. And I'm using libcurl with a problem.
My goal is to coding with libcurl for a download program, which it includes requesting a url to download a file, saving the file locally(fwrite), showing the progress bar while downloading.
The Problem is it can download the very small file well but when requesting a larger file like 30MB, it stops before it's done.
How can I debug this program to work well with any size of files?
I'm not familiar with libcurl, any simple detail could help. Can I have either answer of how curl_easy series works to call multiple callback functions, improper coding of either of the two callback functions, or some missing rules from libcurl? Feel free to answer me anything.
Things I've tried:
1.I've tried re-compiling versions of libcurl. Now I'm using libcurl-7.64 compiled with "WITH_SSL=static".
2.I've tried many sites, finding the clue: the sites for very small(like 80kb) file will be downloaded completely with the progress bar. But larger file(like 30Mb) will be incomplete. One of my guess is it stopped from some transfer problem since the file is larger.
Answer: Just comment out the code below fix the problem.
//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3L); ====> //curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3L);
static FILE * fp;
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t nWrite = fwrite(ptr, size, nmemb, fp);
return nWrite;
}
static int progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
(void)ultotal;
(void)ulnow;
int totaldotz = 40;
double fractiondownloaded = (double)dlnow / (double)dltotal;
int dotz = (int)(fractiondownloaded * totaldotz);
printf("%3.0f%% [", fractiondownloaded * 100); //print the number percentage of the progress
int i = 0;
for (; i < dotz; i++) { //print "=" to show progress
printf("=");
}
for (; i < totaldotz; i++) { //print space to occupy the rest
printf(" ");
}
printf("]\r");
fflush(stdout);
return 0;
}
int download_function(CURL *curl,const char * url, const char * path)
{
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
fopen_s(&fp, path, "ab+");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3L);
char * error = NULL;
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
CURLcode retcCode = curl_easy_perform(curl);
fclose(fp);
const char* pError = curl_easy_strerror(retcCode);
if (curl) {
curl_easy_cleanup(curl);
}
return 0;
}