summaryrefslogtreecommitdiff
path: root/content/fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'content/fetch.c')
-rw-r--r--content/fetch.c136
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)