Refactor http utilities
svn path=/trunk/netsurf/; revision=12595
This commit is contained in:
parent
c54b6aabaa
commit
b34502af82
|
@ -16,9 +16,12 @@ S_RENDER := box.c box_construct.c box_normalise.c \
|
|||
hubbub_binding.c imagemap.c layout.c list.c table.c textinput.c \
|
||||
textplain.c
|
||||
|
||||
S_UTILS := base64.c filename.c hashtable.c http.c locale.c messages.c \
|
||||
S_UTILS := base64.c filename.c hashtable.c locale.c messages.c \
|
||||
talloc.c url.c utf8.c utils.c useragent.c filepath.c log.c
|
||||
|
||||
S_HTTP := challenge.c generics.c primitives.c parameter.c \
|
||||
content-disposition.c content-type.c www-authenticate.c
|
||||
|
||||
S_DESKTOP := cookies.c history_global_core.c hotlist.c knockout.c \
|
||||
mouse.c options.c plot_style.c print.c search.c searchweb.c \
|
||||
scrollbar.c sslcert.c textarea.c thumbnail.c tree.c \
|
||||
|
@ -30,6 +33,7 @@ S_COMMON := $(addprefix content/,$(S_CONTENT)) \
|
|||
$(addprefix css/,$(S_CSS)) \
|
||||
$(addprefix render/,$(S_RENDER)) \
|
||||
$(addprefix utils/,$(S_UTILS)) \
|
||||
$(addprefix utils/http/,$(S_HTTP)) \
|
||||
$(addprefix desktop/,$(S_DESKTOP))
|
||||
|
||||
# S_IMAGE are sources related to image management
|
||||
|
|
|
@ -128,24 +128,16 @@ static const content_handler *content_lookup(lwc_string *mime_type)
|
|||
* \param mime_type MIME type to consider
|
||||
* \return Generic content type
|
||||
*/
|
||||
content_type content_factory_type_from_mime_type(const char *mime_type)
|
||||
content_type content_factory_type_from_mime_type(lwc_string *mime_type)
|
||||
{
|
||||
const content_handler *handler;
|
||||
lwc_string *imime_type;
|
||||
lwc_error lerror;
|
||||
content_type type = CONTENT_NONE;
|
||||
|
||||
lerror = lwc_intern_string(mime_type, strlen(mime_type), &imime_type);
|
||||
if (lerror != lwc_error_ok)
|
||||
return CONTENT_NONE;
|
||||
|
||||
handler = content_lookup(imime_type);
|
||||
handler = content_lookup(mime_type);
|
||||
if (handler != NULL) {
|
||||
type = handler->type(imime_type);
|
||||
type = handler->type(mime_type);
|
||||
}
|
||||
|
||||
lwc_string_unref(imime_type);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -163,10 +155,7 @@ struct content *content_factory_create_content(llcache_handle *llcache,
|
|||
struct content *c;
|
||||
const char *content_type_header;
|
||||
const content_handler *handler;
|
||||
char *mime_type;
|
||||
http_parameter *params;
|
||||
lwc_string *imime_type;
|
||||
lwc_error lerr;
|
||||
http_content_type *ct;
|
||||
nserror error;
|
||||
|
||||
content_type_header =
|
||||
|
@ -174,39 +163,26 @@ struct content *content_factory_create_content(llcache_handle *llcache,
|
|||
if (content_type_header == NULL)
|
||||
content_type_header = "text/plain";
|
||||
|
||||
error = http_parse_content_type(content_type_header, &mime_type,
|
||||
¶ms);
|
||||
error = http_parse_content_type(content_type_header, &ct);
|
||||
if (error != NSERROR_OK)
|
||||
return NULL;
|
||||
|
||||
lerr = lwc_intern_string(mime_type, strlen(mime_type), &imime_type);
|
||||
if (lerr != lwc_error_ok) {
|
||||
http_parameter_list_destroy(params);
|
||||
free(mime_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(mime_type);
|
||||
|
||||
handler = content_lookup(imime_type);
|
||||
handler = content_lookup(ct->media_type);
|
||||
if (handler == NULL) {
|
||||
lwc_string_unref(imime_type);
|
||||
http_parameter_list_destroy(params);
|
||||
http_content_type_destroy(ct);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(handler->create != NULL);
|
||||
|
||||
error = handler->create(handler, imime_type, params, llcache,
|
||||
fallback_charset, quirks, &c);
|
||||
error = handler->create(handler, ct->media_type, ct->parameters,
|
||||
llcache, fallback_charset, quirks, &c);
|
||||
if (error != NSERROR_OK) {
|
||||
lwc_string_unref(imime_type);
|
||||
http_parameter_list_destroy(params);
|
||||
http_content_type_destroy(ct);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lwc_string_unref(imime_type);
|
||||
http_parameter_list_destroy(params);
|
||||
http_content_type_destroy(ct);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,6 @@ nserror content_factory_register_handler(lwc_string *mime_type,
|
|||
struct content *content_factory_create_content(struct llcache_handle *llcache,
|
||||
const char *fallback_charset, bool quirks);
|
||||
|
||||
content_type content_factory_type_from_mime_type(const char *mime_type);
|
||||
content_type content_factory_type_from_mime_type(lwc_string *mime_type);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -541,8 +541,7 @@ bool hlcache_type_is_acceptable(llcache_handle *llcache,
|
|||
content_type accepted_types, content_type *computed_type)
|
||||
{
|
||||
const char *content_type_header;
|
||||
char *mime_type;
|
||||
http_parameter *params;
|
||||
http_content_type *ct;
|
||||
content_type type;
|
||||
nserror error;
|
||||
|
||||
|
@ -551,15 +550,13 @@ bool hlcache_type_is_acceptable(llcache_handle *llcache,
|
|||
if (content_type_header == NULL)
|
||||
content_type_header = "text/plain";
|
||||
|
||||
error = http_parse_content_type(content_type_header, &mime_type,
|
||||
¶ms);
|
||||
error = http_parse_content_type(content_type_header, &ct);
|
||||
if (error != NSERROR_OK)
|
||||
return false;
|
||||
|
||||
type = content_factory_type_from_mime_type(mime_type);
|
||||
type = content_factory_type_from_mime_type(ct->media_type);
|
||||
|
||||
free(mime_type);
|
||||
http_parameter_list_destroy(params);
|
||||
http_content_type_destroy(ct);
|
||||
|
||||
*computed_type = type;
|
||||
|
||||
|
|
26
css/css.c
26
css/css.c
|
@ -90,6 +90,7 @@ static const content_handler css_content_handler = {
|
|||
};
|
||||
|
||||
static lwc_string *css_mime_type;
|
||||
static lwc_string *css_charset;
|
||||
static css_stylesheet *blank_import;
|
||||
|
||||
/**
|
||||
|
@ -105,10 +106,18 @@ nserror css_init(void)
|
|||
if (lerror != lwc_error_ok)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
lerror = lwc_intern_string("charset", SLEN("charset"), &css_charset);
|
||||
if (lerror != lwc_error_ok) {
|
||||
lwc_string_unref(css_mime_type);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
error = content_factory_register_handler(css_mime_type,
|
||||
&css_content_handler);
|
||||
if (error != NSERROR_OK)
|
||||
if (error != NSERROR_OK) {
|
||||
lwc_string_unref(css_charset);
|
||||
lwc_string_unref(css_mime_type);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -118,6 +127,8 @@ nserror css_init(void)
|
|||
*/
|
||||
void css_fini(void)
|
||||
{
|
||||
lwc_string_unref(css_charset);
|
||||
|
||||
lwc_string_unref(css_mime_type);
|
||||
|
||||
if (blank_import != NULL)
|
||||
|
@ -138,6 +149,7 @@ nserror nscss_create(const content_handler *handler,
|
|||
{
|
||||
nscss_content *result;
|
||||
const char *charset = NULL;
|
||||
lwc_string *charset_value = NULL;
|
||||
union content_msg_data msg_data;
|
||||
nserror error;
|
||||
|
||||
|
@ -153,11 +165,14 @@ nserror nscss_create(const content_handler *handler,
|
|||
}
|
||||
|
||||
/* Find charset specified on HTTP layer, if any */
|
||||
error = http_parameter_list_find_item(params, "charset", &charset);
|
||||
if (error != NSERROR_OK || *charset == '\0') {
|
||||
error = http_parameter_list_find_item(params, css_charset,
|
||||
&charset_value);
|
||||
if (error != NSERROR_OK || lwc_string_length(charset_value) == 0) {
|
||||
/* No charset specified, use fallback, if any */
|
||||
/** \todo libcss will take this as gospel, which is wrong */
|
||||
charset = fallback_charset;
|
||||
} else {
|
||||
charset = lwc_string_data(charset_value);
|
||||
}
|
||||
|
||||
error = nscss_create_css_data(&result->data,
|
||||
|
@ -167,10 +182,15 @@ nserror nscss_create(const content_handler *handler,
|
|||
if (error != NSERROR_OK) {
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(&result->base, CONTENT_MSG_ERROR, msg_data);
|
||||
if (charset_value != NULL)
|
||||
lwc_string_unref(charset_value);
|
||||
talloc_free(result);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (charset_value != NULL)
|
||||
lwc_string_unref(charset_value);
|
||||
|
||||
*c = (struct content *) result;
|
||||
|
||||
return NSERROR_OK;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "desktop/gui.h"
|
||||
#include "utils/http.h"
|
||||
#include "utils/url.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/**
|
||||
* A context for a download
|
||||
|
@ -36,7 +37,7 @@ struct download_context {
|
|||
llcache_handle *llcache; /**< Low-level cache handle */
|
||||
struct gui_window *parent; /**< Parent window */
|
||||
|
||||
char *mime_type; /**< MIME type of download */
|
||||
lwc_string *mime_type; /**< MIME type of download */
|
||||
unsigned long total_length; /**< Length of data, in bytes */
|
||||
char *filename; /**< Suggested filename */
|
||||
|
||||
|
@ -87,8 +88,7 @@ static char *download_default_filename(const char *url)
|
|||
static nserror download_context_process_headers(download_context *ctx)
|
||||
{
|
||||
const char *http_header;
|
||||
char *mime_type;
|
||||
http_parameter *params;
|
||||
http_content_type *content_type;
|
||||
unsigned long length;
|
||||
nserror error;
|
||||
|
||||
|
@ -97,13 +97,10 @@ static nserror download_context_process_headers(download_context *ctx)
|
|||
if (http_header == NULL)
|
||||
http_header = "text/plain";
|
||||
|
||||
error = http_parse_content_type(http_header, &mime_type, ¶ms);
|
||||
error = http_parse_content_type(http_header, &content_type);
|
||||
if (error != NSERROR_OK)
|
||||
return error;
|
||||
|
||||
/* Don't care about parameters */
|
||||
http_parameter_list_destroy(params);
|
||||
|
||||
/* Retrieve and parse Content-Length */
|
||||
http_header = llcache_handle_get_header(ctx->llcache, "Content-Length");
|
||||
if (http_header == NULL)
|
||||
|
@ -115,35 +112,46 @@ static nserror download_context_process_headers(download_context *ctx)
|
|||
http_header = llcache_handle_get_header(ctx->llcache,
|
||||
"Content-Disposition");
|
||||
if (http_header != NULL) {
|
||||
const char *filename;
|
||||
char *disposition;
|
||||
lwc_string *filename;
|
||||
lwc_string *filename_value;
|
||||
http_content_disposition *disposition;
|
||||
|
||||
if (lwc_intern_string("filename", SLEN("filename"),
|
||||
&filename) != lwc_error_ok) {
|
||||
http_content_type_destroy(content_type);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
error = http_parse_content_disposition(http_header,
|
||||
&disposition, ¶ms);
|
||||
&disposition);
|
||||
if (error != NSERROR_OK) {
|
||||
free(mime_type);
|
||||
lwc_string_unref(filename);
|
||||
http_content_type_destroy(content_type);
|
||||
return error;
|
||||
}
|
||||
|
||||
free(disposition);
|
||||
|
||||
error = http_parameter_list_find_item(params,
|
||||
"filename", &filename);
|
||||
error = http_parameter_list_find_item(disposition->parameters,
|
||||
filename, &filename_value);
|
||||
if (error == NSERROR_OK)
|
||||
ctx->filename = download_parse_filename(filename);
|
||||
ctx->filename = download_parse_filename(
|
||||
lwc_string_data(filename_value));
|
||||
|
||||
http_parameter_list_destroy(params);
|
||||
http_content_disposition_destroy(disposition);
|
||||
lwc_string_unref(filename_value);
|
||||
lwc_string_unref(filename);
|
||||
}
|
||||
|
||||
ctx->mime_type = mime_type;
|
||||
ctx->mime_type = lwc_string_ref(content_type->media_type);
|
||||
ctx->total_length = length;
|
||||
if (ctx->filename == NULL) {
|
||||
ctx->filename = download_default_filename(
|
||||
llcache_handle_get_url(ctx->llcache));
|
||||
}
|
||||
|
||||
http_content_type_destroy(content_type);
|
||||
|
||||
if (ctx->filename == NULL) {
|
||||
free(ctx->mime_type);
|
||||
lwc_string_unref(ctx->mime_type);
|
||||
ctx->mime_type = NULL;
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
@ -152,9 +160,7 @@ static nserror download_context_process_headers(download_context *ctx)
|
|||
ctx->window = gui_download_window_create(ctx, ctx->parent);
|
||||
if (ctx->window == NULL) {
|
||||
free(ctx->filename);
|
||||
ctx->filename = NULL;
|
||||
free(ctx->mime_type);
|
||||
ctx->mime_type = NULL;
|
||||
lwc_string_unref(ctx->mime_type);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
|
@ -259,7 +265,7 @@ void download_context_destroy(download_context *ctx)
|
|||
{
|
||||
llcache_handle_release(ctx->llcache);
|
||||
|
||||
free(ctx->mime_type);
|
||||
lwc_string_unref(ctx->mime_type);
|
||||
|
||||
free(ctx->filename);
|
||||
|
||||
|
@ -283,7 +289,7 @@ const char *download_context_get_url(const download_context *ctx)
|
|||
/* See download.h for documentation */
|
||||
const char *download_context_get_mime_type(const download_context *ctx)
|
||||
{
|
||||
return ctx->mime_type;
|
||||
return lwc_string_data(ctx->mime_type);
|
||||
}
|
||||
|
||||
/* See download.h for documentation */
|
||||
|
|
|
@ -1257,17 +1257,44 @@ bool box_object(BOX_SPECIAL_PARAMS)
|
|||
* (classid || !classid) && data => data is used (consult type)
|
||||
* !classid && !data => invalid; ignored */
|
||||
|
||||
if (params->classid && !params->data && params->codetype &&
|
||||
content_factory_type_from_mime_type(params->codetype) ==
|
||||
CONTENT_NONE)
|
||||
/* can't handle this MIME type */
|
||||
return true;
|
||||
if (params->classid != NULL && params->data == NULL &&
|
||||
params->codetype != NULL) {
|
||||
lwc_string *icodetype;
|
||||
lwc_error lerror;
|
||||
|
||||
if (params->data && params->type &&
|
||||
content_factory_type_from_mime_type(params->type) ==
|
||||
CONTENT_NONE)
|
||||
/* can't handle this MIME type */
|
||||
return true;
|
||||
lerror = lwc_intern_string(params->codetype,
|
||||
strlen(params->codetype), &icodetype);
|
||||
if (lerror != lwc_error_ok)
|
||||
return false;
|
||||
|
||||
if (content_factory_type_from_mime_type(icodetype) ==
|
||||
CONTENT_NONE) {
|
||||
/* can't handle this MIME type */
|
||||
lwc_string_unref(icodetype);
|
||||
return true;
|
||||
}
|
||||
|
||||
lwc_string_unref(icodetype);
|
||||
}
|
||||
|
||||
if (params->data != NULL && params->type != NULL) {
|
||||
lwc_string *itype;
|
||||
lwc_error lerror;
|
||||
|
||||
lerror = lwc_intern_string(params->type, strlen(params->type),
|
||||
&itype);
|
||||
if (lerror != lwc_error_ok)
|
||||
return false;
|
||||
|
||||
if (content_factory_type_from_mime_type(itype) ==
|
||||
CONTENT_NONE) {
|
||||
/* can't handle this MIME type */
|
||||
lwc_string_unref(itype);
|
||||
return true;
|
||||
}
|
||||
|
||||
lwc_string_unref(itype);
|
||||
}
|
||||
|
||||
/* add parameters to linked list */
|
||||
for (c = n->children; c; c = c->next) {
|
||||
|
|
|
@ -138,6 +138,7 @@ static const char *html_types[] = {
|
|||
};
|
||||
|
||||
static lwc_string *html_mime_types[NOF_ELEMENTS(html_types)];
|
||||
static lwc_string *html_charset;
|
||||
|
||||
nserror html_init(void)
|
||||
{
|
||||
|
@ -145,6 +146,12 @@ nserror html_init(void)
|
|||
lwc_error lerror;
|
||||
nserror error;
|
||||
|
||||
lerror = lwc_intern_string("charset", SLEN("charset"), &html_charset);
|
||||
if (lerror != lwc_error_ok) {
|
||||
error = NSERROR_NOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0; i < NOF_ELEMENTS(html_mime_types); i++) {
|
||||
lerror = lwc_intern_string(html_types[i],
|
||||
strlen(html_types[i]),
|
||||
|
@ -176,6 +183,9 @@ void html_fini(void)
|
|||
if (html_mime_types[i] != NULL)
|
||||
lwc_string_unref(html_mime_types[i]);
|
||||
}
|
||||
|
||||
if (html_charset != NULL)
|
||||
lwc_string_unref(html_charset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,7 +227,7 @@ nserror html_create(const content_handler *handler,
|
|||
|
||||
nserror html_create_html_data(html_content *c, const http_parameter *params)
|
||||
{
|
||||
const char *charset;
|
||||
lwc_string *charset;
|
||||
union content_msg_data msg_data;
|
||||
binding_error error;
|
||||
nserror nerror;
|
||||
|
@ -245,10 +255,13 @@ nserror html_create_html_data(html_content *c, const http_parameter *params)
|
|||
c->font_func = &nsfont;
|
||||
c->scrollbar = NULL;
|
||||
|
||||
nerror = http_parameter_list_find_item(params, "charset", &charset);
|
||||
nerror = http_parameter_list_find_item(params, html_charset, &charset);
|
||||
if (nerror == NSERROR_OK) {
|
||||
c->encoding = talloc_strdup(c, charset);
|
||||
if (!c->encoding) {
|
||||
c->encoding = talloc_strdup(c, lwc_string_data(charset));
|
||||
|
||||
lwc_string_unref(charset);
|
||||
|
||||
if (c->encoding == NULL) {
|
||||
error = BINDING_NOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ struct textplain_line {
|
|||
typedef struct textplain_content {
|
||||
struct content base;
|
||||
|
||||
char *encoding;
|
||||
lwc_string *encoding;
|
||||
void *inputstream;
|
||||
char *utf8_data;
|
||||
size_t utf8_data_size;
|
||||
|
@ -93,7 +93,7 @@ static nserror textplain_create(const content_handler *handler,
|
|||
llcache_handle *llcache, const char *fallback_charset,
|
||||
bool quirks, struct content **c);
|
||||
static nserror textplain_create_internal(textplain_content *c,
|
||||
const char *charset);
|
||||
lwc_string *charset);
|
||||
static bool textplain_process_data(struct content *c,
|
||||
const char *data, unsigned int size);
|
||||
static bool textplain_convert(struct content *c);
|
||||
|
@ -140,6 +140,8 @@ static const content_handler textplain_content_handler = {
|
|||
};
|
||||
|
||||
static lwc_string *textplain_mime_type;
|
||||
static lwc_string *textplain_charset;
|
||||
static lwc_string *textplain_default_charset;
|
||||
|
||||
/**
|
||||
* Initialise the text content handler
|
||||
|
@ -154,10 +156,28 @@ nserror textplain_init(void)
|
|||
if (lerror != lwc_error_ok)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
lerror = lwc_intern_string("charset", SLEN("charset"),
|
||||
&textplain_charset);
|
||||
if (lerror != lwc_error_ok) {
|
||||
lwc_string_unref(textplain_mime_type);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
lerror = lwc_intern_string("Windows-1252", SLEN("Windows-1252"),
|
||||
&textplain_default_charset);
|
||||
if (lerror != lwc_error_ok) {
|
||||
lwc_string_unref(textplain_charset);
|
||||
lwc_string_unref(textplain_mime_type);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
error = content_factory_register_handler(textplain_mime_type,
|
||||
&textplain_content_handler);
|
||||
if (error != NSERROR_OK)
|
||||
if (error != NSERROR_OK) {
|
||||
lwc_string_unref(textplain_default_charset);
|
||||
lwc_string_unref(textplain_charset);
|
||||
lwc_string_unref(textplain_mime_type);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -167,6 +187,8 @@ nserror textplain_init(void)
|
|||
*/
|
||||
void textplain_fini(void)
|
||||
{
|
||||
lwc_string_unref(textplain_default_charset);
|
||||
lwc_string_unref(textplain_charset);
|
||||
lwc_string_unref(textplain_mime_type);
|
||||
}
|
||||
|
||||
|
@ -181,7 +203,7 @@ nserror textplain_create(const content_handler *handler,
|
|||
{
|
||||
textplain_content *text;
|
||||
nserror error;
|
||||
const char *encoding;
|
||||
lwc_string *encoding;
|
||||
|
||||
text = talloc_zero(0, textplain_content);
|
||||
if (text == NULL)
|
||||
|
@ -194,17 +216,21 @@ nserror textplain_create(const content_handler *handler,
|
|||
return error;
|
||||
}
|
||||
|
||||
error = http_parameter_list_find_item(params, "charset", &encoding);
|
||||
error = http_parameter_list_find_item(params, textplain_charset,
|
||||
&encoding);
|
||||
if (error != NSERROR_OK) {
|
||||
encoding = "Windows-1252";
|
||||
encoding = lwc_string_ref(textplain_default_charset);
|
||||
}
|
||||
|
||||
error = textplain_create_internal(text, encoding);
|
||||
if (error != NSERROR_OK) {
|
||||
lwc_string_unref(encoding);
|
||||
talloc_free(text);
|
||||
return error;
|
||||
}
|
||||
|
||||
lwc_string_unref(encoding);
|
||||
|
||||
*c = (struct content *) text;
|
||||
|
||||
return NSERROR_OK;
|
||||
|
@ -226,7 +252,7 @@ parserutils_error textplain_charset_hack(const uint8_t *data, size_t len,
|
|||
return PARSERUTILS_OK;
|
||||
}
|
||||
|
||||
nserror textplain_create_internal(textplain_content *c, const char *encoding)
|
||||
nserror textplain_create_internal(textplain_content *c, lwc_string *encoding)
|
||||
{
|
||||
char *utf8_data;
|
||||
parserutils_inputstream *stream;
|
||||
|
@ -239,7 +265,7 @@ nserror textplain_create_internal(textplain_content *c, const char *encoding)
|
|||
if (utf8_data == NULL)
|
||||
goto no_memory;
|
||||
|
||||
error = parserutils_inputstream_create(encoding, 0,
|
||||
error = parserutils_inputstream_create(lwc_string_data(encoding), 0,
|
||||
textplain_charset_hack, ns_realloc, NULL, &stream);
|
||||
if (error == PARSERUTILS_BADENCODING) {
|
||||
/* Fall back to Windows-1252 */
|
||||
|
@ -252,13 +278,7 @@ nserror textplain_create_internal(textplain_content *c, const char *encoding)
|
|||
goto no_memory;
|
||||
}
|
||||
|
||||
c->encoding = strdup(encoding);
|
||||
if (c->encoding == NULL) {
|
||||
talloc_free(utf8_data);
|
||||
parserutils_inputstream_destroy(stream);
|
||||
goto no_memory;
|
||||
}
|
||||
|
||||
c->encoding = lwc_string_ref(encoding);
|
||||
c->inputstream = stream;
|
||||
c->utf8_data = utf8_data;
|
||||
c->utf8_data_size = 0;
|
||||
|
@ -527,8 +547,7 @@ void textplain_destroy(struct content *c)
|
|||
{
|
||||
textplain_content *text = (textplain_content *) c;
|
||||
|
||||
if (text->encoding != NULL)
|
||||
free(text->encoding);
|
||||
lwc_string_unref(text->encoding);
|
||||
|
||||
if (text->inputstream != NULL)
|
||||
parserutils_inputstream_destroy(text->inputstream);
|
||||
|
|
423
utils/http.c
423
utils/http.c
|
@ -1,423 +0,0 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* HTTP header parsing functions
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils/http.h"
|
||||
|
||||
/**
|
||||
* Representation of an HTTP parameter
|
||||
*/
|
||||
struct http_parameter {
|
||||
struct http_parameter *next; /**< Next parameter in list, or NULL */
|
||||
|
||||
char *name; /**< Parameter name */
|
||||
char *value; /**< Parameter value */
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* The returned value is owned by the caller
|
||||
*/
|
||||
static nserror http_parse_token(const char **input, char **value)
|
||||
{
|
||||
const uint8_t *start = (const uint8_t *) *input;
|
||||
const uint8_t *end;
|
||||
char *token;
|
||||
|
||||
end = start;
|
||||
while (http_is_token_char(*end))
|
||||
end++;
|
||||
|
||||
token = malloc(end - start + 1);
|
||||
if (token == NULL)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
memcpy(token, start, end - start);
|
||||
token[end - start] = '\0';
|
||||
|
||||
*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
|
||||
*
|
||||
* The returned value is owned by the caller
|
||||
*/
|
||||
static nserror http_parse_quoted_string(const char **input, char **value)
|
||||
{
|
||||
const uint8_t *start = (const uint8_t *) *input;
|
||||
const uint8_t *end;
|
||||
uint8_t c;
|
||||
char *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 == '"') {
|
||||
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 != '"') {
|
||||
start--;
|
||||
end = start;
|
||||
}
|
||||
} else {
|
||||
end = start;
|
||||
}
|
||||
|
||||
string_value = malloc(end - start + 1);
|
||||
if (string_value == NULL)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
memcpy(string_value, start, end - start);
|
||||
string_value[end - start] = '\0';
|
||||
|
||||
*value = string_value;
|
||||
|
||||
if (end != start)
|
||||
*input = (const char *) end + 1;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* The returned parameter is owned by the caller.
|
||||
*/
|
||||
static nserror http_parse_parameter(const char **input,
|
||||
http_parameter **parameter)
|
||||
{
|
||||
const char *pos = *input;
|
||||
char *name;
|
||||
char *value;
|
||||
http_parameter *param;
|
||||
nserror error;
|
||||
|
||||
/* token "=" ( token | quoted-string ) */
|
||||
|
||||
error = http_parse_token(&pos, &name);
|
||||
if (error != NSERROR_OK)
|
||||
return error;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
if (*pos != '=') {
|
||||
value = strdup("");
|
||||
if (value == NULL) {
|
||||
free(name);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
} else {
|
||||
pos++;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
if (*pos == '"')
|
||||
error = http_parse_quoted_string(&pos, &value);
|
||||
else
|
||||
error = http_parse_token(&pos, &value);
|
||||
|
||||
if (error != NSERROR_OK) {
|
||||
free(name);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
param = malloc(sizeof(*param));
|
||||
if (param == NULL) {
|
||||
free(value);
|
||||
free(name);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
param->next = NULL;
|
||||
param->name = name;
|
||||
param->value = value;
|
||||
|
||||
*parameter = param;
|
||||
*input = pos;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an HTTP parameter list
|
||||
*
|
||||
* \param input Pointer to current input byte. Updated on exit.
|
||||
* \param parameters Pointer to location to receive on-heap parameter list.
|
||||
* \return NSERROR_OK on success,
|
||||
* NSERROR_NOMEM on memory exhaustion
|
||||
*
|
||||
* The returned parameter list is owned by the caller
|
||||
*/
|
||||
static nserror http_parse_parameter_list(const char **input,
|
||||
http_parameter **parameters)
|
||||
{
|
||||
const char *pos = *input;
|
||||
http_parameter *param;
|
||||
http_parameter *list = NULL;
|
||||
nserror error;
|
||||
|
||||
/* 1*( ";" parameter ) */
|
||||
|
||||
while (*pos == ';') {
|
||||
pos++;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
error = http_parse_parameter(&pos, ¶m);
|
||||
if (error != NSERROR_OK) {
|
||||
while (list != NULL) {
|
||||
param = list;
|
||||
|
||||
list = param->next;
|
||||
|
||||
free(param->name);
|
||||
free(param->value);
|
||||
free(param);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
if (list != NULL)
|
||||
param->next = list;
|
||||
|
||||
list = param;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
}
|
||||
|
||||
*parameters = list;
|
||||
*input = pos;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/* See http.h for documentation */
|
||||
nserror http_parse_content_type(const char *header_value, char **media_type,
|
||||
http_parameter **parameters)
|
||||
{
|
||||
const char *pos = header_value;
|
||||
char *type;
|
||||
char *subtype = NULL;
|
||||
http_parameter *params = NULL;
|
||||
char *mime;
|
||||
size_t mime_len;
|
||||
nserror error;
|
||||
|
||||
/* type "/" subtype *( ";" parameter ) */
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
error = http_parse_token(&pos, &type);
|
||||
if (error != NSERROR_OK)
|
||||
return error;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
if (*pos == '/') {
|
||||
pos++;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
error = http_parse_token(&pos, &subtype);
|
||||
if (error != NSERROR_OK) {
|
||||
free(type);
|
||||
return error;
|
||||
}
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
if (*pos == ';') {
|
||||
error = http_parse_parameter_list(&pos, ¶ms);
|
||||
if (error != NSERROR_OK) {
|
||||
free(subtype);
|
||||
free(type);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* <type> + <subtype> + '/' */
|
||||
mime_len = strlen(type) + (subtype != NULL ? strlen(subtype) : 0) + 1;
|
||||
|
||||
mime = malloc(mime_len + 1);
|
||||
if (mime == NULL) {
|
||||
http_parameter_list_destroy(params);
|
||||
free(subtype);
|
||||
free(type);
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
sprintf(mime, "%s/%s", type, subtype != NULL ? subtype : "");
|
||||
|
||||
free(subtype);
|
||||
free(type);
|
||||
|
||||
*media_type = mime;
|
||||
*parameters = params;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/* See http.h for documentation */
|
||||
nserror http_parse_content_disposition(const char *header_value,
|
||||
char **disposition_type, http_parameter **parameters)
|
||||
{
|
||||
const char *pos = header_value;
|
||||
char *type;
|
||||
http_parameter *params = NULL;
|
||||
nserror error;
|
||||
|
||||
/* disposition-type *( ";" parameter ) */
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
error = http_parse_token(&pos, &type);
|
||||
if (error != NSERROR_OK)
|
||||
return error;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
if (*pos == ';') {
|
||||
error = http_parse_parameter_list(&pos, ¶ms);
|
||||
if (error != NSERROR_OK) {
|
||||
free(type);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
*disposition_type = type;
|
||||
*parameters = params;
|
||||
|
||||
return NSERROR_OK;
|
||||
|
||||
}
|
||||
|
||||
/* See http.h for documentation */
|
||||
nserror http_parameter_list_find_item(const http_parameter *list,
|
||||
const char *name, const char **value)
|
||||
{
|
||||
while (list != NULL && strcasecmp(name, list->name) != 0)
|
||||
list = list->next;
|
||||
|
||||
if (list == NULL)
|
||||
return NSERROR_NOT_FOUND;
|
||||
|
||||
*value = list->value;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/* See http.h for documentation */
|
||||
const http_parameter *http_parameter_list_iterate(const http_parameter *cur,
|
||||
const char **name, const char **value)
|
||||
{
|
||||
if (cur == NULL)
|
||||
return NULL;
|
||||
|
||||
*name = cur->name;
|
||||
*value = cur->value;
|
||||
|
||||
return cur->next;
|
||||
}
|
||||
|
||||
/* See http.h for documentation */
|
||||
void http_parameter_list_destroy(http_parameter *list)
|
||||
{
|
||||
while (list != NULL) {
|
||||
http_parameter *victim = list;
|
||||
|
||||
list = victim->next;
|
||||
|
||||
free(victim->name);
|
||||
free(victim->value);
|
||||
free(victim);
|
||||
}
|
||||
}
|
||||
|
60
utils/http.h
60
utils/http.h
|
@ -23,63 +23,13 @@
|
|||
#ifndef NETSURF_UTILS_HTTP_H_
|
||||
#define NETSURF_UTILS_HTTP_H_
|
||||
|
||||
#include <libwapcaplet/libwapcaplet.h>
|
||||
|
||||
#include "utils/errors.h"
|
||||
|
||||
typedef struct http_parameter http_parameter;
|
||||
|
||||
/**
|
||||
* Parse an HTTP Content-Type header value
|
||||
*
|
||||
* \param header_value Header value to parse
|
||||
* \param media_type Pointer to location to receive media type
|
||||
* \param parameters Pointer to location to receive parameter list
|
||||
* \return NSERROR_OK on success,
|
||||
* NSERROR_NOMEM on memory exhaustion
|
||||
*/
|
||||
nserror http_parse_content_type(const char *header_value, char **media_type,
|
||||
http_parameter **parameters);
|
||||
|
||||
/**
|
||||
* Parse an HTTP Content-Disposition header value
|
||||
*
|
||||
* \param header_value Header value to parse
|
||||
* \param disposition_type Pointer to location to receive disposition type
|
||||
* \param parameters Pointer to location to receive parameter list
|
||||
* \return NSERROR_OK on success,
|
||||
* NSERROR_NOMEM on memory exhaustion
|
||||
*/
|
||||
nserror http_parse_content_disposition(const char *header_value,
|
||||
char **disposition_type, http_parameter **parameters);
|
||||
|
||||
/**
|
||||
* 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,
|
||||
const char *name, const char **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,
|
||||
const char **name, const char **value);
|
||||
|
||||
/**
|
||||
* Destroy a list of HTTP parameters
|
||||
*
|
||||
* \param list List to destroy
|
||||
*/
|
||||
void http_parameter_list_destroy(http_parameter *list);
|
||||
#include "utils/http/content-disposition.h"
|
||||
#include "utils/http/content-type.h"
|
||||
#include "utils/http/www-authenticate.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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, ¶ms);
|
||||
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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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, ¶ms);
|
||||
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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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, ¶ms);
|
||||
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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
Loading…
Reference in New Issue