From: Michael Tremer Date: Wed, 18 Oct 2023 08:51:14 +0000 (+0000) Subject: downloader: Merge URLs using CURLU X-Git-Tag: 0.9.30~1453 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6bcd6292c169c2537fbabe4eb6684f1efbff99d7;p=pakfire.git downloader: Merge URLs using CURLU Signed-off-by: Michael Tremer --- diff --git a/contrib/config/distros/ipfire3.conf b/contrib/config/distros/ipfire3.conf index 1cb527d7d..4d23f79db 100644 --- a/contrib/config/distros/ipfire3.conf +++ b/contrib/config/distros/ipfire3.conf @@ -14,7 +14,7 @@ source_dl = https://source.ipfire.org/source-3.x/ [repo:stable] description = IPFire 3 - stable -baseurl = https://pakfire.ipfire.org/files/repos/ipfire-3/stable/%{arch} +baseurl = https://pakfire.ipfire.org/files/repos/ipfire-3/stable/%{arch}/ key = untrusted comment: IPFire 3 - stable RWTbyeq8zRxmh8VJCRaXtnSlHCKp+tk7+wjNGpJ53jkP5Dz8j8GWxxOt refresh = 6h @@ -22,7 +22,7 @@ refresh = 6h [repo:testing] description = IPFire 3 - testing -baseurl = https://pakfire.ipfire.org/files/repos/ipfire-3/testing/%{arch} +baseurl = https://pakfire.ipfire.org/files/repos/ipfire-3/testing/%{arch}/ key = untrusted comment: IPFire 3 - testing RWRe8hKvJ0Kw4cpDHpmW7eMQ/i5rAYQnOHiqBcYgBGjTrkbrwneCbM7X refresh = 10m diff --git a/src/libpakfire/downloader.c b/src/libpakfire/downloader.c index db6375cb5..e08657c56 100644 --- a/src/libpakfire/downloader.c +++ b/src/libpakfire/downloader.c @@ -58,8 +58,11 @@ struct pakfire_transfer { // cURL handle CURL* handle; - char title[NAME_MAX]; + // URL + CURLU* fullurl; + char url[PATH_MAX]; + char title[NAME_MAX]; char path[PATH_MAX]; enum pakfire_transfer_flags flags; int tries; @@ -104,13 +107,6 @@ struct pakfire_downloader { TAILQ_HEAD(transfers_finished, pakfire_transfer) transfers_finished; }; -#define pakfire_url_join(s, part1, part2) \ - __pakfire_url_join(s, sizeof(s), part1, part2) - -static int __pakfire_url_join(char* s, const size_t length, const char* part1, const char* part2) { - return __pakfire_string_format(s, length, "%s/%s", part1, part2); -} - static int pakfire_downloader_setup_curl(struct pakfire_downloader* downloader) { int r; @@ -150,6 +146,9 @@ static void pakfire_downloader_transfer_free(struct pakfire_transfer* transfer) if (transfer->evp) EVP_MD_CTX_free(transfer->evp); + if (transfer->fullurl) + curl_url_cleanup(transfer->fullurl); + if (transfer->mirror) pakfire_mirror_unref(transfer->mirror); if (transfer->mirrors) @@ -390,6 +389,13 @@ int pakfire_downloader_transfer_create(struct pakfire_transfer** transfer, goto ERROR; } + // Allocate the full URL + t->fullurl = curl_url(); + if (!t->fullurl) { + r = -errno; + goto ERROR; + } + // Setup the transfer r = pakfire_downloader_transfer_setup(downloader, t); if (r) @@ -426,17 +432,18 @@ struct pakfire_transfer* pakfire_downloader_transfer_unref(struct pakfire_transf } const char* pakfire_downloader_transfer_get_title(struct pakfire_transfer* transfer) { - char path[PATH_MAX]; + char title[PATH_MAX]; int r; // Default to the filename if no title is set if (!*transfer->title) { - r = pakfire_path_basename(path, transfer->url); + // Only use the basename + r = pakfire_path_basename(title, transfer->url); if (r) return NULL; // Store the title - r = pakfire_downloader_transfer_set_title(transfer, path); + r = pakfire_downloader_transfer_set_title(transfer, title); if (r) return NULL; } @@ -743,7 +750,7 @@ static int pakfire_transfer_done(struct pakfire_downloader* downloader, char* expected_hexdigest = __pakfire_hexlify(transfer->expected_digest, transfer->expected_digest_length); - CTX_ERROR(downloader->ctx, "Download checksum for %s didn't match:\n", transfer->url); + CTX_ERROR(downloader->ctx, "Download checksum for %s didn't match:\n", url); CTX_ERROR(downloader->ctx, " Expected: %s\n", expected_hexdigest); CTX_ERROR(downloader->ctx, " Computed: %s\n", computed_hexdigest); @@ -898,42 +905,75 @@ static int pakfire_downloader_transfer_prepare_tmpfile(struct pakfire_transfer* return pakfire_string_set(transfer->tempfile, path); } -static int pakfire_downloader_transfer_prepare(struct pakfire_downloader* downloader, - struct pakfire_transfer* transfer, struct pakfire_progress* progress, int flags) { - char url[PATH_MAX]; +static int pakfire_downloader_transfer_prepare_url(struct pakfire_downloader* downloader, + struct pakfire_transfer* transfer) { int r; - // Increment tries - transfer->tries++; - // Simply set absolute URLs if (pakfire_string_is_url(transfer->url)) { - curl_easy_setopt(transfer->handle, CURLOPT_URL, transfer->url); + r = curl_url_set(transfer->fullurl, CURLUPART_URL, transfer->url, 0); + if (r) + goto ERROR; // Join path if we are using mirrors } else if (transfer->mirrors && !pakfire_mirrorlist_empty(transfer->mirrors)) { r = pakfire_transfer_select_mirror(downloader, transfer); if (r) - return r; + goto ERROR; - r = pakfire_url_join(url, pakfire_mirror_get_url(transfer->mirror), transfer->url); + // Set the mirror's base URL first + r = curl_url_set(transfer->fullurl, CURLUPART_URL, + pakfire_mirror_get_url(transfer->mirror), 0); if (r) - return r; + goto ERROR; - curl_easy_setopt(transfer->handle, CURLOPT_URL, url); + // Then append our own part + r = curl_url_set(transfer->fullurl, CURLUPART_URL, transfer->url, 0); + if (r) + goto ERROR; // Use baseurl } else if (*transfer->baseurl) { - r = pakfire_url_join(url, transfer->baseurl, transfer->url); + // Set the base URL first + r = curl_url_set(transfer->fullurl, CURLUPART_URL, transfer->baseurl, 0); if (r) - return r; + goto ERROR; - curl_easy_setopt(transfer->handle, CURLOPT_URL, url); + // Then append our own part + r = curl_url_set(transfer->fullurl, CURLUPART_URL, transfer->url, 0); + if (r) + goto ERROR; // Fail if we could not set the URL } else { CTX_ERROR(downloader->ctx, "Invalid transfer %s\n", transfer->url); - return -EINVAL; + r = -EINVAL; + goto ERROR; + } + + // Set the URL + r = curl_easy_setopt(transfer->handle, CURLOPT_CURLU, transfer->fullurl); + if (r) { + CTX_ERROR(downloader->ctx, "Could not set the URL: %s\n", curl_easy_strerror(r)); + goto ERROR; + } + +ERROR: + return r; +} + +static int pakfire_downloader_transfer_prepare(struct pakfire_downloader* downloader, + struct pakfire_transfer* transfer, struct pakfire_progress* progress, int flags) { + int r; + + // Increment tries + transfer->tries++; + + // Compose the URL + r = pakfire_downloader_transfer_prepare_url(downloader, transfer); + if (r) { + CTX_ERROR(transfer->ctx, "Could not compose URL: %m\n"); + return r; } // If we do not have an output file, we will create a temporary file @@ -1000,8 +1040,11 @@ int pakfire_downloader_transfer_run(struct pakfire_transfer* transfer, int flags AGAIN: // Prepare the transfer r = pakfire_downloader_transfer_prepare(downloader, transfer, NULL, flags); - if (r) + if (r) { + CTX_ERROR(transfer->ctx, "Could not prepare transfer %s: %s\n", + transfer->url, strerror(-r)); return r; + } // Perform the action r = curl_easy_perform(transfer->handle);