From: Michael Tremer Date: Fri, 12 Mar 2021 10:12:38 +0000 (+0000) Subject: downloader: Handle download errors X-Git-Tag: 0.9.28~1285^2~557 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=88be1b278da9b2a077ce300f312a6a22464f8ff4;p=pakfire.git downloader: Handle download errors Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/downloader.c b/src/libpakfire/downloader.c index b9ed4b41d..1e6c0c297 100644 --- a/src/libpakfire/downloader.c +++ b/src/libpakfire/downloader.c @@ -345,15 +345,58 @@ static const char* curl_http_version(long v) { return "unknown"; } +static int pakfire_transfer_save(struct pakfire_downloader* downloader, + struct pakfire_transfer* transfer) { + struct utimbuf times; + + // Remove destination (if it exists) + unlink(transfer->path); + + // Move the temporary file to its destination + int r = link(transfer->tempfile, transfer->path); + if (r) { + ERROR(downloader->pakfire, "Could not link destination file %s: %s\n", + transfer->path, strerror(errno)); + return r; + } + + // Filetime + curl_easy_getinfo(transfer->handle, CURLINFO_FILETIME_T, ×.modtime); + r = utime(transfer->path, ×); + if (r) { + ERROR(downloader->pakfire, "Could not set mtime of %s: %s\n", + transfer->path, strerror(errno)); + } + + return 0; +} + +static int pakfire_transfer_fail(struct pakfire_downloader* downloader, + struct pakfire_transfer* transfer) { + int r; + + DEBUG(downloader->pakfire, "Transfer failed\n"); + + // Get file descriptor + int fd = fileno(transfer->f); + + // Truncate downloaded data + r = ftruncate(fd, 0); + if (r) + return r; + + return 0; +} + static int pakfire_transfer_done(struct pakfire_downloader* downloader, struct pakfire_transfer* transfer, CURLMsg* msg) { CURL* h = transfer->handle; int r; + long protocol; const char* url; long response_code; long http_version; - struct utimbuf times; double total_time; curl_off_t download_size; curl_off_t speed; @@ -361,6 +404,9 @@ static int pakfire_transfer_done(struct pakfire_downloader* downloader, DEBUG(downloader->pakfire, "cURL transfer done: %d - %s\n", msg->data.result, curl_easy_strerror(msg->data.result)); + // Protocol + curl_easy_getinfo(h, CURLINFO_PROTOCOL, &protocol); + // Effective URL curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &url); if (url) @@ -390,25 +436,36 @@ static int pakfire_transfer_done(struct pakfire_downloader* downloader, if (speed) DEBUG(downloader->pakfire, " Download Speed: %ld bps\n", speed); - // Remove destination (if it exists) - unlink(transfer->path); - - // Move the temporary file to its destination - r = link(transfer->tempfile, transfer->path); - if (r) { - ERROR(downloader->pakfire, "Could not link destination file %s: %s\n", - transfer->path, strerror(errno)); - return r; - } + switch (protocol) { + case CURLPROTO_FILE: + r = pakfire_transfer_save(downloader, transfer); + if (r) + return r; + break; - // Filetime - curl_easy_getinfo(h, CURLINFO_FILETIME_T, ×.modtime); - r = utime(transfer->path, ×); - if (r) { - ERROR(downloader->pakfire, "Could not set mtime of %s: %s\n", - transfer->path, strerror(errno)); + case CURLPROTO_HTTPS: + case CURLPROTO_HTTP: + switch (response_code) { + // 200 - OK + case 200: + r = pakfire_transfer_save(downloader, transfer); + if (r) + return r; + break; + + // Treat all other response codes as an error + default: + r = pakfire_transfer_fail(downloader, transfer); + if (r) + return r; + + // Error + return 1; + } + break; } + // Success return 0; } @@ -452,6 +509,7 @@ int pakfire_downloader_run(struct pakfire_downloader* downloader) { int r; int still_running; int msgs_left = -1; + int success = 0; do { // Make sure that we have up to parallel transfers active @@ -480,7 +538,9 @@ int pakfire_downloader_run(struct pakfire_downloader* downloader) { curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &transfer); // Handle whatever comes after the transfer - pakfire_transfer_done(downloader, transfer, msg); + r = pakfire_transfer_done(downloader, transfer, msg); + if (r) + success = r; // Remove and destroy the handle curl_multi_remove_handle(downloader->curl, transfer->handle); @@ -498,5 +558,5 @@ int pakfire_downloader_run(struct pakfire_downloader* downloader) { } while (still_running || !TAILQ_EMPTY(&downloader->transfers)); // Success - return 0; + return success; }