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....
==============================================================================
--- 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....
==============================================================================
--- 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;
/**