From cd7f1eceea81a69e5b4dcdef90d45aab44f8a11f Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 8 May 2014 17:54:44 +0100 Subject: [PATCH] make download_context_get_url() return an nsurl and adapt callers to cope --- atari/download.c | 3 - cocoa/DownloadWindowController.m | 2 +- desktop/download.c | 11 ++- desktop/download.h | 10 ++- gtk/download.c | 25 ++++--- riscos/download.c | 121 +++++++++++++++++-------------- windows/download.c | 11 ++- 7 files changed, 103 insertions(+), 80 deletions(-) diff --git a/atari/download.c b/atari/download.c index dc4b7278a..ffd9f722d 100755 --- a/atari/download.c +++ b/atari/download.c @@ -34,7 +34,6 @@ #include "desktop/textinput.h" #include "desktop/download.h" #include "render/html.h" -#include "utils/url.h" #include "utils/log.h" #include "utils/messages.h" #include "utils/utils.h" @@ -251,7 +250,6 @@ gui_download_window_create(download_context *ctx, struct gui_window *parent) const char *filename; char *destination; char gdos_path[PATH_MAX]; - const char * url; struct gui_download_window * gdw; int dlgres = 0; OBJECT * tree = gemtk_obj_get_tree(DOWNLOAD); @@ -306,7 +304,6 @@ gui_download_window_create(download_context *ctx, struct gui_window *parent) gdw->size_total = download_context_get_total_length(ctx); gdw->destination = destination; gdw->tree = tree; - url = download_context_get_url(ctx); gdw->fd = fopen(gdw->destination, "wb"); if( gdw->fd == NULL ){ diff --git a/cocoa/DownloadWindowController.m b/cocoa/DownloadWindowController.m index c46d7967b..e7b78a4ec 100644 --- a/cocoa/DownloadWindowController.m +++ b/cocoa/DownloadWindowController.m @@ -53,7 +53,7 @@ static void cocoa_register_download( DownloadWindowController *download ); context = ctx; totalSize = download_context_get_total_length( context ); - [self setURL: [NSURL URLWithString: [NSString stringWithUTF8String: download_context_get_url( context )]]]; + [self setURL: [NSURL URLWithString: [NSString stringWithUTF8String: nsurl_access(download_context_get_url( context ))]]]; [self setMIMEType: [NSString stringWithUTF8String: download_context_get_mime_type( context )]]; [self setStartDate: [NSDate date]]; diff --git a/desktop/download.c b/desktop/download.c index cad04779f..0f3fcb6f5 100644 --- a/desktop/download.c +++ b/desktop/download.c @@ -71,11 +71,11 @@ static char *download_parse_filename(const char *filename) * \param url URL of item being fetched * \return Default filename, or NULL on memory exhaustion */ -static char *download_default_filename(const char *url) +static char *download_default_filename(nsurl *url) { char *nice; - if (url_nice(url, &nice, false) == NSERROR_OK) + if (url_nice(nsurl_access(url), &nice, false) == NSERROR_OK) return nice; return NULL; @@ -140,8 +140,7 @@ static nserror download_context_process_headers(download_context *ctx) ctx->total_length = length; if (ctx->filename == NULL) { ctx->filename = download_default_filename( - nsurl_access( - llcache_handle_get_url(ctx->llcache))); + llcache_handle_get_url(ctx->llcache)); } http_content_type_destroy(content_type); @@ -283,9 +282,9 @@ void download_context_abort(download_context *ctx) } /* See download.h for documentation */ -const char *download_context_get_url(const download_context *ctx) +nsurl *download_context_get_url(const download_context *ctx) { - return nsurl_access(llcache_handle_get_url(ctx->llcache)); + return llcache_handle_get_url(ctx->llcache); } /* See download.h for documentation */ diff --git a/desktop/download.h b/desktop/download.h index f53f38b95..4084fa148 100644 --- a/desktop/download.h +++ b/desktop/download.h @@ -67,10 +67,14 @@ void download_context_abort(download_context *ctx); /** * Retrieve the URL for a download * - * \param ctx Context to retrieve URL from - * \return URL string + * The caller is borrowing the url reference from the underlying low + * level cache object. If it is used beyond the immediate scope of the + * caller an additional reference should be made. + * + * \param ctx Context to retrieve URL from + * \return URL object */ -const char *download_context_get_url(const download_context *ctx); +nsurl *download_context_get_url(const download_context *ctx); /** * Retrieve the MIME type for a download diff --git a/gtk/download.c b/gtk/download.c index 2f7250b5f..3a321ec5f 100644 --- a/gtk/download.c +++ b/gtk/download.c @@ -25,7 +25,7 @@ #include "utils/log.h" #include "utils/utils.h" -#include "utils/url.h" +#include "utils/nsurl.h" #include "utils/messages.h" #include "utils/nsoption.h" #include "desktop/download.h" @@ -717,7 +717,7 @@ static void nsgtk_download_store_create_item (struct gui_download_window *dl) static struct gui_download_window * gui_download_window_create(download_context *ctx, struct gui_window *gui) { - const char *url = download_context_get_url(ctx); + nsurl *url = download_context_get_url(ctx); unsigned long total_size = download_context_get_total_length(ctx); gchar *domain; gchar *destination; @@ -730,17 +730,22 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui) nsgtk_scaffolding_window(nsgtk_get_scaffold(gui)); struct gui_download_window *download = malloc(sizeof *download); - if (download == NULL) + if (download == NULL) { return NULL; - - if (url_host(url, &domain) != NSERROR_OK) { - domain = g_strdup(messages_get("gtkUnknownHost")); - if (domain == NULL) { - free(download); - return NULL; - } } + /* set the domain to the host component of the url if it exists */ + if (nsurl_has_component(url, NSURL_HOST)) { + domain = g_strdup(lwc_string_data(nsurl_get_component(url, NSURL_HOST))); + } else { + domain = g_strdup(messages_get("gtkUnknownHost")); + } + if (domain == NULL) { + free(download); + return NULL; + } + + /* show the dialog */ destination = nsgtk_download_dialog_show( download_context_get_filename(ctx), domain, size); if (destination == NULL) { diff --git a/riscos/download.c b/riscos/download.c index 05a2e9ec9..0d15229a9 100644 --- a/riscos/download.c +++ b/riscos/download.c @@ -48,7 +48,7 @@ #include "utils/nsoption.h" #include "utils/log.h" #include "utils/messages.h" -#include "utils/url.h" +#include "utils/nsurl.h" #include "utils/utf8.h" #include "utils/utils.h" @@ -210,6 +210,59 @@ const char *ro_gui_download_temp_name(struct gui_download_window *dw) return temp_name; } +/** + * Try and find the correct RISC OS filetype from a download context. + */ +static nserror download_ro_filetype(download_context *ctx, bits *ftype_out) +{ + nsurl *url = download_context_get_url(ctx); + bits ftype = 0; + lwc_string *scheme; + + /* If the file is local try and read its filetype */ + scheme = nsurl_get_component(url, NSURL_SCHEME); + if (scheme != NULL) { + bool filescheme; + if (lwc_string_isequal(scheme, + corestring_lwc_file, + &filescheme) != lwc_error_ok) { + filescheme = false; + } + + if (filescheme) { + lwc_string *path = nsurl_get_component(url, NSURL_PATH); + if (path != NULL) { + char *raw_path; + raw_path = curl_unescape(path, strlen(path)); + if (raw_path != NULL) { + ftype = ro_filetype_from_unix_path(raw_path); + curl_free(raw_path); + } + } + } + } + + /* If we still don't have a filetype (i.e. failed reading local + * one or fetching a remote object), then use the MIME type. + */ + if (ftype == 0) { + /* convert MIME type to RISC OS file type */ + os_error *error; + const char *mime_type; + + mime_type = download_context_get_mime_type(ctx); + error = xmimemaptranslate_mime_type_to_filetype(mime_type, &ftype); + if (error) { + LOG(("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MiscError", error->errmess); + ftype = 0xffd; + } + } + + *ftype_out = ftype; + return NSERROR_OK; +} /** * Create and open a download progress window. @@ -219,13 +272,11 @@ const char *ro_gui_download_temp_name(struct gui_download_window *dw) * reported */ -static struct gui_download_window *gui_download_window_create(download_context *ctx, - struct gui_window *gui) +static struct gui_download_window * +gui_download_window_create(download_context *ctx, struct gui_window *gui) { - const char *url = download_context_get_url(ctx); - const char *mime_type = download_context_get_mime_type(ctx); + nsurl *url = download_context_get_url(ctx); const char *temp_name; - char *scheme = NULL; char *filename = NULL; struct gui_download_window *dw; bool space_warning = false; @@ -248,8 +299,13 @@ static struct gui_download_window *gui_download_window_create(download_context * dw->query = QUERY_INVALID; dw->received = 0; dw->total_size = download_context_get_total_length(ctx); - strncpy(dw->url, url, sizeof dw->url); + + /** @todo change this to take a reference to the nsurl and use + * that value directly rather than using a fixed buffer. + */ + strncpy(dw->url, nsurl_access(url), sizeof dw->url); dw->url[sizeof dw->url - 1] = 0; + dw->status[0] = 0; gettimeofday(&dw->start_time, 0); dw->last_time = dw->start_time; @@ -258,55 +314,12 @@ static struct gui_download_window *gui_download_window_create(download_context * dw->average_rate = 0; dw->average_points = 0; - /* Get scheme from URL */ - res = url_scheme(url, &scheme); - if (res == NSERROR_NOMEM) { - warn_user("NoMemory", 0); + /* get filetype */ + err = download_ro_filetype(ctx, &dw->file_type); + if (err != NSERROR_OK) { + warn_user(messages_get_errorcode(err), 0); free(dw); return 0; - } else if (res == NSERROR_OK) { - /* If we have a scheme and it's "file", then - * attempt to use the local filetype directly */ - if (strcasecmp(scheme, "file") == 0) { - char *path = NULL; - res = url_path(url, &path); - if (res == NSERROR_NOMEM) { - warn_user("NoMemory", 0); - free(scheme); - free(dw); - return 0; - } else if (res == NSERROR_OK) { - char *raw_path = curl_unescape(path, - strlen(path)); - if (raw_path == NULL) { - warn_user("NoMemory", 0); - free(path); - free(scheme); - free(dw); - return 0; - } - dw->file_type = - ro_filetype_from_unix_path(raw_path); - curl_free(raw_path); - free(path); - } - } - - free(scheme); - } - - /* If we still don't have a filetype (i.e. failed reading local - * one or fetching a remote object), then use the MIME type */ - if (dw->file_type == 0) { - /* convert MIME type to RISC OS file type */ - error = xmimemaptranslate_mime_type_to_filetype(mime_type, - &(dw->file_type)); - if (error) { - LOG(("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MiscError", error->errmess); - dw->file_type = 0xffd; - } } /* open temporary output file */ diff --git a/windows/download.c b/windows/download.c index b721d1fdc..2045864f5 100644 --- a/windows/download.c +++ b/windows/download.c @@ -30,6 +30,7 @@ #include "utils/log.h" #include "utils/messages.h" #include "utils/url.h" +#include "utils/nsurl.h" #include "utils/utils.h" #include "windows/download.h" @@ -64,21 +65,25 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui) } int total_size = download_context_get_total_length(ctx); char *domain, *filename, *destination; - const char *url=download_context_get_url(ctx); + nsurl *url = download_context_get_url(ctx); bool unknown_size = (total_size == 0); const char *size = (unknown_size) ? messages_get("UnknownSize") : human_friendly_bytesize(total_size); - if (url_nice(url, &filename, false) != NSERROR_OK) + if (url_nice(nsurl_access(url), &filename, false) != NSERROR_OK) filename = strdup(messages_get("UnknownFile")); if (filename == NULL) { warn_user(messages_get("NoMemory"), 0); free(w); return NULL; } - if (url_host(url, &domain) != NSERROR_OK) + + if (nsurl_has_component(url, NSURL_HOST)) { + domain = strdup(lwc_string_data(nsurl_get_component(url, NSURL_HOST))); + } else { domain = strdup(messages_get("UnknownHost")); + } if (domain == NULL) { warn_user(messages_get("NoMemory"), 0); free(filename);