Beispiel #1
0
/**
 * Initialise a CSS content
 *
 * \param c       Content to initialise
 * \param params  Content-Type parameters
 * \return true on success, false on failure
 */
nserror nscss_create(const content_handler *handler, 
		lwc_string *imime_type,	const http_parameter *params,
		llcache_handle *llcache, const char *fallback_charset,
		bool quirks, struct content **c)
{
	nscss_content *result;
	const char *charset = NULL;
	const char *xnsbase = NULL;
	lwc_string *charset_value = NULL;
	union content_msg_data msg_data;
	nserror error;

	result = calloc(1, sizeof(nscss_content));
	if (result == NULL)
		return NSERROR_NOMEM;

	error = content__init(&result->base, handler, imime_type,
			params, llcache, fallback_charset, quirks);
	if (error != NSERROR_OK) {
		free(result);
		return error;
	}

	/* Find charset specified on HTTP layer, if any */
	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);
	}

	/* Compute base URL for stylesheet */
	xnsbase = llcache_handle_get_header(llcache, "X-NS-Base");
	if (xnsbase == NULL) {
		xnsbase = nsurl_access(content_get_url(&result->base));
	}

	error = nscss_create_css_data(&result->data, 
			xnsbase, charset, result->base.quirks, 
			nscss_content_done, result);
	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);
		free(result);
		return error;
	}

	if (charset_value != NULL)
		lwc_string_unref(charset_value);

	*c = (struct content *) result;

	return NSERROR_OK;
}
Beispiel #2
0
/**
 * Process fetch headers for a download context.
 * Extracts MIME type, total length, and creates gui_download_window
 *
 * \param ctx  Context to process
 * \return NSERROR_OK on success, appropriate error otherwise
 */
static nserror download_context_process_headers(download_context *ctx)
{
	const char *http_header;
	char *mime_type;
	http_parameter *params;
	unsigned long length;
	nserror error;

	/* Retrieve and parse Content-Type */
	http_header = llcache_handle_get_header(ctx->llcache, "Content-Type");
	if (http_header == NULL)
		http_header = "text/plain";

	error = http_parse_content_type(http_header, &mime_type, &params);
	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)
		length = 0;
	else
		length = strtoul(http_header, NULL, 10);

	ctx->mime_type = mime_type;
	ctx->total_length = length;

	/* Create the frontend window */
	ctx->window = gui_download_window_create(ctx, ctx->parent);
	if (ctx->window == NULL) {
		free(ctx->mime_type);
		ctx->mime_type = NULL;
		return NSERROR_NOMEM;
	}

	return NSERROR_OK;
}
Beispiel #3
0
/**
 * Create a content object
 *
 * \param llcache           Underlying source data handle
 * \param fallback_charset  Character set to fall back to if none specified
 * \param quirks            Quirkiness of containing document
 * \param effective_type    Effective MIME type of content
 * \return Pointer to content object, or NULL on failure
 */
struct content *content_factory_create_content(llcache_handle *llcache,
		const char *fallback_charset, bool quirks,
		lwc_string *effective_type)
{
	struct content *c;
	const char *content_type_header;
	const content_handler *handler;
	http_content_type *ct = NULL;
	nserror error;

	handler = content_lookup(effective_type);
	if (handler == NULL)
		return NULL;

	assert(handler->create != NULL);

	/* Use the parameters from the declared Content-Type header */
	content_type_header = 
			llcache_handle_get_header(llcache, "Content-Type");
	if (content_type_header != NULL) {
		/* We don't care if this fails */
		http_parse_content_type(content_type_header, &ct);
	}

	error = handler->create(handler, effective_type, 
			ct != NULL ? ct->parameters : NULL, 
			llcache, fallback_charset, quirks, 
			&c);

	if (ct != NULL)
		http_content_type_destroy(ct);

	if (error != NSERROR_OK)
		return NULL;

	return c;
}
Beispiel #4
0
/* See mimesniff.h for documentation */
nserror mimesniff_compute_effective_type(llcache_handle *handle,
		const uint8_t *data, size_t len, bool sniff_allowed,
		bool image_only, lwc_string **effective_type)
{
#define S(s) { s, SLEN(s) }
	static const struct tt_s {
		const char *data;
		size_t len;
	} text_types[] = {
		S("text/plain"),
		S("text/plain; charset=ISO-8859-1"),
		S("text/plain; charset=iso-8859-1"),
		S("text/plain; charset=UTF-8"),
		{ NULL, 0 }
	};
#undef S

	const char *content_type_header;
	size_t content_type_header_len;
	http_content_type *ct;
	const struct tt_s *tt;
	bool match;
	nserror error;

	content_type_header = 
			llcache_handle_get_header(handle, "Content-Type");
	if (content_type_header == NULL) {
		if (sniff_allowed == false)
			return NSERROR_NOT_FOUND;

		/* No official type => unknown */
		return mimesniff__compute_unknown(data, len, effective_type);
	}

	error = http_parse_content_type(content_type_header, &ct);
	if (error != NSERROR_OK) {
		if (sniff_allowed == false)
			return NSERROR_NOT_FOUND;

		/* Unparseable => unknown */
		return mimesniff__compute_unknown(data, len, effective_type);
	}

	if (sniff_allowed == false) {
		*effective_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return NSERROR_OK;
	}

	if (image_only) {
		lwc_string *official_type;

		if (lwc_string_caseless_isequal(ct->media_type, image_svg, 
				&match) == lwc_error_ok && match) {
			*effective_type = lwc_string_ref(image_svg);
			http_content_type_destroy(ct);
			return NSERROR_OK;
		}

		official_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return mimesniff__compute_image(official_type,
				data, len, effective_type);
	}

	content_type_header_len = strlen(content_type_header);

	/* Look for text types */
	for (tt = text_types; tt->data != NULL; tt++) {
		if (tt->len == content_type_header_len &&
				memcmp(tt->data, content_type_header, 
					content_type_header_len) == 0) {
			http_content_type_destroy(ct);
			return mimesniff__compute_text_or_binary(data, len,
					effective_type);
		}
	}

	/* unknown/unknown, application/unknown, * / * */
	if ((lwc_string_caseless_isequal(ct->media_type, unknown_unknown, 
				&match) == lwc_error_ok && match) ||
			(lwc_string_caseless_isequal(ct->media_type, 
				application_unknown, &match) == lwc_error_ok && 
				match) ||
			(lwc_string_caseless_isequal(ct->media_type, any, 
				&match) == lwc_error_ok && match)) {
		http_content_type_destroy(ct);
		return mimesniff__compute_unknown(data, len, effective_type);
	}

	/* +xml */
	if (lwc_string_length(ct->media_type) > SLEN("+xml") &&
			strncasecmp(lwc_string_data(ct->media_type) + 
				lwc_string_length(ct->media_type) - 
				SLEN("+xml"), 
				"+xml", SLEN("+xml")) == 0) {
		/* Use official type */
		*effective_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return NSERROR_OK;
	}

	/* text/xml, application/xml */
	if ((lwc_string_caseless_isequal(ct->media_type, text_xml, 
				&match) == lwc_error_ok && match) ||
			(lwc_string_caseless_isequal(ct->media_type, 
				application_xml, &match) == lwc_error_ok && 
				match)) {
		/* Use official type */
		*effective_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return NSERROR_OK;
	}
	
	/* Image types */
	if (content_factory_type_from_mime_type(ct->media_type) == 
			CONTENT_IMAGE) {
		lwc_string *official_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return mimesniff__compute_image(official_type,
				data, len, effective_type);
	}

	/* text/html */
	if ((lwc_string_caseless_isequal(ct->media_type, text_html, 
			&match) == lwc_error_ok && match)) {
		http_content_type_destroy(ct);
		return mimesniff__compute_feed_or_html(data, len,
				effective_type);
	}

	/* Use official type */
	*effective_type = lwc_string_ref(ct->media_type);

	http_content_type_destroy(ct);

	return NSERROR_OK;
}
Beispiel #5
0
/**
 * Process fetch headers for a download context.
 * Extracts MIME type, total length, and creates gui_download_window
 *
 * \param ctx  Context to process
 * \return NSERROR_OK on success, appropriate error otherwise
 */
static nserror download_context_process_headers(download_context *ctx)
{
	const char *http_header;
	http_content_type *content_type;
	unsigned long length;
	nserror error;

	/* Retrieve and parse Content-Type */
	http_header = llcache_handle_get_header(ctx->llcache, "Content-Type");
	if (http_header == NULL)
		http_header = "text/plain";

	error = http_parse_content_type(http_header, &content_type);
	if (error != NSERROR_OK)
		return error;

	/* Retrieve and parse Content-Length */
	http_header = llcache_handle_get_header(ctx->llcache, "Content-Length");
	if (http_header == NULL)
		length = 0;
	else
		length = strtoul(http_header, NULL, 10);

	/* Retrieve and parse Content-Disposition */
	http_header = llcache_handle_get_header(ctx->llcache, 
			"Content-Disposition");
	if (http_header != NULL) {
		lwc_string *filename_value;
		http_content_disposition *disposition;

		error = http_parse_content_disposition(http_header, 
				&disposition);
		if (error != NSERROR_OK) {
			http_content_type_destroy(content_type);
			return error;
		}

		error = http_parameter_list_find_item(disposition->parameters, 
				corestring_lwc_filename, &filename_value);
		if (error == NSERROR_OK) {
			ctx->filename = download_parse_filename(
					lwc_string_data(filename_value));
			lwc_string_unref(filename_value);
		}

		http_content_disposition_destroy(disposition);
	}

	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) {
		lwc_string_unref(ctx->mime_type);
		ctx->mime_type = NULL;
		return NSERROR_NOMEM;
	}

	/* Create the frontend window */
	ctx->window = guit->download->create(ctx, ctx->parent);
	if (ctx->window == NULL) {
		free(ctx->filename);
		ctx->filename = NULL;
		lwc_string_unref(ctx->mime_type);
		ctx->mime_type = NULL;
		return NSERROR_NOMEM;
	}

	return NSERROR_OK;
}