diff options
Diffstat (limited to 'content/fetchcache.c')
-rw-r--r-- | content/fetchcache.c | 75 |
1 files changed, 68 insertions, 7 deletions
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, ¶ms); 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> |