From e1f7a37f157686aba073296c3458875b839577b5 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Tue, 27 Sep 2011 11:07:32 +0000 Subject: Port fetch layer to nsurl. Remove unused fetch_get_referer function. svn path=/trunk/netsurf/; revision=12899 --- Makefile.sources | 2 +- content/fetch.c | 170 ++++++++++++++++++++++++------------------------------ content/fetch.h | 6 +- content/llcache.c | 48 ++++++++++++++- utils/ring.h | 8 +-- 5 files changed, 128 insertions(+), 106 deletions(-) diff --git a/Makefile.sources b/Makefile.sources index 6dcf106b6..0aaaa1612 100644 --- a/Makefile.sources +++ b/Makefile.sources @@ -16,7 +16,7 @@ S_RENDER := box.c box_construct.c box_normalise.c \ hubbub_binding.c imagemap.c layout.c list.c search.c table.c \ textinput.c textplain.c -S_UTILS := base64.c filename.c hashtable.c locale.c messages.c \ +S_UTILS := base64.c filename.c hashtable.c locale.c messages.c nsurl.c \ talloc.c url.c utf8.c utils.c useragent.c filepath.c log.c S_HTTP := challenge.c generics.c primitives.c parameter.c \ diff --git a/content/fetch.c b/content/fetch.c index 820e3cd56..ffabd6799 100644 --- a/content/fetch.c +++ b/content/fetch.c @@ -48,7 +48,7 @@ #include "desktop/options.h" #include "utils/log.h" #include "utils/messages.h" -#include "utils/url.h" +#include "utils/nsurl.h" #include "utils/utils.h" #include "utils/ring.h" @@ -76,12 +76,12 @@ static scheme_fetcher *fetchers = NULL; /** Information for a single fetch. */ struct fetch { fetch_callback callback;/**< Callback function. */ - char *url; /**< URL. */ - char *referer; /**< Referer URL. */ + nsurl *url; /**< URL. */ + nsurl *referer; /**< Referer URL. */ bool send_referer; /**< Valid to send the referer */ bool verifiable; /**< Transaction is verifiable */ void *p; /**< Private data for callback. */ - lwc_string *lwc_host; /**< Host part of URL, interned */ + lwc_string *host; /**< Host part of URL, interned */ long http_code; /**< HTTP response code, or 0. */ scheme_fetcher *ops; /**< Fetcher operations for this fetch, NULL if not set. */ @@ -100,6 +100,10 @@ static void fetch_dispatch_jobs(void); static bool fetch_choose_and_dispatch(void); static bool fetch_dispatch_job(struct fetch *fetch); +/* Static lwc_strings */ +static lwc_string *fetch_http_lwc; +static lwc_string *fetch_https_lwc; + /** * Initialise the fetcher. @@ -115,6 +119,18 @@ void fetch_init(void) fetch_resource_register(); fetch_about_register(); fetch_active = false; + + if (lwc_intern_string("http", SLEN("http"), &fetch_http_lwc) != + lwc_error_ok) { + die("Failed to initialise the fetch module " + "(couldn't intern \"http\")."); + } + + if (lwc_intern_string("https", SLEN("https"), &fetch_https_lwc) != + lwc_error_ok) { + die("Failed to initialise the fetch module " + "(couldn't intern \"https\")."); + } } @@ -135,6 +151,9 @@ void fetch_quit(void) } fetch_unref_fetcher(fetchers); } + + lwc_string_unref(fetch_http_lwc); + lwc_string_unref(fetch_https_lwc); } @@ -211,56 +230,33 @@ void fetch_unref_fetcher(scheme_fetcher *fetcher) * */ -struct fetch * fetch_start(const char *url, const char *referer, +struct fetch * fetch_start(nsurl *url, nsurl *referer, fetch_callback callback, void *p, bool only_2xx, const char *post_urlenc, const struct fetch_multipart_data *post_multipart, bool verifiable, const char *headers[]) { - char *host; struct fetch *fetch; - url_func_result res; - char *scheme = NULL, *ref_scheme = NULL; scheme_fetcher *fetcher = fetchers; + lwc_string *scheme; + bool match; fetch = malloc(sizeof (*fetch)); if (fetch == NULL) return NULL; - res = url_host(url, &host); - if (res != URL_FUNC_OK) { - /* we only fail memory exhaustion */ - if (res == URL_FUNC_NOMEM) - goto failed; - - host = strdup(""); - if (host == NULL) - goto failed; - } - /* The URL we're fetching must have a scheme */ - res = url_scheme(url, &scheme); - if (res != URL_FUNC_OK) + scheme = nsurl_get_component(url, NSURL_SCHEME); + if (scheme == NULL) goto failed; - if (referer) { - res = url_scheme(referer, &ref_scheme); - if (res != URL_FUNC_OK) { - /* we only fail memory exhaustion */ - if (res == URL_FUNC_NOMEM) - goto failed; - - ref_scheme = NULL; - } - } - #ifdef DEBUG_FETCH_VERBOSE - LOG(("fetch %p, url '%s'", fetch, url)); + LOG(("fetch %p, url '%s'", fetch, nsurl_access(url))); #endif /* construct a new fetch structure */ fetch->callback = callback; - fetch->url = strdup(url); + fetch->url = nsurl_ref(url); fetch->verifiable = verifiable; fetch->p = p; fetch->http_code = 0; @@ -271,15 +267,14 @@ struct fetch * fetch_start(const char *url, const char *referer, fetch->fetcher_handle = NULL; fetch->ops = NULL; fetch->fetch_is_active = false; - fetch->lwc_host = NULL; - - if (lwc_intern_string(host, strlen(host), &fetch->lwc_host) != lwc_error_ok) - goto failed; + fetch->host = nsurl_get_component(url, NSURL_HOST); if (referer != NULL) { - fetch->referer = strdup(referer); - if (fetch->referer == NULL) - goto failed; + lwc_string *ref_scheme; + fetch->referer = nsurl_ref(referer); + + ref_scheme = nsurl_get_component(referer, NSURL_SCHEME); + /* Not a problem if referer has no scheme */ /* Determine whether to send the Referer header */ if (option_send_referer && ref_scheme != NULL) { @@ -293,11 +288,16 @@ struct fetch * fetch_start(const char *url, const char *referer, * request from a page served over http. The inverse * (https -> http) should not send the referer (15.1.3) */ - if (strcasecmp(scheme, ref_scheme) == 0 || - (strcasecmp(scheme, "https") == 0 && - strcasecmp(ref_scheme, "http") == 0)) + bool match1; + bool match2; + lwc_string_isequal(scheme, ref_scheme, &match); + lwc_string_isequal(scheme, fetch_https_lwc, &match1); + lwc_string_isequal(ref_scheme, fetch_http_lwc, &match2); + if (match == true || (match1 == true && match2 == true)) fetch->send_referer = true; } + if (ref_scheme != NULL) + lwc_string_unref(ref_scheme); } if (fetch->url == NULL) @@ -305,8 +305,8 @@ struct fetch * fetch_start(const char *url, const char *referer, /* Pick the scheme ops */ while (fetcher) { - if (strcmp(lwc_string_data(fetcher->scheme_name), - scheme) == 0) { + lwc_string_isequal(fetcher->scheme_name, scheme, &match); + if (match == true) { fetch->ops = fetcher; break; } @@ -318,7 +318,8 @@ struct fetch * fetch_start(const char *url, const char *referer, /* Got a scheme fetcher, try and set up the fetch */ fetch->fetcher_handle = - fetch->ops->setup_fetch(fetch, url, only_2xx, post_urlenc, + fetch->ops->setup_fetch(fetch, nsurl_access(url), + only_2xx, post_urlenc, post_multipart, headers); if (fetch->fetcher_handle == NULL) @@ -328,9 +329,7 @@ struct fetch * fetch_start(const char *url, const char *referer, fetch_ref_fetcher(fetch->ops); /* these aren't needed past here */ - free(scheme); - free(host); - free(ref_scheme); + lwc_string_unref(scheme); /* Dump us in the queue and ask the queue to run. */ RING_INSERT(queue_ring, fetch); @@ -339,13 +338,16 @@ struct fetch * fetch_start(const char *url, const char *referer, return fetch; failed: - free(host); - free(ref_scheme); - free(scheme); - free(fetch->url); - free(fetch->referer); - if (fetch->lwc_host != NULL) - lwc_string_unref(fetch->lwc_host); + if (scheme != NULL) + lwc_string_unref(scheme); + + if (fetch->host != NULL) + lwc_string_unref(fetch->host); + if (fetch->url != NULL) + nsurl_unref(fetch->url); + if (fetch->referer != NULL) + nsurl_unref(fetch->referer); + free(fetch); return NULL; @@ -422,7 +424,7 @@ bool fetch_choose_and_dispatch(void) */ int countbyhost; RING_COUNTBYLWCHOST(struct fetch, fetch_ring, countbyhost, - queueitem->lwc_host); + queueitem->host); if (countbyhost < option_max_fetchers_per_host) { /* We can dispatch this item in theory */ return fetch_dispatch_job(queueitem); @@ -441,7 +443,7 @@ bool fetch_dispatch_job(struct fetch *fetch) RING_REMOVE(queue_ring, fetch); #ifdef DEBUG_FETCH_VERBOSE LOG(("Attempting to start fetch %p, fetcher %p, url %s", fetch, - fetch->fetcher_handle, fetch->url)); + fetch->fetcher_handle, nsurl_access(fetch->url))); #endif if (!fetch->ops->start_fetch(fetch->fetcher_handle)) { RING_INSERT(queue_ring, fetch); /* Put it back on the end of the queue */ @@ -462,7 +464,8 @@ void fetch_abort(struct fetch *f) { assert(f); #ifdef DEBUG_FETCH_VERBOSE - LOG(("fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle, f->url)); + LOG(("fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle, + nsurl_access(f->url))); #endif f->ops->abort_fetch(f->fetcher_handle); } @@ -479,11 +482,11 @@ void fetch_free(struct fetch *f) #endif f->ops->free_fetch(f->fetcher_handle); fetch_unref_fetcher(f->ops); - free(f->url); - if (f->referer) - free(f->referer); - if (f->lwc_host != NULL) - lwc_string_unref(f->lwc_host); + nsurl_unref(f->url); + if (f->referer != NULL) + nsurl_unref(f->referer); + if (f->host != NULL) + lwc_string_unref(f->host); free(f); } @@ -520,20 +523,11 @@ void fetch_poll(void) * \return true if the scheme is supported */ -bool fetch_can_fetch(const char *url) +bool fetch_can_fetch(nsurl *url) { - const char *semi; - size_t len; scheme_fetcher *fetcher = fetchers; - lwc_string *scheme; bool match; - - if ((semi = strchr(url, ':')) == NULL) - return false; - len = semi - url; - - if (lwc_intern_string(url, len, &scheme) != lwc_error_ok) - return false; + lwc_string *scheme = nsurl_get_component(url, NSURL_SCHEME); while (fetcher != NULL) { lwc_string_isequal(fetcher->scheme_name, scheme, &match); @@ -573,20 +567,6 @@ long fetch_http_code(struct fetch *fetch) return fetch->http_code; } - -/** - * Get the referer - * - * \param fetch fetch to retrieve referer from - * \return Pointer to referer string, or NULL if none. - */ -const char *fetch_get_referer(struct fetch *fetch) -{ - assert(fetch); - - return fetch->referer; -} - /** * Determine if a fetch was verifiable * @@ -718,11 +698,10 @@ fetch_set_http_code(struct fetch *fetch, long http_code) fetch->http_code = http_code; } -const char * -fetch_get_referer_to_send(struct fetch *fetch) +const char *fetch_get_referer_to_send(struct fetch *fetch) { if (fetch->send_referer) - return fetch->referer; + return nsurl_access(fetch->referer); return NULL; } @@ -738,7 +717,7 @@ fetch_set_cookie(struct fetch *fetch, const char *data) /* If the transaction's verifiable, we don't require * that the request uri and the parent domain match, * so don't pass in any referer/parent in this case. */ - urldb_set_cookie(data, fetch->url, NULL); + urldb_set_cookie(data, nsurl_access(fetch->url), NULL); } else if (fetch->referer != NULL) { /* Permit the cookie to be set if the fetch is unverifiable * and the fetch URI domain matches the referer. */ @@ -747,7 +726,8 @@ fetch_set_cookie(struct fetch *fetch, const char *data) * where a nested object requests a fetch, the origin URI * is the nested object's parent URI, whereas the referer * for the fetch will be the nested object's URI. */ - urldb_set_cookie(data, fetch->url, fetch->referer); + urldb_set_cookie(data, nsurl_access(fetch->url), + nsurl_access(fetch->referer)); } } diff --git a/content/fetch.h b/content/fetch.h index 33378a0a9..66a0f4a44 100644 --- a/content/fetch.h +++ b/content/fetch.h @@ -28,6 +28,7 @@ #include #include "utils/config.h" +#include "utils/nsurl.h" typedef enum { FETCH_PROGRESS, @@ -84,7 +85,7 @@ typedef void (*fetch_callback)(fetch_msg msg, void *p, const void *data, void fetch_init(void); -struct fetch * fetch_start(const char *url, const char *referer, +struct fetch * fetch_start(nsurl *url, nsurl *referer, fetch_callback callback, void *p, bool only_2xx, const char *post_urlenc, const struct fetch_multipart_data *post_multipart, @@ -95,12 +96,11 @@ void fetch_poll(void); void fetch_quit(void); const char *fetch_filetype(const char *unix_path); char *fetch_mimetype(const char *ro_path); -bool fetch_can_fetch(const char *url); +bool fetch_can_fetch(nsurl *url); void fetch_change_callback(struct fetch *fetch, fetch_callback callback, void *p); long fetch_http_code(struct fetch *fetch); -const char *fetch_get_referer(struct fetch *fetch); bool fetch_get_verifiable(struct fetch *fetch); void fetch_multipart_data_destroy(struct fetch_multipart_data *list); diff --git a/content/llcache.c b/content/llcache.c index d4a6c9168..afa2702b9 100644 --- a/content/llcache.c +++ b/content/llcache.c @@ -351,11 +351,20 @@ nserror llcache_handle_retrieve(const char *url, uint32_t flags, nserror error; llcache_object_user *user; llcache_object *object; + nsurl *nsurl; + + /* make a nsurl */ + error = nsurl_create(url, &nsurl); + if (error != NSERROR_OK) + return error; /* Can we fetch this URL at all? */ - if (fetch_can_fetch(url) == false) + if (fetch_can_fetch(nsurl) == false) return NSERROR_NO_FETCH_HANDLER; + /* done with nsurl */ + nsurl_unref(nsurl); + /* Create a new object user */ error = llcache_object_user_new(cb, pw, &user); if (error != NSERROR_OK) @@ -1051,6 +1060,8 @@ nserror llcache_object_refetch(llcache_object *object) struct fetch_multipart_data *multipart = NULL; char **headers = NULL; int header_idx = 0; + nsurl*nsurl, *nsurl_ref; + nserror error; if (object->fetch.post != NULL) { if (object->fetch.post->type == LLCACHE_POST_URL_ENCODED) @@ -1109,14 +1120,35 @@ nserror llcache_object_refetch(llcache_object *object) LOG(("Refetching %p", object)); #endif + /* make nsurls */ + error = nsurl_create(object->url, &nsurl); + if (error != NSERROR_OK) { + free(headers); + return error; + } + if (object->fetch.referer != NULL) { + error = nsurl_create(object->fetch.referer, &nsurl_ref); + if (error != NSERROR_OK) { + nsurl_unref(nsurl); + free(headers); + return error; + } + } else { + nsurl_ref = NULL; + } + /* Kick off fetch */ - object->fetch.fetch = fetch_start(object->url, object->fetch.referer, + object->fetch.fetch = fetch_start(nsurl, nsurl_ref, llcache_fetch_callback, object, object->fetch.flags & LLCACHE_RETRIEVE_NO_ERROR_PAGES, urlenc, multipart, object->fetch.flags & LLCACHE_RETRIEVE_VERIFIABLE, (const char **) headers); + nsurl_unref(nsurl); + if (nsurl_ref != NULL) + nsurl_unref(nsurl_ref); + /* Clean up cache-control headers */ while (--header_idx >= 0) free(headers[header_idx]); @@ -2000,6 +2032,7 @@ nserror llcache_fetch_redirect(llcache_object *object, const char *target, url_func_result result; /* Extract HTTP response code from the fetch object */ long http_code = fetch_http_code(object->fetch.fetch); + nsurl *nsurl; /* Abort fetch for this object */ fetch_abort(object->fetch.fetch); @@ -2074,11 +2107,20 @@ nserror llcache_fetch_redirect(llcache_object *object, const char *target, free(scheme); free(object_scheme); + /* make a nsurl */ + error = nsurl_create(url, &nsurl); + if (error != NSERROR_OK) { + free(url); + return error; + } + /* Bail out if we've no way of handling this URL */ - if (fetch_can_fetch(url) == false) { + if (fetch_can_fetch(nsurl) == false) { free(url); + nsurl_unref(nsurl); return NSERROR_OK; } + nsurl_unref(nsurl); if (http_code == 301 || http_code == 302 || http_code == 303) { /* 301, 302, 303 redirects are all unconditional GET requests */ diff --git a/utils/ring.h b/utils/ring.h index 8fab0f9ea..a40f882a2 100644 --- a/utils/ring.h +++ b/utils/ring.h @@ -113,10 +113,10 @@ ringtype *p = ring; \ sizevar = 0; \ do { \ - bool matches = false; \ - if (lwc_string_caseless_isequal(p->lwc_host, \ - lwc_hostname, \ - &matches) == lwc_error_ok) \ + bool matches = false; \ + /* nsurl guarantees lowercase host */ \ + if (lwc_string_isequal(p->host, lwc_hostname, \ + &matches) == lwc_error_ok) \ if (matches) \ sizevar++; \ p = p->r_next; \ -- cgit v1.2.3