1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| #define CURL_STATICLIB
#include <stdio.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include <string>
class MyClass;
typedef struct job_info_t {
int jobID;
MyClass *parent;
} struct job_info_t;
int progress_callback(void *data, double download_total_size, double download_total_size_done, double ultotal, double uldone)
{
job_info_t *jinfo = (job_info_t *)data;
if(!jinfo) return 1;
jinfo->parent->reportProgress(jinfo->jobID, download_total_size, download_total_size_done);
return 0;
}
void MyClass::reportProgress(int jobID, double download_total_size, double download_total_size_done)
{
printf("DLFile-%04d|progress: %0.3f\n", jobID, download_total_size_done / download_total_size);
}
int MyClass::downloadFile(int jobID, std::string localFile, string url)
{
job_info jinfo;
jinfo.parent = this;
jinfo.jobID = jobID;
CURL *curl = curl_easy_init();
if(!curl)
{
printf("DLFile-%04d|error creating curl: %s\n", jobID, localFile.string().c_str());
printf("DLFile-%04d|download URL: %s\n", jobID, url.c_str());
return 1;
}
FILE *outFile = fopen(localFile.string().c_str(), "wb");
if(!outFile)
{
perror("error opening file");
printf("DLFile-%04d|error opening local file: %s.\n", jobID, localFile.string().c_str());
printf("DLFile-%04d|download URL: %s\n", jobID, url.c_str());
return 2;
}
char *curl_err_str[CURL_ERROR_SIZE];
memset(curl_err_str, 0, CURL_ERROR_SIZE);
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
// logging stuff
// curl_easy_setopt(curl, CURLOPT_STDERR, InstallerLog::getSingleton()->getLogFilePtr());
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str[0]);
// progess stuff
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &jinfo);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, &progress_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outFile);
// http related settings
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); // follow redirects
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1); // set the Referer: field in requests where it follows a Location: redirect.
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 20);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "YourUserAgent");
curl_easy_setopt(curl, CURLOPT_FILETIME, 1);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(outFile);
// print curl error if existing
if(res != CURLE_OK)
{
printf("DLFile-%04d| CURL returned: %d\n", jobID, res);
printf("DLFile-%04d| CURL error: %s\n", jobID, curl_err_str);
return 3;
}
return 0;
} |