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

📄 mime.c

📁 -
💻 C
字号:
/* * $Id: mime.c,v 1.84.2.3 1999/02/12 22:18:59 wessels Exp $ * * DEBUG: section 25    MIME Parsing * AUTHOR: Harvest Derived * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  This program 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; either version 2 of the License, or *  (at your option) any later version. *   *  This program 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, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"#define GET_HDR_SZ 1024typedef struct _mime_entry {    char *pattern;    regex_t compiled_pattern;    char *icon;    char *content_type;    char *content_encoding;    char transfer_mode;    unsigned int view_option:1, download_option:1;    struct _mime_entry *next;} mimeEntry;static mimeEntry *MimeTable = NULL;static mimeEntry **MimeTableTail = NULL;static void mimeLoadIconFile(const char *icon);/* returns a pointer to a field-value of the first matching field-name */char *mime_get_header(const char *mime, const char *name){    return mime_get_header_field(mime, name, NULL);}/* * returns a pointer to a field-value of the first matching field-name where * field-value matches prefix if any */char *mime_get_header_field(const char *mime, const char *name, const char *prefix){    LOCAL_ARRAY(char, header, GET_HDR_SZ);    const char *p = NULL;    char *q = NULL;    char got = 0;    const int namelen = name ? strlen(name) : 0;    const int preflen = prefix ? strlen(prefix) : 0;    int l;    if (NULL == mime)	return NULL;    assert(NULL != name);    debug(25, 5) ("mime_get_header: looking for '%s'\n", name);    for (p = mime; *p; p += strcspn(p, "\n\r")) {	if (strcmp(p, "\r\n\r\n") == 0 || strcmp(p, "\n\n") == 0)	    return NULL;	while (xisspace(*p))	    p++;	if (strncasecmp(p, name, namelen))	    continue;	if (!xisspace(p[namelen]) && p[namelen] != ':')	    continue;	l = strcspn(p, "\n\r") + 1;	if (l > GET_HDR_SZ)	    l = GET_HDR_SZ;	xstrncpy(header, p, l);	debug(25, 5) ("mime_get_header: checking '%s'\n", header);	q = header;	q += namelen;	if (*q == ':')	    q++, got = 1;	while (xisspace(*q))	    q++, got = 1;	if (got && prefix) {	    /* we could process list entries here if we had strcasestr(). */	    /* make sure we did not match a part of another field-value */	    got = !strncasecmp(q, prefix, preflen) && !xisalpha(q[preflen]);	}	if (got) {	    debug(25, 5) ("mime_get_header: returning '%s'\n", q);	    return q;	}    }    return NULL;}size_theadersEnd(const char *mime, size_t l){    size_t e = 0;    int state = 0;    while (e < l && state < 3) {	switch (state) {	case 0:	    if ('\n' == mime[e])		state = 1;	    break;	case 1:	    if ('\r' == mime[e])		state = 2;	    else if ('\n' == mime[e])		state = 3;	    else		state = 0;	    break;	case 2:	    if ('\r' == mime[e])	/* ignore repeated CR */		(void) 0;	    else if ('\n' == mime[e])		state = 3;	    else		state = 0;	    break;	default:	    break;	}	e++;    }    if (3 == state)	return e;    return 0;}const char *mime_get_auth(const char *hdr, const char *auth_scheme, const char **auth_field){    char *auth_hdr;    char *t;    if (auth_field)	*auth_field = NULL;    if (hdr == NULL)	return NULL;    if ((auth_hdr = mime_get_header(hdr, "Authorization")) == NULL)	return NULL;    if (auth_field)	*auth_field = auth_hdr;    if ((t = strtok(auth_hdr, " \t")) == NULL)	return NULL;    if (strcasecmp(t, auth_scheme) != 0)	return NULL;    if ((t = strtok(NULL, " \t")) == NULL)	return NULL;    return base64_decode(t);}static mimeEntry *mimeGetEntry(const char *fn, int skip_encodings){    mimeEntry *m;    char *t;    char *name = xstrdup(fn);  try_again:    for (m = MimeTable; m; m = m->next) {	if (regexec(&m->compiled_pattern, name, 0, 0, 0) == 0)	    break;    }    if (!skip_encodings)	(void) 0;    else if (m == NULL)	(void) 0;    else if (strcmp(m->content_type, dash_str))	(void) 0;    else if (!strcmp(m->content_encoding, dash_str))	(void) 0;    else {	/* Assume we matched /\.\w$/ and cut off the last extension */	if ((t = strrchr(name, '.'))) {	    *t = '\0';	    goto try_again;	}	/* What? A encoding without a extension? */	m = NULL;    }    xfree(name);    return m;}char *mimeGetIcon(const char *fn){    mimeEntry *m = mimeGetEntry(fn, 1);    if (m == NULL)	return NULL;    if (!strcmp(m->icon, dash_str))	return NULL;    return m->icon;}char *mimeGetIconURL(const char *fn){    char *icon = mimeGetIcon(fn);    if (icon == NULL)	return NULL;    return internalLocalUri("/squid-internal-static/icons/", icon);}char *mimeGetContentType(const char *fn){    mimeEntry *m = mimeGetEntry(fn, 1);    if (m == NULL)	return NULL;    if (!strcmp(m->content_type, dash_str))	return NULL;    return m->content_type;}char *mimeGetContentEncoding(const char *fn){    mimeEntry *m = mimeGetEntry(fn, 0);    if (m == NULL)	return NULL;    if (!strcmp(m->content_encoding, dash_str))	return NULL;    return m->content_encoding;}charmimeGetTransferMode(const char *fn){    mimeEntry *m = mimeGetEntry(fn, 0);    return m ? m->transfer_mode : 'I';}intmimeGetDownloadOption(const char *fn){    mimeEntry *m = mimeGetEntry(fn, 1);    return m ? m->download_option : 0;}intmimeGetViewOption(const char *fn){    mimeEntry *m = mimeGetEntry(fn, 0);    return m ? m->view_option : 0;}voidmimeInit(char *filename){    FILE *fp;    char buf[BUFSIZ];    char chopbuf[BUFSIZ];    char *t;    char *pattern;    char *icon;    char *type;    char *encoding;    char *mode;    char *option;    int view_option;    int download_option;    regex_t re;    mimeEntry *m;    int re_flags = REG_EXTENDED | REG_NOSUB | REG_ICASE;    if (filename == NULL)	return;    if ((fp = fopen(filename, "r")) == NULL) {	debug(50, 1) ("mimeInit: %s: %s\n", filename, xstrerror());	return;    }    if (MimeTableTail == NULL)	MimeTableTail = &MimeTable;    while (fgets(buf, BUFSIZ, fp)) {	if ((t = strchr(buf, '#')))	    *t = '\0';	if ((t = strchr(buf, '\r')))	    *t = '\0';	if ((t = strchr(buf, '\n')))	    *t = '\0';	if (buf[0] == '\0')	    continue;	xstrncpy(chopbuf, buf, BUFSIZ);	if ((pattern = strtok(chopbuf, w_space)) == NULL) {	    debug(25, 1) ("mimeInit: parse error: '%s'\n", buf);	    continue;	}	if ((type = strtok(NULL, w_space)) == NULL) {	    debug(25, 1) ("mimeInit: parse error: '%s'\n", buf);	    continue;	}	if ((icon = strtok(NULL, w_space)) == NULL) {	    debug(25, 1) ("mimeInit: parse error: '%s'\n", buf);	    continue;	}	if ((encoding = strtok(NULL, w_space)) == NULL) {	    debug(25, 1) ("mimeInit: parse error: '%s'\n", buf);	    continue;	}	if ((mode = strtok(NULL, w_space)) == NULL) {	    debug(25, 1) ("mimeInit: parse error: '%s'\n", buf);	    continue;	}	download_option = 0;	view_option = 0;	while ((option = strtok(NULL, w_space)) != NULL) {	    if (!strcmp(option, "+download"))		download_option = 1;	    else if (!strcmp(option, "+view"))		view_option = 1;	    else		debug(25, 1) ("mimeInit: unknown option: '%s' (%s)\n", buf, option);	}	if (regcomp(&re, pattern, re_flags) != 0) {	    debug(25, 1) ("mimeInit: regcomp error: '%s'\n", buf);	    continue;	}	m = xcalloc(1, sizeof(mimeEntry));	m->pattern = xstrdup(pattern);	m->content_type = xstrdup(type);	m->icon = xstrdup(icon);	m->content_encoding = xstrdup(encoding);	m->compiled_pattern = re;	if (!strcasecmp(mode, "ascii"))	    m->transfer_mode = 'A';	else if (!strcasecmp(mode, "text"))	    m->transfer_mode = 'A';	else	    m->transfer_mode = 'I';	m->view_option = view_option;	m->download_option = download_option;	*MimeTableTail = m;	MimeTableTail = &m->next;	debug(25, 5) ("mimeInit: added '%s'\n", buf);    }    fclose(fp);    /*     * Create Icon StoreEntry's     */    for (m = MimeTable; m != NULL; m = m->next)	mimeLoadIconFile(m->icon);    debug(25, 1) ("Loaded Icons.\n");}voidmimeFreeMemory(void){    mimeEntry *m;    while ((m = MimeTable)) {	MimeTable = m->next;	safe_free(m->pattern);	safe_free(m->content_type);	safe_free(m->icon);	safe_free(m->content_encoding);	regfree(&m->compiled_pattern);	safe_free(m);    }    MimeTableTail = &MimeTable;}static voidmimeLoadIconFile(const char *icon){    int fd;    int n;    request_flags flags;    struct stat sb;    StoreEntry *e;    LOCAL_ARRAY(char, path, MAXPATHLEN);    LOCAL_ARRAY(char, url, MAX_URL);    char *buf;    const char *type = mimeGetContentType(icon);    HttpReply *reply;    if (type == NULL)	fatal("Unknown icon format while reading mime.conf\n");    buf = internalLocalUri("/squid-internal-static/icons/", icon);    xstrncpy(url, buf, MAX_URL);    if (storeGetPublic(url, METHOD_GET))	return;    snprintf(path, MAXPATHLEN, "%s/%s", Config.icons.directory, icon);    fd = file_open(path, O_RDONLY, NULL, NULL, NULL);    if (fd < 0) {	debug(25, 0) ("mimeLoadIconFile: %s: %s\n", path, xstrerror());	return;    }    if (fstat(fd, &sb) < 0) {	debug(50, 0) ("mimeLoadIconFile: FD %d: fstat: %s\n", fd, xstrerror());	return;    }    flags = null_request_flags;    flags.cachable = 1;    e = storeCreateEntry(url,	url,	flags,	METHOD_GET);    assert(e != NULL);    storeSetPublicKey(e);    e->mem_obj->request = requestLink(urlParse(METHOD_GET, url));    httpReplyReset(reply = e->mem_obj->reply);    httpReplySetHeaders(reply, 1.0, HTTP_OK, NULL,	type, (int) sb.st_size, sb.st_mtime, -1);    reply->cache_control = httpHdrCcCreate();    httpHdrCcSetMaxAge(reply->cache_control, 86400);    httpHeaderPutCc(&reply->header, reply->cache_control);    httpReplySwapOut(reply, e);    /* read the file into the buffer and append it to store */    buf = memAllocate(MEM_4K_BUF);    while ((n = read(fd, buf, 4096)) > 0)	storeAppend(e, buf, n);    file_close(fd);    storeComplete(e);    storeTimestampsSet(e);    EBIT_SET(e->flags, ENTRY_SPECIAL);    debug(25, 3) ("Loaded icon %s\n", url);    storeUnlockObject(e);    memFree(buf, MEM_4K_BUF);}

⌨️ 快捷键说明

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