diff options
Diffstat (limited to 'utils/nsurl/nsurl.c')
-rw-r--r-- | utils/nsurl/nsurl.c | 212 |
1 files changed, 180 insertions, 32 deletions
diff --git a/utils/nsurl/nsurl.c b/utils/nsurl/nsurl.c index 3b0af9328..63619af15 100644 --- a/utils/nsurl/nsurl.c +++ b/utils/nsurl/nsurl.c @@ -36,6 +36,7 @@ #include <stdlib.h> #include <string.h> #include <strings.h> +#include <inttypes.h> #include "utils/ascii.h" #include "utils/corestrings.h" @@ -54,7 +55,7 @@ * Does nothing if the components are the same, so ensure match is * preset to true. */ -#define nsurl__component_compare(c1, c2, match) \ +#define nsurl__component_compare(c1, c2, match) \ if (c1 && c2 && lwc_error_ok == \ lwc_string_isequal(c1, c2, match)) { \ /* do nothing */ \ @@ -88,10 +89,6 @@ void nsurl_unref(nsurl *url) if (--url->count > 0) return; -#ifdef NSURL_DEBUG - nsurl__dump(url); -#endif - /* Release lwc strings */ nsurl__components_destroy(&url->components); @@ -240,6 +237,15 @@ lwc_string *nsurl_get_component(const nsurl *url, nsurl_component part) /* exported interface, documented in nsurl.h */ +enum nsurl_scheme_type nsurl_get_scheme_type(const nsurl *url) +{ + assert(url != NULL); + + return url->components.scheme_type; +} + + +/* exported interface, documented in nsurl.h */ bool nsurl_has_component(const nsurl *url, nsurl_component part) { assert(url != NULL); @@ -316,6 +322,19 @@ const char *nsurl_access(const nsurl *url) /* exported interface, documented in nsurl.h */ +const char *nsurl_access_log(const nsurl *url) +{ + assert(url != NULL); + + if (url->components.scheme_type == NSURL_SCHEME_DATA) { + return "[data url]"; + } + + return url->string; +} + + +/* exported interface, documented in nsurl.h */ nserror nsurl_get_utf8(const nsurl *url, char **url_s, size_t *url_l) { nserror err; @@ -355,7 +374,7 @@ nserror nsurl_get_utf8(const nsurl *url, char **url_s, size_t *url_l) } *url_l = scheme_len + idna_host_len + path_len + 1; /* +1 for \0 */ - *url_s = malloc(*url_l); + *url_s = malloc(*url_l); if (*url_s == NULL) { err = NSERROR_NOMEM; @@ -565,57 +584,67 @@ nserror nsurl_refragment(const nsurl *url, lwc_string *frag, nsurl **new_url) nserror nsurl_replace_query(const nsurl *url, const char *query, nsurl **new_url) { - int query_len; /* Length of new query string, including '?' */ - int frag_len = 0; /* Length of fragment, including '#' */ - int base_len; /* Length of URL up to start of query */ - char *pos; - size_t len; - lwc_string *lwc_query; + int query_len; /* Length of new query string excluding '?' */ + int frag_len = 0; /* Length of fragment, excluding '#' */ + int base_len; /* Length of URL up to start of query */ + char *pos; /* current position in output string */ + size_t length; /* new url string length */ + lwc_string *lwc_query = NULL; assert(url != NULL); assert(query != NULL); - assert(query[0] == '?'); - /* Get the length of the new query */ - query_len = strlen(query); + length = query_len = strlen(query); + if (query_len > 0) { + length++; /* allow for '?' */ + + /* intern string */ + if (lwc_intern_string(query, + query_len, + &lwc_query) != lwc_error_ok) { + return NSERROR_NOMEM; + } + } /* Find the change in length from url to new_url */ base_len = url->length; if (url->components.query != NULL) { - base_len -= lwc_string_length(url->components.query); + base_len -= (1 + lwc_string_length(url->components.query)); } if (url->components.fragment != NULL) { - frag_len = 1 + lwc_string_length(url->components.fragment); - base_len -= frag_len; + frag_len = lwc_string_length(url->components.fragment); + base_len -= (1 + frag_len); + length += frag_len + 1; /* allow for '#' */ } - /* Set new_url's length */ - len = base_len + query_len + frag_len; + /* compute new url string length */ + length += base_len; /* Create NetSurf URL object */ - *new_url = malloc(sizeof(nsurl) + len + 1); /* Add 1 for \0 */ + *new_url = malloc(sizeof(nsurl) + length + 1); /* Add 1 for \0 */ if (*new_url == NULL) { + if (query_len > 0) { + lwc_string_unref(lwc_query); + } return NSERROR_NOMEM; } - if (lwc_intern_string(query, query_len, &lwc_query) != lwc_error_ok) { - free(*new_url); - return NSERROR_NOMEM; - } - - (*new_url)->length = len; + (*new_url)->length = length; /* Set string */ pos = (*new_url)->string; memcpy(pos, url->string, base_len); pos += base_len; - memcpy(pos, query, query_len); - pos += query_len; + if (query_len > 0) { + *pos = '?'; + memcpy(++pos, query, query_len); + pos += query_len; + } if (url->components.fragment != NULL) { const char *frag = lwc_string_data(url->components.fragment); *pos = '#'; - memcpy(++pos, frag, frag_len - 1); - pos += frag_len - 1; + memcpy(++pos, frag, frag_len); + pos += frag_len; } *pos = '\0'; @@ -648,6 +677,93 @@ nserror nsurl_replace_query(const nsurl *url, const char *query, } +/* exported interface, documented in nsurl.h */ +nserror nsurl_replace_scheme(const nsurl *url, lwc_string *scheme, + nsurl **new_url) +{ + int scheme_len; + int base_len; + char *pos; + size_t len; + bool match; + + assert(url != NULL); + assert(scheme != NULL); + + /* Get the length of the new scheme */ + scheme_len = lwc_string_length(scheme); + + /* Find the change in length from url to new_url */ + base_len = url->length; + if (url->components.scheme != NULL) { + base_len -= lwc_string_length(url->components.scheme); + } + + /* Set new_url's length */ + len = base_len + scheme_len; + + /* Create NetSurf URL object */ + *new_url = malloc(sizeof(nsurl) + len + 1); /* Add 1 for \0 */ + if (*new_url == NULL) { + return NSERROR_NOMEM; + } + + (*new_url)->length = len; + + /* Set string */ + pos = (*new_url)->string; + memcpy(pos, lwc_string_data(scheme), scheme_len); + memcpy(pos + scheme_len, + url->string + url->length - base_len, base_len); + pos[len] = '\0'; + + /* Copy components */ + (*new_url)->components.scheme = lwc_string_ref(scheme); + (*new_url)->components.username = + nsurl__component_copy(url->components.username); + (*new_url)->components.password = + nsurl__component_copy(url->components.password); + (*new_url)->components.host = + nsurl__component_copy(url->components.host); + (*new_url)->components.port = + nsurl__component_copy(url->components.port); + (*new_url)->components.path = + nsurl__component_copy(url->components.path); + (*new_url)->components.query = + nsurl__component_copy(url->components.query); + (*new_url)->components.fragment = + nsurl__component_copy(url->components.fragment); + + /* Compute new scheme type */ + if (lwc_string_caseless_isequal(scheme, corestring_lwc_http, + &match) == lwc_error_ok && match == true) { + (*new_url)->components.scheme_type = NSURL_SCHEME_HTTP; + } else if (lwc_string_caseless_isequal(scheme, corestring_lwc_https, + &match) == lwc_error_ok && match == true) { + (*new_url)->components.scheme_type = NSURL_SCHEME_HTTPS; + } else if (lwc_string_caseless_isequal(scheme, corestring_lwc_file, + &match) == lwc_error_ok && match == true) { + (*new_url)->components.scheme_type = NSURL_SCHEME_FILE; + } else if (lwc_string_caseless_isequal(scheme, corestring_lwc_ftp, + &match) == lwc_error_ok && match == true) { + (*new_url)->components.scheme_type = NSURL_SCHEME_FTP; + } else if (lwc_string_caseless_isequal(scheme, corestring_lwc_mailto, + &match) == lwc_error_ok && match == true) { + (*new_url)->components.scheme_type = NSURL_SCHEME_MAILTO; + } else { + (*new_url)->components.scheme_type = NSURL_SCHEME_OTHER; + } + + /* Get the nsurl's hash */ + nsurl__calc_hash(*new_url); + + /* Give the URL a reference */ + (*new_url)->count = 1; + + return NSERROR_OK; +} + + /* exported interface documented in utils/nsurl.h */ nserror nsurl_nice(const nsurl *url, char **result, bool remove_extensions) { @@ -809,7 +925,7 @@ nserror nsurl_parent(const nsurl *url, nsurl **new_url) } else if (old_path_len == new_path_len) { lwc_path = lwc_string_ref(url->components.path); } else { - if (lwc_intern_string(path, old_path_len - new_path_len, + if (lwc_intern_string(path, new_path_len, &lwc_path) != lwc_error_ok) { free(*new_url); return NSERROR_NOMEM; @@ -850,3 +966,35 @@ nserror nsurl_parent(const nsurl *url, nsurl **new_url) return NSERROR_OK; } +/* exported interface, documented in nsurl.h */ +void nsurl_dump(const nsurl *url) +{ + fprintf(stderr, "nsurl components for %p " + "(refs: %i hash: %"PRIx32"):\n", + url, url->count, url->hash); + + if (url->components.scheme) + fprintf(stderr, " Scheme: %s\n", + lwc_string_data(url->components.scheme)); + if (url->components.username) + fprintf(stderr, "Username: %s\n", + lwc_string_data(url->components.username)); + if (url->components.password) + fprintf(stderr, "Password: %s\n", + lwc_string_data(url->components.password)); + if (url->components.host) + fprintf(stderr, " Host: %s\n", + lwc_string_data(url->components.host)); + if (url->components.port) + fprintf(stderr, " Port: %s\n", + lwc_string_data(url->components.port)); + if (url->components.path) + fprintf(stderr, " Path: %s\n", + lwc_string_data(url->components.path)); + if (url->components.query) + fprintf(stderr, " Query: %s\n", + lwc_string_data(url->components.query)); + if (url->components.fragment) + fprintf(stderr, "Fragment: %s\n", + lwc_string_data(url->components.fragment)); +} |