]> git.ipfire.org Git - people/ms/pakfire.git/commitdiff
downloader: Merge URLs using CURLU
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 18 Oct 2023 08:51:14 +0000 (08:51 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 18 Oct 2023 08:51:14 +0000 (08:51 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
contrib/config/distros/ipfire3.conf
src/libpakfire/downloader.c

index 1cb527d7dda493b9a2c959bd2e574c5d10fa1373..4d23f79dbb8abea22995d9d4d6f21759e43890c0 100644 (file)
@@ -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
index db6375cb523d3f386e230289d940d987e4787be8..e08657c562ebc374c996684618b2ca11591492a3 100644 (file)
@@ -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);