⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 data.c

📁 一个很有名的浏览器
💻 C
字号:
/* The "data" URI protocol implementation (RFC 2397) *//* $Id: data.c,v 1.9 2004/11/10 21:22:54 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "elinks.h"#include "cache/cache.h"#include "protocol/data.h"#include "protocol/protocol.h"#include "protocol/uri.h"#include "sched/connection.h"#include "util/base64.h"#include "util/string.h"/* The URLs are of the form: * *	data:[<mediatype>][;base64],<data> * * The <mediatype> is an Internet media type specification (with optional * parameters.) The appearance of ";base64" means that the data is encoded as * base64. Without ";base64", the data (as a sequence of octets) is represented * using ASCII encoding for octets inside the range of safe URL characters and * using the standard %xx hex encoding of URLs for octets outside that range. * If <mediatype> is omitted, it defaults to "text/plain;charset=US-ASCII".  As a * shorthand, "text/plain" can be omitted but the charset parameter supplied. * * The syntax: * *	dataurl	  := "data:" [ mediatype ] [ ";base64" ] "," data *	mediatype := [ type "/" subtype ] *( ";" parameter ) *	data	  := *urlchar *	parameter := attribute "=" value * * where "urlchar" is imported from [RFC2396], and "type", "subtype", * "attribute" and "value" are the corresponding tokens from [RFC2045], * represented using URL escaped encoding of [RFC2396] as necessary. * * Attribute values in [RFC2045] are allowed to be either represented as tokens * or as quoted strings. However, within a "data" URL, the "quoted-string" * representation would be awkward, since the quote mark is itself not a valid * urlchar. For this reason, parameter values should use the URL Escaped * encoding instead of quoted string if the parameter values contain any * "tspecial". * * The ";base64" extension is distinguishable from a content-type parameter by * the fact that it doesn't have a following "=" sign. *//* FIXME: Maybe some kind of redirecting to common specialized data URI could * be useful so "data:,blah" and data:text/plain,blah" are redirected to the * most specialized "data:text/plain;charset=US-ASCII,blah". On the other hand * for small entries it doesn't matter. */#define	DEFAULT_DATA_MEDIATYPE	"text/plain;charset=US-ASCII"#define data_has_mediatype(header, headerlen) \	((headerlen) >= 3 && memchr(header, '/', headerlen))#define data_has_base64_attribute(typelen, endstr) \	((typelen) >= sizeof(";base64") - 1 \	 && !memcmp(";base64", (end) - sizeof(";base64") + 1, sizeof(";base64") - 1))static unsigned char *init_data_protocol_header(struct cache_entry *cached,			  unsigned char *type, int typelen){	unsigned char *head;	assert(typelen);	type = memacpy(type, typelen);	if (!type) return NULL;	/* Set fake content type */	head = straconcat("\r\nContent-Type: ", type, "\r\n", NULL);	mem_free(type);	if (!head) return NULL;	mem_free_set(&cached->head, head);	return head;}static unsigned char *parse_data_protocol_header(struct connection *conn, int *base64){	struct uri *uri = conn->uri;	unsigned char *end = memchr(uri->data, ',', uri->datalen);	unsigned char *type = DEFAULT_DATA_MEDIATYPE;	int typelen = sizeof(DEFAULT_DATA_MEDIATYPE) - 1;	if (end) {		int headerlen = end - uri->data;		if (data_has_base64_attribute(headerlen, end)) {			*base64 = 1;			headerlen -= sizeof(";base64") - 1;		}		if (data_has_mediatype(uri->data, headerlen)) {			type	= uri->data;			typelen	= headerlen;		}	}	if (!init_data_protocol_header(conn->cached, type, typelen))		return NULL;	/* Return char after ',' or complete data part */	return end ? end + 1 : uri->data;}voiddata_protocol_handler(struct connection *conn){	struct uri *uri = conn->uri;	struct cache_entry *cached = get_cache_entry(uri);	unsigned char *data_start, *data;	int base64 = 0;	if (!cached) {		abort_conn_with_state(conn, S_OUT_OF_MEM);		return;	}	conn->cached = cached;	data_start = parse_data_protocol_header(conn, &base64);	if (!data_start) {		abort_conn_with_state(conn, S_OUT_OF_MEM);		return;	}	/* Allocate the data string because URI decoding will possibly modify	 * it. */	data = memacpy(data_start, uri->datalen - (data_start - uri->data));	if (!data) {		abort_conn_with_state(conn, S_OUT_OF_MEM);		return;	}	if (base64) {		unsigned char *decoded = base64_encode(data);		if (!decoded) {			abort_conn_with_state(conn, S_OUT_OF_MEM);			return;		}		mem_free_set(&data, decoded);	} else {		decode_uri(data);	}	/* This will not release the newly created header */	delete_entry_content(cached);	/* Use strlen() to get the correct decoded length */	add_fragment(cached, conn->from, data, strlen(data));	mem_free(data);	cached->incomplete = 0;	abort_conn_with_state(conn, S_OK);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -