r9631 jmb - in /branches/jmb/new-cache/content: llcache.c llcache.h

netsurf at semichrome.net netsurf at semichrome.net
Tue Oct 13 03:36:48 BST 2009


Author: jmb
Date: Mon Oct 12 21:36:48 2009
New Revision: 9631

URL: http://source.netsurf-browser.org?rev=9631&view=rev
Log:
Handlers for the remaining FETCH_ states.

Modified:
    branches/jmb/new-cache/content/llcache.c
    branches/jmb/new-cache/content/llcache.h

Modified: branches/jmb/new-cache/content/llcache.c
URL: http://source.netsurf-browser.org/branches/jmb/new-cache/content/llcache.c?rev=9631&r1=9630&r2=9631&view=diff
==============================================================================
--- branches/jmb/new-cache/content/llcache.c (original)
+++ branches/jmb/new-cache/content/llcache.c Mon Oct 12 21:36:48 2009
@@ -29,6 +29,7 @@
 
 #include "content/fetch.h"
 #include "content/llcache.h"
+#include "utils/messages.h"
 #include "utils/url.h"
 #include "utils/utils.h"
 
@@ -144,6 +145,7 @@
 		llcache_object *destination, bool deep);
 static nserror llcache_object_fetch(llcache_object *object, uint32_t flags,
 		const char *referer, const llcache_post_data *post);
+static nserror llcache_object_refetch(llcache_object *object);
 
 static nserror llcache_object_new(const char *url, llcache_object **result);
 static nserror llcache_object_destroy(llcache_object *object);
@@ -160,6 +162,8 @@
 static nserror llcache_object_notify_users(llcache_object *object);
 
 static nserror llcache_clean(void);
+
+static nserror llcache_query_handle_response(bool proceed, void *cbpw);
 
 static void llcache_fetch_callback(fetch_msg msg, void *p, const void *data, 
 		unsigned long size);
@@ -175,6 +179,10 @@
 		const char *data, size_t len);
 static nserror llcache_fetch_process_data(llcache_object *object, 
 		const uint8_t *data, size_t len);
+static nserror llcache_fetch_auth(llcache_object *object,
+		const char *realm);
+static nserror llcache_fetch_cert_error(llcache_object *object,
+		const struct ssl_cert_info *certs, size_t num);
 
 
 /******************************************************************************
@@ -644,8 +652,6 @@
 {
 	char *referer_clone;
 	llcache_post_data *post_clone;
-	const char *urlenc = NULL;
-	struct form_successful_control *multipart = NULL;
 
 	referer_clone = strdup(referer);
 	if (referer_clone == NULL)
@@ -657,6 +663,22 @@
 	object->fetch.flags = flags;
 	object->fetch.referer = referer_clone;
 	object->fetch.post = post_clone;
+
+	return llcache_object_refetch(object);
+}
+
+/**
+ * (Re)fetch an object
+ *
+ * \param object  Object to refetch
+ * \return NSERROR_OK on success, appropriate error otherwise
+ *
+ * \pre The fetch parameters in object->fetch must be populated
+ */ 
+nserror llcache_object_refetch(llcache_object *object)
+{
+	const char *urlenc = NULL;
+	struct form_successful_control *multipart = NULL;
 
 	if (object->fetch.post != NULL) {
 		if (object->fetch.post->type == LLCACHE_POST_URL_ENCODED)
@@ -667,9 +689,9 @@
 
 	object->fetch.fetch = fetch_start(object->url, object->fetch.referer,
 			llcache_fetch_callback, object,
-			flags & LLCACHE_RETRIEVE_NO_ERROR_PAGES,
+			object->fetch.flags & LLCACHE_RETRIEVE_NO_ERROR_PAGES,
 			urlenc, multipart,
-			flags & LLCACHE_RETRIEVE_VERIFIABLE,
+			object->fetch.flags & LLCACHE_RETRIEVE_VERIFIABLE,
 			NULL, /** \todo Remove parent from this API */
 			NULL /** \todo Generate cache-control headers */);
 	if (object->fetch.fetch == NULL)
@@ -892,8 +914,10 @@
 				object->source_len > handle->bytes) {
 			/* Emit HAD_DATA event */
 			event.type = LLCACHE_EVENT_HAD_DATA;
-			event.data.buf = object->source_data + handle->bytes;
-			event.data.len = object->source_len - handle->bytes;
+			event.data.data.buf = 
+					object->source_data + handle->bytes;
+			event.data.data.len = 
+					object->source_len - handle->bytes;
 
 			error = handle->cb(handle, &event, handle->pw);
 			if (error != NSERROR_OK)
@@ -970,6 +994,38 @@
 }
 
 /**
+ * Handle a query response
+ *
+ * \param proceed  Whether to proceed with fetch
+ * \param cbpw     Our context for query
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+nserror llcache_query_handle_response(bool proceed, void *cbpw)
+{
+	nserror error;
+	llcache_event event;
+	llcache_object_user *user;
+	llcache_object *object = cbpw;
+
+	/* Refetch, using existing fetch parameters, if client allows us to */
+	if (proceed)
+		return llcache_object_refetch(object);
+
+	/* Inform client(s) that object fetch failed */
+	event.type = LLCACHE_EVENT_ERROR;
+	/** \todo More appropriate error message */
+	event.data.msg = messages_get("FetchFailed");
+
+	for (user = object->users; user != NULL; user = user->next) {
+		error = user->handle.cb(&user->handle, &event, user->handle.pw);
+		if (error != NSERROR_OK)
+			return error;
+	}
+
+	return NSERROR_OK;
+}
+
+/**
  * Handler for fetch events
  *
  * \param msg   Type of fetch event
@@ -982,6 +1038,8 @@
 {
 	nserror error = NSERROR_OK;
 	llcache_object *object = p;
+	llcache_object_user *user;
+	llcache_event event;
 
 	switch (msg) {
 	/* 3xx responses */
@@ -994,22 +1052,14 @@
 		error = llcache_fetch_notmodified(object, &object);
 		break;
 
-	/** \todo Handle the rest of the FETCH_ events */
-
 	/* Normal 2xx state machine */
-	/** \todo Merge FETCH_TYPE and FETCH_HEADER? */
 	case FETCH_HEADER:
 		/* Received a fetch header */
 		object->fetch.state = LLCACHE_FETCH_HEADERS;
 
 		error = llcache_fetch_process_header(object, data, size);
-		break;
 	case FETCH_TYPE:
-		/* Determined MIME type for object */
-		/* This is always emitted after all headers have been received
-		 * and immediately before the first FETCH_DATA event. ::data
-		 * specifies the detected type (defaulted, if no Content-Type
-		 * header) and ::size contains the Content-Length or 0. */
+		/** \todo Purge FETCH_TYPE completely */
 		break;
 	case FETCH_DATA:
 		/* Received some data */
@@ -1025,20 +1075,44 @@
 		llcache_object_cache_update(object);
 		break;
 
-	/* Out-of-band progress information */
+	/* Out-of-band information */
+	case FETCH_ERROR:
+		/* An error occurred while fetching */
+		fetch_abort(object->fetch.fetch);
+		object->fetch.fetch = NULL;
+		/** \todo Ensure this object becomes stale */
+
+		event.type = LLCACHE_EVENT_ERROR;
+		event.data.msg = data;
+
+		for (user = object->users; user != NULL; user = user->next) {
+			error = user->handle.cb(&user->handle, &event,
+					user->handle.pw);
+			if (error != NSERROR_OK)
+				break;
+		}
+		break;
 	case FETCH_PROGRESS:
 		/* Progress update */
+		event.type = LLCACHE_EVENT_PROGRESS;
+		event.data.msg = data;
+
+		for (user = object->users; user != NULL; user = user->next) {
+			error = user->handle.cb(&user->handle, &event, 
+					user->handle.pw);
+			if (error != NSERROR_OK)
+				break;
+		}
 		break;
 
 	/* Events requiring action */
-	case FETCH_ERROR:
-		/* An error occurred while fetching */
-		break;
 	case FETCH_AUTH:
 		/* Need Authentication */
+		error = llcache_fetch_auth(object, data);
 		break;
 	case FETCH_CERT_ERR:
 		/* Something went wrong when validating TLS certificates */
+		error = llcache_fetch_cert_error(object, data, size);
 		break;
 	}
 
@@ -1426,3 +1500,107 @@
 
 	return NSERROR_OK;
 }
+
+/**
+ * Handle an authentication request
+ *
+ * \param object  Object being fetched
+ * \param realm   Authentication realm
+ * \return NSERROR_OK on success, appropriate error otherwise.
+ */
+nserror llcache_fetch_auth(llcache_object *object, const char *realm)
+{
+	nserror error = NSERROR_OK;
+
+	/* Abort fetch for this object */
+	fetch_abort(object->fetch.fetch);
+	object->fetch.fetch = NULL;
+
+	if (query_cb != NULL) {
+		llcache_query query;
+
+		/* Destroy headers */
+		while (object->num_headers > 0) {
+			object->num_headers--;
+
+			free(object->headers[object->num_headers].name);
+			free(object->headers[object->num_headers].value);
+		}
+		free(object->headers);
+		object->headers = NULL;
+
+		/* Emit query for authentication details */
+		query.type = LLCACHE_QUERY_AUTH;
+		query.url = object->url;
+		query.data.auth.realm = realm;
+
+		error = query_cb(&query, query_cb_pw, 
+				llcache_query_handle_response, object);
+	} else {
+		llcache_object_user *user;
+		llcache_event event;
+
+		/* Inform client(s) that object fetch failed */
+		event.type = LLCACHE_EVENT_ERROR;
+		/** \todo More appropriate error message */
+		event.data.msg = messages_get("FetchFailed");
+
+		for (user = object->users; user != NULL; user = user->next) {
+			error = user->handle.cb(&user->handle, &event, 
+					user->handle.pw);
+			if (error != NSERROR_OK)
+				break;
+		}
+	}
+
+	return error;
+}
+
+/**
+ * Handle a TLS certificate verification failure
+ *
+ * \param object  Object being fetched
+ * \param certs   Certificate chain
+ * \param num     Number of certificates in chain
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+nserror llcache_fetch_cert_error(llcache_object *object,
+		const struct ssl_cert_info *certs, size_t num)
+{
+	nserror error = NSERROR_OK;
+
+	/* Abort fetch for this object */
+	fetch_abort(object->fetch.fetch);
+	object->fetch.fetch = NULL;
+
+	if (query_cb != NULL) {
+		llcache_query query;
+
+		/* Emit query for TLS */
+		query.type = LLCACHE_QUERY_SSL;
+		query.url = object->url;
+		query.data.ssl.certs = certs;
+		query.data.ssl.num = num;
+
+		error = query_cb(&query, query_cb_pw,
+				llcache_query_handle_response, object);
+	} else {
+		llcache_object_user *user;
+		llcache_event event;
+
+		/* Inform client(s) that object fetch failed */
+		event.type = LLCACHE_EVENT_ERROR;
+		/** \todo More appropriate error message */
+		event.data.msg = messages_get("FetchFailed");
+
+		for (user = object->users; user != NULL; user = user->next) {
+			error = user->handle.cb(&user->handle, &event, 
+					user->handle.pw);
+			if (error != NSERROR_OK)
+				break;
+		}
+	}
+
+	return error;
+}
+

Modified: branches/jmb/new-cache/content/llcache.h
URL: http://source.netsurf-browser.org/branches/jmb/new-cache/content/llcache.h?rev=9631&r1=9630&r2=9631&view=diff
==============================================================================
--- branches/jmb/new-cache/content/llcache.h (original)
+++ branches/jmb/new-cache/content/llcache.h Mon Oct 12 21:36:48 2009
@@ -55,16 +55,22 @@
 typedef enum {
 	LLCACHE_EVENT_HAD_HEADERS,	/**< Received all headers */
 	LLCACHE_EVENT_HAD_DATA,		/**< Received some data */
-	LLCACHE_EVENT_DONE		/**< Finished fetching data */
+	LLCACHE_EVENT_DONE,		/**< Finished fetching data */
+
+	LLCACHE_EVENT_ERROR,		/**< An error occurred during fetch */
+	LLCACHE_EVENT_PROGRESS,		/**< Fetch progress update */
 } llcache_event_type;
 
 /** Low-level cache events */
 typedef struct {
 	llcache_event_type type;	/**< Type of event */
-	struct {
-		const uint8_t *buf;	/**< Buffer of data */
-		size_t len;		/**< Length of buffer, in bytes */
-	} data;				/**< Received data */
+	union {
+		struct {
+			const uint8_t *buf;	/**< Buffer of data */
+			size_t len;	/**< Length of buffer, in bytes */
+		} data;			/**< Received data */
+		const char *msg;	/**< Error or progress message */
+	} data;				/**< Event data */
 } llcache_event;
 
 /** 




More information about the netsurf-commits mailing list