#include "../include/curl.hpp" #include "../include/env.hpp" #include #include using namespace std; #ifdef DEBUG #define CURL_DEBUG #endif #undef CURL_DEBUG class CurlSession { public: CurlSession() { curl_global_init(CURL_GLOBAL_ALL); } ~CurlSession() { curl_global_cleanup(); } }; static CurlSession curlSession; namespace sibs { // TODO: Instead of writing to file, reading from file and extracting it; // we can extract to file directly by putting libarchive code here size_t writeToFile(char *data, size_t size, size_t nmemb, FILE *stream) { if(!stream) return 0; return fwrite(data, size, nmemb, stream); } size_t writeToString(char *data, size_t size, size_t nmemb, string *writerData) { if(!writerData) return 0; writerData->append(data, size * nmemb); return size * nmemb; } Result curl::downloadFile(const char *url, const _tinydir_char_t *filepath) { CURL *curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle, CURLOPT_URL, url); #ifdef CURL_DEBUG long verbose = 1L; long noProgressMeter = 0L; #else long verbose = 0L; long noProgressMeter = 1L; #endif curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, verbose); curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, noProgressMeter); curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeToFile); curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, true); curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "SIBS"); curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, false); #if OS_FAMILY == OS_FAMILY_POSIX FILE *file = fopen(filepath, "wb"); #else FILE *file = _wfopen(filepath, L"wb"); #endif if(!file) { int error = errno; curl_easy_cleanup(curl_handle); string errMsg = "Failed to open file for writing: "; errMsg += toUtf8(filepath); if(error != 0) { errMsg += "; Reason: "; errMsg += strerror(error); return Result::Err(errMsg); } else { return Result::Err(errMsg); } } curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, file); printf("Downloading from url: %s\n", url); CURLcode curlResponse = curl_easy_perform(curl_handle); long httpCode = 0; curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpCode); curl_easy_cleanup(curl_handle); fclose(file); if(httpCode == 200 && curlResponse == CURLE_OK) return Result::Ok(true); if(httpCode != 200) { string errMsg = "Failed to download file from url: "; errMsg += url; errMsg += "\nReason: Expected http response code 200 (OK), got: "; errMsg += to_string(httpCode); errMsg += " ("; errMsg += curl_easy_strerror(curlResponse); errMsg += ")"; return Result::Err(errMsg); } else { string errMsg = "Failed to download file from url: "; errMsg += url; errMsg += "\nReason: "; errMsg += curl_easy_strerror(curlResponse); return Result::Err(errMsg); } } HttpResult curl::get(const char *url) { HttpResult result; CURL *curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle, CURLOPT_URL, url); #ifdef CURL_DEBUG long verbose = 1L; long noProgressMeter = 0L; #else long verbose = 0L; long noProgressMeter = 1L; #endif curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, verbose); curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, noProgressMeter); curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeToString); curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, true); curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "SIBS"); curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &result.str); printf("Downloading from url: %s\n", url); CURLcode curlResponse = curl_easy_perform(curl_handle); long httpCode = 503; curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpCode); curl_easy_cleanup(curl_handle); result.httpCode = httpCode; if(httpCode == 200 && curlResponse == CURLE_OK) { result.success = true; return result; } result.success = false; if(httpCode != 200) { string errMsg = "Failed to download file from url: "; errMsg += url; errMsg += "\nReason: Expected http response code 200 (OK), got: "; errMsg += to_string(httpCode); errMsg += " ("; errMsg += curl_easy_strerror(curlResponse); errMsg += ")"; return result; } else { string errMsg = "Failed to download file from url: "; errMsg += url; errMsg += "\nReason: "; errMsg += curl_easy_strerror(curlResponse); return result; } } }