}
std::string output_file_partial;
+
+ if (!output_file.empty()) {
+ output_file_partial = output_file + ".partial";
+ }
+
+ if (download(url, headers, output_file_partial, progress, response_str)) {
+ return 1;
+ }
+
+ if (!output_file.empty()) {
+ try {
+ std::filesystem::rename(output_file_partial, output_file);
+ } catch (const std::filesystem::filesystem_error & e) {
+ printe("Failed to rename '%s' to '%s': %s\n", output_file_partial.c_str(), output_file.c_str(), e.what());
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+ ~HttpClient() {
+ if (chunk) {
+ curl_slist_free_all(chunk);
+ }
+
+ if (curl) {
+ curl_easy_cleanup(curl);
+ }
+ }
+
+ private:
+ CURL * curl = nullptr;
+ struct curl_slist * chunk = nullptr;
+
+ int download(const std::string & url, const std::vector<std::string> & headers, const std::string & output_file,
+ const bool progress, std::string * response_str = nullptr) {
curl = curl_easy_init();
if (!curl) {
return 1;
progress_data data;
File out;
if (!output_file.empty()) {
- output_file_partial = output_file + ".partial";
- if (!out.open(output_file_partial, "ab")) {
+ if (!out.open(output_file, "ab")) {
printe("Failed to open file for writing\n");
return 1;
}
set_write_options(response_str, out);
- data.file_size = set_resume_point(output_file_partial);
+ data.file_size = set_resume_point(output_file);
set_progress_options(progress, data);
set_headers(headers);
CURLcode res = perform(url);
printe("Fetching resource '%s' failed: %s\n", url.c_str(), curl_easy_strerror(res));
return 1;
}
- if (!output_file.empty()) {
- std::filesystem::rename(output_file_partial, output_file);
- }
return 0;
}
- ~HttpClient() {
- if (chunk) {
- curl_slist_free_all(chunk);
- }
-
- if (curl) {
- curl_easy_cleanup(curl);
- }
- }
-
- private:
- CURL * curl = nullptr;
- struct curl_slist * chunk = nullptr;
-
void set_write_options(std::string * response_str, const File & out) {
if (response_str) {
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, capture_data);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
+#ifdef _WIN32
+ curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
+#endif
return curl_easy_perform(curl);
}