diff options
Diffstat (limited to 'content/fetch.c')
-rw-r--r-- | content/fetch.c | 136 |
1 files changed, 77 insertions, 59 deletions
diff --git a/content/fetch.c b/content/fetch.c index 766502941..1fcc3f996 100644 --- a/content/fetch.c +++ b/content/fetch.c @@ -53,10 +53,10 @@ #include "content/fetch.h" #include "content/fetchers.h" #include "content/fetchers/resource.h" -#include "content/fetchers/about.h" +#include "content/fetchers/about/about.h" #include "content/fetchers/curl.h" #include "content/fetchers/data.h" -#include "content/fetchers/file.h" +#include "content/fetchers/file/file.h" #include "javascript/fetcher.h" #include "content/urldb.h" @@ -90,7 +90,6 @@ struct fetch { fetch_callback callback;/**< Callback function. */ 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 *host; /**< Host part of URL, interned */ @@ -98,6 +97,7 @@ struct fetch { int fetcherd; /**< Fetcher descriptor for this fetch */ void *fetcher_handle; /**< The handle for the fetcher. */ bool fetch_is_active; /**< This fetch is active. */ + fetch_msg_type last_msg;/**< The last message sent for this fetch */ struct fetch *r_prev; /**< Previous active fetch in ::fetch_ring. */ struct fetch *r_next; /**< Next active fetch in ::fetch_ring. */ }; @@ -460,9 +460,8 @@ fetch_start(nsurl *url, { struct fetch *fetch; lwc_string *scheme; - bool match; - fetch = malloc(sizeof (*fetch)); + fetch = calloc(1, sizeof (*fetch)); if (fetch == NULL) { return NSERROR_NOMEM; } @@ -473,8 +472,8 @@ fetch_start(nsurl *url, /* try and obtain a fetcher for this scheme */ fetch->fetcherd = get_fetcher_for_scheme(scheme); + lwc_string_unref(scheme); if (fetch->fetcherd == -1) { - lwc_string_unref(scheme); free(fetch); return NSERROR_NO_FETCH_HANDLER; } @@ -486,58 +485,12 @@ fetch_start(nsurl *url, fetch->url = nsurl_ref(url); fetch->verifiable = verifiable; fetch->p = p; - fetch->http_code = 0; - fetch->r_prev = NULL; - fetch->r_next = NULL; - fetch->referer = NULL; - fetch->send_referer = false; - fetch->fetcher_handle = NULL; - fetch->fetch_is_active = false; fetch->host = nsurl_get_component(url, NSURL_HOST); if (referer != NULL) { - 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 (nsoption_bool(send_referer) && ref_scheme != NULL) { - /* User permits us to send the header - * Only send it if: - * 1) The fetch and referer schemes match - * or 2) The fetch is https and the referer is http - * - * This ensures that referer information is only sent - * across schemes in the special case of an https - * request from a page served over http. The inverse - * (https -> http) should not send the referer (15.1.3) - */ - bool match1; - bool match2; - if (lwc_string_isequal(scheme, ref_scheme, - &match) != lwc_error_ok) { - match = false; - } - if (lwc_string_isequal(scheme, corestring_lwc_https, - &match1) != lwc_error_ok) { - match1 = false; - } - if (lwc_string_isequal(ref_scheme, corestring_lwc_http, - &match2) != lwc_error_ok) { - match2= false; - } - if (match == true || (match1 == true && match2 == true)) - fetch->send_referer = true; - } - if (ref_scheme != NULL) - lwc_string_unref(ref_scheme); } - /* these aren't needed past here */ - lwc_string_unref(scheme); - /* try and set up the fetch */ fetch->fetcher_handle = fetchers[fetch->fetcherd].ops.setup(fetch, url, only_2xx, downgrade_tls, @@ -584,6 +537,7 @@ fetch_start(nsurl *url, void fetch_abort(struct fetch *f) { assert(f); + f->last_msg = FETCH__INTERNAL_ABORTED; NSLOG(fetch, DEBUG, "fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle, nsurl_access(f->url)); @@ -593,6 +547,20 @@ void fetch_abort(struct fetch *f) /* exported interface documented in content/fetch.h */ void fetch_free(struct fetch *f) { + if (f->last_msg < FETCH_MIN_FINISHED_MSG) { + /* We didn't finish, so tell our user that an error occurred */ + fetch_msg msg; + + msg.type = FETCH_ERROR; + msg.data.error = "FetchFailedToFinish"; + + NSLOG(fetch, CRITICAL, + "During the fetch of %s, the fetcher did not finish.", + nsurl_access(f->url)); + + fetch_send_callback(&msg, f); + } + NSLOG(fetch, DEBUG, "Freeing fetch %p, fetcher %p", f, @@ -712,6 +680,23 @@ fetch_multipart_data_clone(const struct fetch_multipart_data *list) return result; } + +/* exported interface documented in content/fetch.h */ +const char * +fetch_multipart_data_find(const struct fetch_multipart_data *list, + const char *name) +{ + while (list != NULL) { + if (strcmp(list->name, name) == 0) { + return list->value; + } + list = list->next; + } + + return NULL; +} + + /* exported interface documented in content/fetch.h */ void fetch_multipart_data_destroy(struct fetch_multipart_data *list) { @@ -730,10 +715,50 @@ void fetch_multipart_data_destroy(struct fetch_multipart_data *list) } } + +/* exported interface documented in content/fetch.h */ +nserror +fetch_multipart_data_new_kv(struct fetch_multipart_data **list, + const char *name, + const char *value) +{ + struct fetch_multipart_data *newdata; + + assert(list); + + newdata = calloc(sizeof(*newdata), 1); + + if (newdata == NULL) { + return NSERROR_NOMEM; + } + + newdata->name = strdup(name); + if (newdata->name == NULL) { + free(newdata); + return NSERROR_NOMEM; + } + + newdata->value = strdup(value); + if (newdata->value == NULL) { + free(newdata->name); + free(newdata); + return NSERROR_NOMEM; + } + + newdata->next = *list; + *list = newdata; + + return NSERROR_OK; +} + + /* exported interface documented in content/fetch.h */ void fetch_send_callback(const fetch_msg *msg, struct fetch *fetch) { + /* Bump the last_msg to the greatest seen msg */ + if (msg->type > fetch->last_msg) + fetch->last_msg = msg->type; fetch->callback(msg, fetch->p); } @@ -773,13 +798,6 @@ void fetch_set_http_code(struct fetch *fetch, long http_code) fetch->http_code = http_code; } -/* exported interface documented in content/fetch.h */ -const char *fetch_get_referer_to_send(struct fetch *fetch) -{ - if (fetch->send_referer) - return nsurl_access(fetch->referer); - return NULL; -} /* exported interface documented in content/fetch.h */ void fetch_set_cookie(struct fetch *fetch, const char *data) |