@@ -373,7 +373,7 @@ class File {
373373 return out;
374374 }
375375
376- void close () {
376+ ~File () {
377377 if (fd >= 0 ) {
378378# ifdef _WIN32
379379 if (hFile != INVALID_HANDLE_VALUE) {
@@ -388,13 +388,6 @@ class File {
388388 if (file) {
389389 fclose (file);
390390 }
391-
392- fd = -1 ;
393- file = nullptr ;
394- }
395-
396- ~File () {
397- close ();
398391 }
399392
400393 private:
@@ -414,6 +407,38 @@ class HttpClient {
414407 }
415408
416409 std::string output_file_partial;
410+
411+ if (!output_file.empty ()) {
412+ output_file_partial = output_file + " .partial" ;
413+ }
414+
415+ if (download (url, headers, output_file_partial, progress, response_str)) {
416+ return 1 ;
417+ }
418+
419+ if (!output_file.empty ()) {
420+ std::filesystem::rename (output_file_partial, output_file);
421+ }
422+
423+ return 0 ;
424+ }
425+
426+ ~HttpClient () {
427+ if (chunk) {
428+ curl_slist_free_all (chunk);
429+ }
430+
431+ if (curl) {
432+ curl_easy_cleanup (curl);
433+ }
434+ }
435+
436+ private:
437+ CURL * curl = nullptr ;
438+ struct curl_slist * chunk = nullptr ;
439+
440+ int download (const std::string & url, const std::vector<std::string> & headers, const std::string & output_file,
441+ const bool progress, std::string * response_str = nullptr ) {
417442 curl = curl_easy_init ();
418443 if (!curl) {
419444 return 1 ;
@@ -422,8 +447,7 @@ class HttpClient {
422447 progress_data data;
423448 File out;
424449 if (!output_file.empty ()) {
425- output_file_partial = output_file + " .partial" ;
426- if (!out.open (output_file_partial, " ab" )) {
450+ if (!out.open (output_file, " ab" )) {
427451 printe (" Failed to open file for writing\n " );
428452
429453 return 1 ;
@@ -437,37 +461,18 @@ class HttpClient {
437461 }
438462
439463 set_write_options (response_str, out);
440- data.file_size = set_resume_point (output_file_partial );
464+ data.file_size = set_resume_point (output_file );
441465 set_progress_options (progress, data);
442466 set_headers (headers);
443467 CURLcode res = perform (url);
444468 if (res != CURLE_OK){
445469 printe (" Fetching resource '%s' failed: %s\n " , url.c_str (), curl_easy_strerror (res));
446470 return 1 ;
447471 }
448- if (!output_file.empty ()) {
449- // Explicitly close file in order to release lock
450- out.close ();
451- std::filesystem::rename (output_file_partial, output_file);
452- }
453472
454473 return 0 ;
455474 }
456-
457- ~HttpClient () {
458- if (chunk) {
459- curl_slist_free_all (chunk);
460- }
461-
462- if (curl) {
463- curl_easy_cleanup (curl);
464- }
465- }
466-
467- private:
468- CURL * curl = nullptr ;
469- struct curl_slist * chunk = nullptr ;
470-
475+
471476 void set_write_options (std::string * response_str, const File & out) {
472477 if (response_str) {
473478 curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, capture_data);
0 commit comments