summaryrefslogtreecommitdiff
path: root/utils/http
diff options
context:
space:
mode:
Diffstat (limited to 'utils/http')
-rw-r--r--utils/http/challenge.c140
-rw-r--r--utils/http/challenge.h47
-rw-r--r--utils/http/challenge_internal.h27
-rw-r--r--utils/http/content-disposition.c78
-rw-r--r--utils/http/content-disposition.h49
-rw-r--r--utils/http/content-type.c128
-rw-r--r--utils/http/content-type.h49
-rw-r--r--utils/http/generics.c99
-rw-r--r--utils/http/generics.h54
-rw-r--r--utils/http/parameter.c153
-rw-r--r--utils/http/parameter.h59
-rw-r--r--utils/http/parameter_internal.h27
-rw-r--r--utils/http/primitives.c146
-rw-r--r--utils/http/primitives.h32
-rw-r--r--utils/http/www-authenticate.c75
-rw-r--r--utils/http/www-authenticate.h48
16 files changed, 1211 insertions, 0 deletions
diff --git a/utils/http/challenge.c b/utils/http/challenge.c
new file mode 100644
index 000000000..578532e97
--- /dev/null
+++ b/utils/http/challenge.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#include "utils/http.h"
+
+#include "utils/http/challenge_internal.h"
+#include "utils/http/generics.h"
+#include "utils/http/parameter_internal.h"
+#include "utils/http/primitives.h"
+
+/**
+ * Representation of an HTTP challenge
+ */
+struct http_challenge {
+ http__item base;
+
+ lwc_string *scheme; /**< Challenge scheme */
+ http_parameter *params; /**< Challenge parameters */
+};
+
+/**
+ * Destroy an HTTP challenge
+ *
+ * \param self Challenge to destroy
+ */
+static void http_destroy_challenge(http_challenge *self)
+{
+ lwc_string_unref(self->scheme);
+ http_parameter_list_destroy(self->params);
+ free(self);
+}
+
+/**
+ * Parse an HTTP challenge
+ *
+ * \param input Pointer to current input byte. Updated on exit.
+ * \param challenge Pointer to location to receive challenge
+ * \return NSERROR_OK on success,
+ * NSERROR_NOMEM on memory exhaustion,
+ * NSERROR_NOT_FOUND if no parameter could be parsed
+ *
+ * The returned challenge is owned by the caller.
+ */
+nserror http__parse_challenge(const char **input, http_challenge **challenge)
+{
+ const char *pos = *input;
+ http_challenge *result;
+ lwc_string *scheme;
+ http_parameter *first = NULL;
+ http_parameter *params = NULL;
+ nserror error;
+
+ /* challenge = auth-scheme 1*SP 1#auth-param
+ * auth-scheme = token
+ * auth-param = parameter
+ */
+
+ error = http__parse_token(&pos, &scheme);
+ if (error != NSERROR_OK)
+ return error;
+
+ if (*pos != ' ' && *pos != '\t') {
+ lwc_string_unref(scheme);
+ return NSERROR_NOT_FOUND;
+ }
+
+ http__skip_LWS(&pos);
+
+ error = http__parse_parameter(&pos, &first);
+ if (error != NSERROR_OK) {
+ lwc_string_unref(scheme);
+ return error;
+ }
+
+ http__skip_LWS(&pos);
+
+ if (*pos == ',') {
+ error = http__item_list_parse(&pos,
+ http__parse_parameter, first, &params);
+ if (error != NSERROR_OK && error != NSERROR_NOT_FOUND) {
+ lwc_string_unref(scheme);
+ return error;
+ }
+ } else {
+ params = first;
+ }
+
+ result = malloc(sizeof(*result));
+ if (result == NULL) {
+ http_parameter_list_destroy(params);
+ lwc_string_unref(scheme);
+ return NSERROR_NOMEM;
+ }
+
+ HTTP__ITEM_INIT(result, NULL, http_destroy_challenge);
+ result->scheme = scheme;
+ result->params = params;
+
+ *challenge = result;
+ *input = pos;
+
+ return NSERROR_OK;
+}
+
+/* See challenge.h for documentation */
+const http_challenge *http_challenge_list_iterate(const http_challenge *cur,
+ lwc_string **scheme, http_parameter **parameters)
+{
+ if (cur == NULL)
+ return NULL;
+
+ *scheme = lwc_string_ref(cur->scheme);
+ *parameters = cur->params;
+
+ return (http_challenge *) cur->base.next;
+}
+
+/* See challenge.h for documentation */
+void http_challenge_list_destroy(http_challenge *list)
+{
+ http__item_list_destroy(list);
+}
+
diff --git a/utils/http/challenge.h b/utils/http/challenge.h
new file mode 100644
index 000000000..1e34bb3fa
--- /dev/null
+++ b/utils/http/challenge.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_CHALLENGE_H_
+#define NETSURF_UTILS_HTTP_CHALLENGE_H_
+
+#include <libwapcaplet/libwapcaplet.h>
+
+#include "utils/http/parameter.h"
+
+typedef struct http_challenge http_challenge;
+
+/**
+ * Iterate over a challenge list
+ *
+ * \param cur Pointer to current iteration position, list head to start
+ * \param scheme Pointer to location to receive challenge scheme
+ * \param parameters Pointer to location to receive challenge parameters
+ * \return Pointer to next iteration position, or NULL for end of iteration
+ */
+const http_challenge *http_challenge_list_iterate(const http_challenge *cur,
+ lwc_string **scheme, http_parameter **parameters);
+
+/**
+ * Destroy a list of HTTP challenges
+ *
+ * \param list List to destroy
+ */
+void http_challenge_list_destroy(http_challenge *list);
+
+#endif
+
diff --git a/utils/http/challenge_internal.h b/utils/http/challenge_internal.h
new file mode 100644
index 000000000..55027648b
--- /dev/null
+++ b/utils/http/challenge_internal.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_CHALLENGE_INTERNAL_H_
+#define NETSURF_UTILS_HTTP_CHALLENGE_INTERNAL_H_
+
+#include "utils/errors.h"
+#include "utils/http/challenge.h"
+
+nserror http__parse_challenge(const char **input, http_challenge **parameter);
+
+#endif
diff --git a/utils/http/content-disposition.c b/utils/http/content-disposition.c
new file mode 100644
index 000000000..5d5e94c26
--- /dev/null
+++ b/utils/http/content-disposition.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#include "utils/http.h"
+
+#include "utils/http/generics.h"
+#include "utils/http/parameter_internal.h"
+#include "utils/http/primitives.h"
+
+/* See content-disposition.h for documentation */
+nserror http_parse_content_disposition(const char *header_value,
+ http_content_disposition **result)
+{
+ const char *pos = header_value;
+ lwc_string *mtype;
+ http_parameter *params = NULL;
+ http_content_disposition *cd;
+ nserror error;
+
+ /* disposition-type *( ";" parameter ) */
+
+ http__skip_LWS(&pos);
+
+ error = http__parse_token(&pos, &mtype);
+ if (error != NSERROR_OK)
+ return error;
+
+ http__skip_LWS(&pos);
+
+ if (*pos == ';') {
+ error = http__item_list_parse(&pos,
+ http__parse_parameter, NULL, &params);
+ if (error != NSERROR_OK && error != NSERROR_NOT_FOUND) {
+ lwc_string_unref(mtype);
+ return error;
+ }
+ }
+
+ cd = malloc(sizeof(*cd));
+ if (cd == NULL) {
+ http_parameter_list_destroy(params);
+ lwc_string_unref(mtype);
+ return NSERROR_NOMEM;
+ }
+
+ cd->disposition_type = mtype;
+ cd->parameters = params;
+
+ *result = cd;
+
+ return NSERROR_OK;
+}
+
+/* See content-disposition.h for documentation */
+void http_content_disposition_destroy(http_content_disposition *victim)
+{
+ lwc_string_unref(victim->disposition_type);
+ http_parameter_list_destroy(victim->parameters);
+ free(victim);
+}
+
diff --git a/utils/http/content-disposition.h b/utils/http/content-disposition.h
new file mode 100644
index 000000000..ae2b52030
--- /dev/null
+++ b/utils/http/content-disposition.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_CONTENT_DISPOSITION_H_
+#define NETSURF_UTILS_HTTP_CONTENT_DISPOSITION_H_
+
+#include <libwapcaplet/libwapcaplet.h>
+
+#include "utils/http/parameter.h"
+
+typedef struct http_content_disposition {
+ lwc_string *disposition_type;
+ http_parameter *parameters;
+} http_content_disposition;
+
+/**
+ * Parse an HTTP Content-Disposition header value
+ *
+ * \param header_value Header value to parse
+ * \param result Pointer to location to receive result
+ * \return NSERROR_OK on success,
+ * NSERROR_NOMEM on memory exhaustion
+ */
+nserror http_parse_content_disposition(const char *header_value,
+ http_content_disposition **result);
+
+/**
+ * Destroy a content disposition object
+ *
+ * \param victim Object to destroy
+ */
+void http_content_disposition_destroy(http_content_disposition *victim);
+
+#endif
diff --git a/utils/http/content-type.c b/utils/http/content-type.c
new file mode 100644
index 000000000..f84da8c8e
--- /dev/null
+++ b/utils/http/content-type.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils/http.h"
+
+#include "utils/http/generics.h"
+#include "utils/http/parameter_internal.h"
+#include "utils/http/primitives.h"
+
+/* See content-type.h for documentation */
+nserror http_parse_content_type(const char *header_value,
+ http_content_type **result)
+{
+ const char *pos = header_value;
+ lwc_string *type;
+ lwc_string *subtype = NULL;
+ http_parameter *params = NULL;
+ char *mime;
+ size_t mime_len;
+ lwc_string *imime;
+ http_content_type *ct;
+ nserror error;
+
+ /* type "/" subtype *( ";" parameter ) */
+
+ http__skip_LWS(&pos);
+
+ error = http__parse_token(&pos, &type);
+ if (error != NSERROR_OK)
+ return error;
+
+ http__skip_LWS(&pos);
+
+ if (*pos != '/') {
+ lwc_string_unref(type);
+ return NSERROR_NOT_FOUND;
+ }
+
+ pos++;
+
+ http__skip_LWS(&pos);
+
+ error = http__parse_token(&pos, &subtype);
+ if (error != NSERROR_OK) {
+ lwc_string_unref(type);
+ return error;
+ }
+
+ http__skip_LWS(&pos);
+
+ if (*pos == ';') {
+ error = http__item_list_parse(&pos,
+ http__parse_parameter, NULL, &params);
+ if (error != NSERROR_OK && error != NSERROR_NOT_FOUND) {
+ lwc_string_unref(subtype);
+ lwc_string_unref(type);
+ return error;
+ }
+ }
+
+ /* <type> + <subtype> + '/' */
+ mime_len = lwc_string_length(type) + lwc_string_length(subtype) + 1;
+
+ mime = malloc(mime_len + 1);
+ if (mime == NULL) {
+ http_parameter_list_destroy(params);
+ lwc_string_unref(subtype);
+ lwc_string_unref(type);
+ return NSERROR_NOMEM;
+ }
+
+ sprintf(mime, "%.*s/%.*s",
+ (int) lwc_string_length(type), lwc_string_data(type),
+ (int) lwc_string_length(subtype), lwc_string_data(subtype));
+
+ lwc_string_unref(subtype);
+ lwc_string_unref(type);
+
+ if (lwc_intern_string(mime, mime_len, &imime) != lwc_error_ok) {
+ http_parameter_list_destroy(params);
+ free(mime);
+ return NSERROR_NOMEM;
+ }
+
+ free(mime);
+
+ ct = malloc(sizeof(*ct));
+ if (ct == NULL) {
+ lwc_string_unref(imime);
+ http_parameter_list_destroy(params);
+ return NSERROR_NOMEM;
+ }
+
+ ct->media_type = imime;
+ ct->parameters = params;
+
+ *result = ct;
+
+ return NSERROR_OK;
+}
+
+/* See content-type.h for documentation */
+void http_content_type_destroy(http_content_type *victim)
+{
+ lwc_string_unref(victim->media_type);
+ http_parameter_list_destroy(victim->parameters);
+ free(victim);
+}
+
diff --git a/utils/http/content-type.h b/utils/http/content-type.h
new file mode 100644
index 000000000..840871bb7
--- /dev/null
+++ b/utils/http/content-type.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_CONTENT_TYPE_H_
+#define NETSURF_UTILS_HTTP_CONTENT_TYPE_H_
+
+#include <libwapcaplet/libwapcaplet.h>
+
+#include "utils/http/parameter.h"
+
+typedef struct http_content_type {
+ lwc_string *media_type;
+ http_parameter *parameters;
+} http_content_type;
+
+/**
+ * Parse an HTTP Content-Type header value
+ *
+ * \param header_value Header value to parse
+ * \param result Pointer to location to receive result
+ * \return NSERROR_OK on success,
+ * NSERROR_NOMEM on memory exhaustion
+ */
+nserror http_parse_content_type(const char *header_value,
+ http_content_type **result);
+
+/**
+ * Destroy a content type object
+ *
+ * \param victim Object to destroy
+ */
+void http_content_type_destroy(http_content_type *victim);
+
+#endif
diff --git a/utils/http/generics.c b/utils/http/generics.c
new file mode 100644
index 000000000..129a56f69
--- /dev/null
+++ b/utils/http/generics.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#include "utils/http/generics.h"
+#include "utils/http/primitives.h"
+
+/**
+ * Destructor for an item list
+ *
+ * \param list List to destroy
+ */
+void http___item_list_destroy(http__item *list)
+{
+ while (list != NULL) {
+ http__item *victim = list;
+
+ list = victim->next;
+
+ victim->free(victim);
+ }
+}
+
+/**
+ * Parse a list of items
+ *
+ * \param input Pointer to current input byte. Updated on exit.
+ * \param itemparser Pointer to function to parse list items
+ * \param first Pointer to first item, or NULL.
+ * \param parameters Pointer to location to receive on-heap parameter list.
+ * \return NSERROR_OK on success,
+ * NSERROR_NOMEM on memory exhaustion,
+ * NSERROR_NOT_FOUND if no items could be parsed
+ *
+ * The returned list is owned by the caller
+ *
+ * \note Ownership of the \a first item is passed to this function.
+ */
+nserror http___item_list_parse(const char **input,
+ http__itemparser itemparser, http__item *first,
+ http__item **items)
+{
+ const char *pos = *input;
+ const char separator = *pos;
+ http__item *item;
+ http__item *list = first;
+ nserror error = NSERROR_OK;
+
+ /* 1*( <separator> <item> ) */
+
+ while (*pos == separator) {
+ pos++;
+
+ http__skip_LWS(&pos);
+
+ error = itemparser(&pos, &item);
+ if (error == NSERROR_OK) {
+ if (list != NULL)
+ item->next = list;
+
+ list = item;
+
+ http__skip_LWS(&pos);
+ } else if (error != NSERROR_NOT_FOUND) {
+ /* Permit <separator> LWS <separator> */
+ break;
+ }
+ }
+
+ if (error != NSERROR_OK && error != NSERROR_NOT_FOUND) {
+ http__item_list_destroy(list);
+ } else if (list == NULL) {
+ error = NSERROR_NOT_FOUND;
+ } else {
+ error = NSERROR_OK;
+ *items = list;
+ *input = pos;
+ }
+
+ return error;
+}
+
+
diff --git a/utils/http/generics.h b/utils/http/generics.h
new file mode 100644
index 000000000..3fa498a29
--- /dev/null
+++ b/utils/http/generics.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_GENERICS_H_
+#define NETSURF_UTILS_HTTP_GENERICS_H_
+
+#include "utils/errors.h"
+
+/**
+ * Representation of an item
+ */
+typedef struct http__item {
+ struct http__item *next; /**< Next item in list, or NULL */
+
+ void (*free)(struct http__item *self); /**< Item destructor */
+} http__item;
+
+#define HTTP__ITEM_INIT(item, n, f) \
+ ((http__item *) (item))->next = (http__item *) (n); \
+ ((http__item *) (item))->free = (void (*)(http__item *)) (f)
+
+/**
+ * Type of an item parser
+ */
+typedef nserror (*http__itemparser)(const char **input, http__item **item);
+
+
+void http___item_list_destroy(http__item *list);
+#define http__item_list_destroy(l) \
+ http___item_list_destroy((http__item *) (l))
+
+nserror http___item_list_parse(const char **input,
+ http__itemparser itemparser, http__item *first,
+ http__item **items);
+#define http__item_list_parse(i, p, f, r) \
+ http___item_list_parse((i), (http__itemparser) (p), \
+ (http__item *) (f), (http__item **) (r))
+
+#endif
diff --git a/utils/http/parameter.c b/utils/http/parameter.c
new file mode 100644
index 000000000..968879d80
--- /dev/null
+++ b/utils/http/parameter.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils/http.h"
+
+#include "utils/http/generics.h"
+#include "utils/http/parameter_internal.h"
+#include "utils/http/primitives.h"
+
+/**
+ * Representation of an HTTP parameter
+ */
+struct http_parameter {
+ http__item base;
+
+ lwc_string *name; /**< Parameter name */
+ lwc_string *value; /**< Parameter value */
+};
+
+/**
+ * Destructor for an HTTP parameter
+ *
+ * \param self Parameter to destroy
+ */
+static void http_destroy_parameter(http_parameter *self)
+{
+ lwc_string_unref(self->name);
+ lwc_string_unref(self->value);
+ free(self);
+}
+
+/**
+ * Parse an HTTP parameter
+ *
+ * \param input Pointer to current input byte. Updated on exit.
+ * \param parameter Pointer to location to receive on-heap parameter.
+ * \return NSERROR_OK on success,
+ * NSERROR_NOMEM on memory exhaustion,
+ * NSERROR_NOT_FOUND if no parameter could be parsed
+ *
+ * The returned parameter is owned by the caller.
+ */
+nserror http__parse_parameter(const char **input, http_parameter **parameter)
+{
+ const char *pos = *input;
+ lwc_string *name;
+ lwc_string *value;
+ http_parameter *param;
+ nserror error;
+
+ /* token "=" ( token | quoted-string ) */
+
+ error = http__parse_token(&pos, &name);
+ if (error != NSERROR_OK)
+ return error;
+
+ http__skip_LWS(&pos);
+
+ if (*pos != '=') {
+ lwc_string_unref(name);
+ return NSERROR_NOT_FOUND;
+ }
+
+ pos++;
+
+ http__skip_LWS(&pos);
+
+ if (*pos == '"')
+ error = http__parse_quoted_string(&pos, &value);
+ else
+ error = http__parse_token(&pos, &value);
+
+ if (error != NSERROR_OK) {
+ lwc_string_unref(name);
+ return error;
+ }
+
+ param = malloc(sizeof(*param));
+ if (param == NULL) {
+ lwc_string_unref(value);
+ lwc_string_unref(name);
+ return NSERROR_NOMEM;
+ }
+
+ HTTP__ITEM_INIT(param, NULL, http_destroy_parameter);
+ param->name = name;
+ param->value = value;
+
+ *parameter = param;
+ *input = pos;
+
+ return NSERROR_OK;
+}
+
+/* See parameter.h for documentation */
+nserror http_parameter_list_find_item(const http_parameter *list,
+ lwc_string *name, lwc_string **value)
+{
+ bool match;
+
+ while (list != NULL) {
+ if (lwc_string_caseless_isequal(name, list->name,
+ &match) == lwc_error_ok && match)
+ break;
+
+ list = (http_parameter *) list->base.next;
+ }
+
+ if (list == NULL)
+ return NSERROR_NOT_FOUND;
+
+ *value = lwc_string_ref(list->value);
+
+ return NSERROR_OK;
+}
+
+/* See parameter.h for documentation */
+const http_parameter *http_parameter_list_iterate(const http_parameter *cur,
+ lwc_string **name, lwc_string **value)
+{
+ if (cur == NULL)
+ return NULL;
+
+ *name = lwc_string_ref(cur->name);
+ *value = lwc_string_ref(cur->value);
+
+ return (http_parameter *) cur->base.next;
+}
+
+/* See parameter.h for documentation */
+void http_parameter_list_destroy(http_parameter *list)
+{
+ http__item_list_destroy(list);
+}
+
diff --git a/utils/http/parameter.h b/utils/http/parameter.h
new file mode 100644
index 000000000..2f5d41a54
--- /dev/null
+++ b/utils/http/parameter.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_PARAMETER_H_
+#define NETSURF_UTILS_HTTP_PARAMETER_H_
+
+#include <libwapcaplet/libwapcaplet.h>
+
+#include "utils/errors.h"
+
+typedef struct http_parameter http_parameter;
+
+/**
+ * Find a named item in an HTTP parameter list
+ *
+ * \param list List to search
+ * \param name Name of item to search for
+ * \param value Pointer to location to receive value
+ * \return NSERROR_OK on success,
+ * NSERROR_NOT_FOUND if requested item does not exist
+ */
+nserror http_parameter_list_find_item(const http_parameter *list,
+ lwc_string *name, lwc_string **value);
+
+/**
+ * Iterate over a parameter list
+ *
+ * \param cur Pointer to current iteration position, list head to start
+ * \param name Pointer to location to receive item name
+ * \param value Pointer to location to receive item value
+ * \return Pointer to next iteration position, or NULL for end of iteration
+ */
+const http_parameter *http_parameter_list_iterate(const http_parameter *cur,
+ lwc_string **name, lwc_string **value);
+
+/**
+ * Destroy a list of HTTP parameters
+ *
+ * \param list List to destroy
+ */
+void http_parameter_list_destroy(http_parameter *list);
+
+#endif
+
diff --git a/utils/http/parameter_internal.h b/utils/http/parameter_internal.h
new file mode 100644
index 000000000..a3ab0a02f
--- /dev/null
+++ b/utils/http/parameter_internal.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_PARAMETER_INTERNAL_H_
+#define NETSURF_UTILS_HTTP_PARAMETER_INTERNAL_H_
+
+#include "utils/errors.h"
+#include "utils/http/parameter.h"
+
+nserror http__parse_parameter(const char **input, http_parameter **parameter);
+
+#endif
diff --git a/utils/http/primitives.c b/utils/http/primitives.c
new file mode 100644
index 000000000..f4c4e056e
--- /dev/null
+++ b/utils/http/primitives.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils/http/primitives.h"
+
+/**
+ * Skip past linear whitespace in input
+ *
+ * \param input Pointer to current input byte. Updated on exit.
+ */
+void http__skip_LWS(const char **input)
+{
+ const char *pos = *input;
+
+ while (*pos == ' ' || *pos == '\t')
+ pos++;
+
+ *input = pos;
+}
+
+/**
+ * Determine if a character is valid for an HTTP token
+ *
+ * \param c Character to consider
+ * \return True if character is valid, false otherwise
+ */
+static bool http_is_token_char(uint8_t c)
+{
+ /* [ 32 - 126 ] except ()<>@,;:\"/[]?={} SP HT */
+
+ if (c <= ' ' || 126 < c)
+ return false;
+
+ return (strchr("()<>@,;:\\\"/[]?={}", c) == NULL);
+}
+
+/**
+ * Parse an HTTP token
+ *
+ * \param input Pointer to current input byte. Updated on exit.
+ * \param value Pointer to location to receive on-heap token value.
+ * \return NSERROR_OK on success,
+ * NSERROR_NOMEM on memory exhaustion,
+ * NSERROR_NOT_FOUND if no token could be parsed
+ *
+ * The returned value is owned by the caller
+ */
+nserror http__parse_token(const char **input, lwc_string **value)
+{
+ const uint8_t *start = (const uint8_t *) *input;
+ const uint8_t *end;
+ lwc_string *token;
+
+ end = start;
+ while (http_is_token_char(*end))
+ end++;
+
+ if (end == start)
+ return NSERROR_NOT_FOUND;
+
+ if (lwc_intern_string((const char *) start,
+ end - start, &token) != lwc_error_ok)
+ return NSERROR_NOMEM;
+
+ *value = token;
+ *input = (const char *) end;
+
+ return NSERROR_OK;
+}
+
+/**
+ * Parse an HTTP quoted-string
+ *
+ * \param input Pointer to current input byte. Updated on exit.
+ * \param value Pointer to location to receive on-heap string value.
+ * \return NSERROR_OK on success,
+ * NSERROR_NOMEM on memory exhaustion,
+ * NSERROR_NOT_FOUND if no string could be parsed
+ *
+ * The returned value is owned by the caller
+ */
+nserror http__parse_quoted_string(const char **input, lwc_string **value)
+{
+ const uint8_t *start = (const uint8_t *) *input;
+ const uint8_t *end;
+ uint8_t c;
+ lwc_string *string_value;
+
+ /* <"> *( qdtext | quoted-pair ) <">
+ * qdtext = any TEXT except <">
+ * quoted-pair = "\" CHAR
+ * TEXT = [ HT, CR, LF, 32-126, 128-255 ]
+ * CHAR = [ 0 - 127 ]
+ *
+ * \todo TEXT may contain non 8859-1 chars encoded per RFC 2047
+ * \todo Support quoted-pairs
+ */
+
+ if (*start != '"')
+ return NSERROR_NOT_FOUND;
+
+ end = start = start + 1;
+
+ c = *end;
+ while (c == '\t' || c == '\r' || c == '\n' ||
+ c == ' ' || c == '!' ||
+ ('#' <= c && c <= 126) || c > 127) {
+ end++;
+ c = *end;
+ }
+
+ if (*end != '"')
+ return NSERROR_NOT_FOUND;
+
+ if (lwc_intern_string((const char *) start, end - start,
+ &string_value) != lwc_error_ok)
+ return NSERROR_NOMEM;
+
+ *value = string_value;
+
+ *input = (const char *) end + 1;
+
+ return NSERROR_OK;
+}
+
+
diff --git a/utils/http/primitives.h b/utils/http/primitives.h
new file mode 100644
index 000000000..b8b6abbc0
--- /dev/null
+++ b/utils/http/primitives.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_PRIMITIVES_H_
+#define NETSURF_UTILS_HTTP_PRIMITIVES_H_
+
+#include <libwapcaplet/libwapcaplet.h>
+
+#include "utils/errors.h"
+
+void http__skip_LWS(const char **input);
+
+nserror http__parse_token(const char **input, lwc_string **value);
+
+nserror http__parse_quoted_string(const char **input, lwc_string **value);
+
+#endif
diff --git a/utils/http/www-authenticate.c b/utils/http/www-authenticate.c
new file mode 100644
index 000000000..b263fdf31
--- /dev/null
+++ b/utils/http/www-authenticate.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#include "utils/http/challenge_internal.h"
+#include "utils/http/generics.h"
+#include "utils/http/parameter_internal.h"
+#include "utils/http/primitives.h"
+#include "utils/http/www-authenticate.h"
+
+/* See www-authenticate.h for documentation */
+nserror http_parse_www_authenticate(const char *header_value,
+ http_www_authenticate **result)
+{
+ const char *pos = header_value;
+ http_challenge *first = NULL;
+ http_challenge *list = NULL;
+ http_www_authenticate *wa;
+ nserror error;
+
+ /* 1#challenge */
+
+ http__skip_LWS(&pos);
+
+ error = http__parse_challenge(&pos, &first);
+ if (error != NSERROR_OK)
+ return error;
+
+ http__skip_LWS(&pos);
+
+ if (*pos == ',') {
+ error = http__item_list_parse(&pos,
+ http__parse_challenge, first, &list);
+ if (error != NSERROR_OK && error != NSERROR_NOT_FOUND)
+ return error;
+ } else {
+ list = first;
+ }
+
+ wa = malloc(sizeof(*wa));
+ if (wa == NULL) {
+ http_challenge_list_destroy(list);
+ return NSERROR_NOMEM;
+ }
+
+ wa->challenges = list;
+
+ *result = wa;
+
+ return NSERROR_OK;
+}
+
+/* See www-authenticate.h for documentation */
+void http_www_authenticate_destroy(http_www_authenticate *victim)
+{
+ http_challenge_list_destroy(victim->challenges);
+ free(victim);
+}
+
diff --git a/utils/http/www-authenticate.h b/utils/http/www-authenticate.h
new file mode 100644
index 000000000..105ca385a
--- /dev/null
+++ b/utils/http/www-authenticate.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_WWW_AUTHENTICATE_H_
+#define NETSURF_UTILS_HTTP_WWW_AUTHENTICATE_H_
+
+#include <libwapcaplet/libwapcaplet.h>
+
+#include "utils/http/challenge.h"
+
+typedef struct http_www_authenticate {
+ http_challenge *challenges;
+} http_www_authenticate;
+
+/**
+ * Parse an HTTP WWW-Authenticate header value
+ *
+ * \param header_value Header value to parse
+ * \param result Pointer to location to receive result
+ * \return NSERROR_OK on success,
+ * NSERROR_NOMEM on memory exhaustion
+ */
+nserror http_parse_www_authenticate(const char *header_value,
+ http_www_authenticate **result);
+
+/**
+ * Destroy a www authenticate object
+ *
+ * \param victim Object to destroy
+ */
+void http_www_authenticate_destroy(http_www_authenticate *victim);
+
+#endif