// 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;
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;
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)
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)
}
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;
}
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);
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
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);