summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/content.c12
-rw-r--r--content/content.h3
-rw-r--r--content/fetchcache.c75
-rw-r--r--content/fetchcache.h1
-rw-r--r--content/other.c2
-rw-r--r--content/other.h2
6 files changed, 82 insertions, 13 deletions
diff --git a/content/content.c b/content/content.c
index 280364b9d..a3ff9f777 100644
--- a/content/content.c
+++ b/content/content.c
@@ -57,7 +57,7 @@ static const struct mime_entry mime_map[] = {
/** An entry in handler_map. */
struct handler_entry {
- void (*create)(struct content *c);
+ void (*create)(struct content *c, const char *params[]);
void (*process_data)(struct content *c, char *data, unsigned long size);
int (*convert)(struct content *c, unsigned int width, unsigned int height);
void (*revive)(struct content *c, unsigned int width, unsigned int height);
@@ -169,9 +169,15 @@ struct content * content_create(char *url)
* status is changed to CONTENT_STATUS_LOADING. CONTENT_MSG_LOADING is sent to
* all users. The create function for the type is called to initialise the type
* specific parts of the content structure.
+ *
+ * \param c content structure
+ * \param type content_type to initialise to
+ * \param mime_type MIME-type string for this content
+ * \param params array of strings, ordered attribute, value, attribute, ..., 0
*/
-void content_set_type(struct content *c, content_type type, char* mime_type)
+void content_set_type(struct content *c, content_type type, char* mime_type,
+ const char *params[])
{
assert(c != 0);
assert(c->status == CONTENT_STATUS_TYPE_UNKNOWN);
@@ -180,7 +186,7 @@ void content_set_type(struct content *c, content_type type, char* mime_type)
c->type = type;
c->mime_type = xstrdup(mime_type);
c->status = CONTENT_STATUS_LOADING;
- handler_map[type].create(c);
+ handler_map[type].create(c, params);
content_broadcast(c, CONTENT_MSG_LOADING, 0);
/* c may be destroyed at this point as a result of
* CONTENT_MSG_LOADING, so must not be accessed */
diff --git a/content/content.h b/content/content.h
index 72034b316..2e4a36f31 100644
--- a/content/content.h
+++ b/content/content.h
@@ -139,7 +139,8 @@ struct browser_window;
content_type content_lookup(const char *mime_type);
struct content * content_create(char *url);
-void content_set_type(struct content *c, content_type type, char *mime_type);
+void content_set_type(struct content *c, content_type type, char *mime_type,
+ const char *params[]);
void content_process_data(struct content *c, char *data, unsigned long size);
void content_convert(struct content *c, unsigned long width, unsigned long height);
void content_revive(struct content *c, unsigned long width, unsigned long height);
diff --git a/content/fetchcache.c b/content/fetchcache.c
index 9e89f5876..cc755e73c 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -15,6 +15,8 @@
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
+#include <regex.h>
#include "netsurf/content/cache.h"
#include "netsurf/content/content.h"
#include "netsurf/content/fetchcache.h"
@@ -23,7 +25,9 @@
#include "netsurf/utils/utils.h"
+static regex_t re_content_type;
static void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size);
+static char *fetchcache_parse_type(char *s, char **params[]);
/**
@@ -95,20 +99,21 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
{
struct content *c = p;
content_type type;
- char *mime_type;
- char *semic;
- char *url;
+ char *mime_type, *url;
+ char **params;
+ unsigned int i;
switch (msg) {
case FETCH_TYPE:
c->total_size = size;
- mime_type = xstrdup(data);
- if ((semic = strchr(mime_type, ';')) != 0)
- *semic = 0; /* remove "; charset=..." */
+ mime_type = fetchcache_parse_type(data, &params);
type = content_lookup(mime_type);
LOG(("FETCH_TYPE, type %u", type));
- content_set_type(c, type, mime_type);
+ content_set_type(c, type, mime_type, params);
free(mime_type);
+ for (i = 0; params[i]; i++)
+ free(params[i]);
+ free(params);
break;
case FETCH_DATA:
@@ -172,6 +177,62 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
}
+/**
+ * Initialise the fetchcache module.
+ */
+
+void fetchcache_init(void)
+{
+ regcomp_wrapper(&re_content_type,
+ "^([-0-9a-zA-Z_.]+/[-0-9a-zA-Z_.]+)[ \t]*"
+ "(;[ \t]*([-0-9a-zA-Z_.]+)="
+ "([-0-9a-zA-Z_.]+|\"([^\"]|[\\].)*\")[ \t]*)*$",
+ REG_EXTENDED);
+}
+
+
+/**
+ * Parse a Content-Type header.
+ *
+ * \param s a Content-Type header
+ * \param params updated to point to an array of strings, ordered attribute,
+ * value, attribute, ..., 0
+ * \return a new string containing the MIME-type
+ */
+
+#define MAX_ATTRS 10
+
+char *fetchcache_parse_type(char *s, char **params[])
+{
+ char *type;
+ unsigned int i;
+ int r;
+ regmatch_t pmatch[2 + MAX_ATTRS * 3];
+ *params = xcalloc(MAX_ATTRS * 2 + 2, sizeof (*params)[0]);
+
+ r = regexec(&re_content_type, s, 2 + MAX_ATTRS * 3, pmatch, 0);
+ if (r) {
+ LOG(("failed to parse content-type '%s'", s));
+ return xstrdup(s);
+ }
+
+ type = strndup(s + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so);
+ assert(type);
+
+ /* parameters */
+ for (i = 0; i != MAX_ATTRS && pmatch[2 + 3 * i].rm_so != -1; i++) {
+ (*params)[2 * i] = strndup(s + pmatch[2 + 3 * i + 1].rm_so,
+ pmatch[2 + 3 * i + 1].rm_eo - pmatch[2 + 3 * i + 1].rm_so);
+ (*params)[2 * i + 1] = strndup(s + pmatch[2 + 3 * i + 2].rm_so,
+ pmatch[2 + 3 * i + 2].rm_eo - pmatch[2 + 3 * i + 2].rm_so);
+ assert((*params)[2 * i] && (*params)[2 * i + 1]);
+ }
+ (*params)[2 * i] = 0;
+
+ return type;
+}
+
+
#ifdef TEST
#include <unistd.h>
diff --git a/content/fetchcache.h b/content/fetchcache.h
index 36d40e098..12326970b 100644
--- a/content/fetchcache.h
+++ b/content/fetchcache.h
@@ -26,5 +26,6 @@ struct content * fetchcache(const char *url, char *referer,
void *p1, void *p2, unsigned long width, unsigned long height,
bool only_2xx, char *post_urlenc,
struct form_successful_control *post_multipart, bool cookies);
+void fetchcache_init(void);
#endif
diff --git a/content/other.c b/content/other.c
index a974bd8ed..a4ef7bec7 100644
--- a/content/other.c
+++ b/content/other.c
@@ -17,7 +17,7 @@
#include "netsurf/utils/utils.h"
-void other_create(struct content *c)
+void other_create(struct content *c, char *params[])
{
c->data.other.data = xcalloc(0, 1);
c->data.other.length = 0;
diff --git a/content/other.h b/content/other.h
index 96326a159..71fd4aab4 100644
--- a/content/other.h
+++ b/content/other.h
@@ -24,7 +24,7 @@ struct content_other_data {
unsigned long length; /**< Current length of stored data. */
};
-void other_create(struct content *c);
+void other_create(struct content *c, char *params[]);
void other_process_data(struct content *c, char *data, unsigned long size);
int other_convert(struct content *c, unsigned int width, unsigned int height);
void other_revive(struct content *c, unsigned int width, unsigned int height);