Fix duplicate download IDs.

Fixes https://github.com/profanity-im/profanity/issues/1794

Explanation
The problem is the download's identifier. Downloads are given an ID so they can be referenced later when their progress changes. Currently, the download's ID is the download's URL. When you download the same file twice, you have two downloads with the same ID. Download progress updates are shown on the first of both downloads with the same ID.

Solution
Change the download's ID from its URL to a random number. A random ID is generated when get_random_string() is called from cmd_funcs.c. Several other functions are updated to cope with the new ID format.
This commit is contained in:
IsaacM88
2023-03-09 13:16:42 -07:00
parent 4887d21a11
commit d043d53948
12 changed files with 43 additions and 28 deletions

View File

@@ -71,7 +71,7 @@ aesgcm_file_get(void* userdata)
// and tag stored in the URL fragment.
if (omemo_parse_aesgcm_url(aesgcm_dl->url, &https_url, &fragment) != 0) {
cons_show_error("Download failed: Cannot parse URL '%s'.", aesgcm_dl->url);
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->id,
"Download failed: Cannot parse URL '%s'.",
aesgcm_dl->url);
return NULL;
@@ -82,7 +82,7 @@ aesgcm_file_get(void* userdata)
gchar* tmpname = NULL;
gint tmpfd;
if ((tmpfd = g_file_open_tmp("profanity.XXXXXX", &tmpname, NULL)) == -1) {
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->id,
"Downloading '%s' failed: Unable to create "
"temporary ciphertext file for writing "
"(%s).",
@@ -93,7 +93,7 @@ aesgcm_file_get(void* userdata)
// Open the target file for storing the cleartext.
FILE* outfh = fopen(aesgcm_dl->filename, "wb");
if (outfh == NULL) {
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->id,
"Downloading '%s' failed: Unable to open "
"output file at '%s' for writing (%s).",
https_url, aesgcm_dl->filename,
@@ -106,6 +106,7 @@ aesgcm_file_get(void* userdata)
HTTPDownload* http_dl = malloc(sizeof(HTTPDownload));
http_dl->window = aesgcm_dl->window;
http_dl->worker = aesgcm_dl->worker;
http_dl->id = strdup(aesgcm_dl->id);
http_dl->url = strdup(https_url);
http_dl->filename = strdup(tmpname);
http_dl->cmd_template = NULL;
@@ -115,7 +116,7 @@ aesgcm_file_get(void* userdata)
FILE* tmpfh = fopen(tmpname, "rb");
if (tmpfh == NULL) {
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->id,
"Downloading '%s' failed: Unable to open "
"temporary file at '%s' for reading (%s).",
aesgcm_dl->url, tmpname,
@@ -136,7 +137,7 @@ aesgcm_file_get(void* userdata)
g_free(tmpname);
if (crypt_res != GPG_ERR_NO_ERROR) {
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->id,
"Downloading '%s' failed: Failed to decrypt "
"file (%s).",
https_url, gcry_strerror(crypt_res));
@@ -156,7 +157,7 @@ aesgcm_file_get(void* userdata)
// TODO: Log the error.
if (!call_external(argv)) {
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->id,
"Downloading '%s' failed: Unable to call "
"command '%s' with file at '%s' (%s).",
aesgcm_dl->url,
@@ -169,6 +170,7 @@ aesgcm_file_get(void* userdata)
free(aesgcm_dl->cmd_template);
}
free(aesgcm_dl->id);
free(aesgcm_dl->filename);
free(aesgcm_dl->url);
free(aesgcm_dl);

View File

@@ -50,6 +50,7 @@
typedef struct aesgcm_download_t
{
char* id;
char* url;
char* filename;
char* cmd_template;

View File

@@ -45,7 +45,7 @@
#define FALLBACK_MSG ""
void
http_print_transfer_update(ProfWin* window, char* url, const char* fmt, ...)
http_print_transfer_update(ProfWin* window, char* id, const char* fmt, ...)
{
va_list args;
@@ -54,13 +54,13 @@ http_print_transfer_update(ProfWin* window, char* url, const char* fmt, ...)
g_string_vprintf(msg, fmt, args);
va_end(args);
win_update_entry_message(window, url, msg->str);
win_update_entry_message(window, id, msg->str);
g_string_free(msg, TRUE);
}
void
http_print_transfer(ProfWin* window, char* url, const char* fmt, ...)
http_print_transfer(ProfWin* window, char* id, const char* fmt, ...)
{
va_list args;
@@ -69,7 +69,7 @@ http_print_transfer(ProfWin* window, char* url, const char* fmt, ...)
g_string_vprintf(msg, fmt, args);
va_end(args);
win_print_http_transfer(window, msg->str, url);
win_print_http_transfer(window, msg->str, id);
g_string_free(msg, TRUE);
}

View File

@@ -38,7 +38,7 @@
#include "ui/window.h"
void http_print_transfer(ProfWin* window, char* url, const char* fmt, ...);
void http_print_transfer_update(ProfWin* window, char* url, const char* fmt, ...);
void http_print_transfer(ProfWin* window, char* id, const char* fmt, ...);
void http_print_transfer_update(ProfWin* window, char* id, const char* fmt, ...);
#endif

View File

@@ -112,12 +112,12 @@ http_file_get(void* userdata)
download->bytes_received = 0;
pthread_mutex_lock(&lock);
http_print_transfer(download->window, download->url,
http_print_transfer(download->window, download->id,
"Downloading '%s': 0%%", download->url);
FILE* outfh = fopen(download->filename, "wb");
if (outfh == NULL) {
http_print_transfer_update(download->window, download->url,
http_print_transfer_update(download->window, download->id,
"Downloading '%s' failed: Unable to open "
"output file at '%s' for writing (%s).",
download->url, download->filename,
@@ -177,22 +177,22 @@ http_file_get(void* userdata)
g_free(cert_path);
if (err) {
if (download->cancel) {
http_print_transfer_update(download->window, download->url,
http_print_transfer_update(download->window, download->id,
"Downloading '%s' failed: "
"Download was canceled",
download->url);
} else {
http_print_transfer_update(download->window, download->url,
http_print_transfer_update(download->window, download->id,
"Downloading '%s' failed: %s",
download->url, err);
}
free(err);
} else {
if (!download->cancel) {
http_print_transfer_update(download->window, download->url,
http_print_transfer_update(download->window, download->id,
"Downloading '%s': done\nSaved to '%s'",
download->url, download->filename);
win_mark_received(download->window, download->url);
win_mark_received(download->window, download->id);
}
}
@@ -203,7 +203,7 @@ http_file_get(void* userdata)
// TODO: Log the error.
if (!call_external(argv)) {
http_print_transfer_update(download->window, download->url,
http_print_transfer_update(download->window, download->id,
"Downloading '%s' failed: Unable to call "
"command '%s' with file at '%s' (%s).",
download->url,
@@ -221,6 +221,7 @@ out:
download_processes = g_slist_remove(download_processes, download);
pthread_mutex_unlock(&lock);
free(download->id);
free(download->url);
free(download->filename);
free(download);

View File

@@ -49,6 +49,7 @@
typedef struct http_download_t
{
char* id;
char* url;
char* filename;
char* cmd_template;