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

📄 httpheadertools.c

📁 -
💻 C
字号:
/* * $Id: HttpHeaderTools.c,v 1.24.2.1 1999/02/12 19:38:19 wessels Exp $ * * DEBUG: section 66    HTTP Header Tools * AUTHOR: Alex Rousskov * * 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"static int httpHeaderStrCmp(const char *h1, const char *h2, int len);static void httpHeaderPutStrvf(HttpHeader * hdr, http_hdr_type id, const char *fmt, va_list vargs);HttpHeaderFieldInfo *httpHeaderBuildFieldsInfo(const HttpHeaderFieldAttrs * attrs, int count){    int i;    HttpHeaderFieldInfo *table = NULL;    assert(attrs && count);    /* allocate space */    table = xcalloc(count, sizeof(HttpHeaderFieldInfo));    for (i = 0; i < count; ++i) {	const int id = attrs[i].id;	HttpHeaderFieldInfo *info = table + id;	/* sanity checks */	assert(id >= 0 && id < count);	assert(attrs[i].name);	assert(info->id == 0 && info->type == 0);	/* was not set before */	/* copy and init fields */	info->id = id;	info->type = attrs[i].type;	stringInit(&info->name, attrs[i].name);	assert(strLen(info->name));	/* init stats */	memset(&info->stat, 0, sizeof(info->stat));    }    return table;}voidhttpHeaderDestroyFieldsInfo(HttpHeaderFieldInfo * table, int count){    int i;    for (i = 0; i < count; ++i)	stringClean(&table[i].name);    xfree(table);}voidhttpHeaderMaskInit(HttpHeaderMask * mask, int value){    memset(mask, value, sizeof(*mask));}/* calculates a bit mask of a given array; does not reset mask! */voidhttpHeaderCalcMask(HttpHeaderMask * mask, const int *enums, int count){    int i;    assert(mask && enums);    assert(count < sizeof(*mask) * 8);	/* check for overflow */    for (i = 0; i < count; ++i) {	assert(!CBIT_TEST(*mask, enums[i]));	/* check for duplicates */	CBIT_SET(*mask, enums[i]);    }}/* same as httpHeaderPutStr, but formats the string using snprintf first */#if STDC_HEADERSvoidhttpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, const char *fmt,...){    va_list args;    va_start(args, fmt);#elsevoidhttpHeaderPutStrf(va_alist)     va_dcl{    va_list args;    HttpHeader *hdr = NULL;    http_hdr_type id = HDR_ENUM_END;    const char *fmt = NULL;    va_start(args);    hdr = va_arg(args, HttpHeader *);    id = va_arg(args, http_hdr_type);    fmt = va_arg(args, char *);#endif    httpHeaderPutStrvf(hdr, id, fmt, args);    va_end(args);}/* used by httpHeaderPutStrf */static voidhttpHeaderPutStrvf(HttpHeader * hdr, http_hdr_type id, const char *fmt, va_list vargs){    MemBuf mb;    memBufDefInit(&mb);    memBufVPrintf(&mb, fmt, vargs);    httpHeaderPutStr(hdr, id, mb.buf);    memBufClean(&mb);}/* wrapper arrounf PutContRange */voidhttpHeaderAddContRange(HttpHeader * hdr, HttpHdrRangeSpec spec, size_t ent_len){    HttpHdrContRange *cr = httpHdrContRangeCreate();    assert(hdr && ent_len >= 0);    httpHdrContRangeSet(cr, spec, ent_len);    httpHeaderPutContRange(hdr, cr);    httpHdrContRangeDestroy(cr);}/* * return true if a given directive is found in at least one of the "connection" header-fields * note: if HDR_PROXY_CONNECTION is present we ignore HDR_CONNECTION */inthttpHeaderHasConnDir(const HttpHeader * hdr, const char *directive){    if (httpHeaderHas(hdr, HDR_PROXY_CONNECTION)) {	const char *str = httpHeaderGetStr(hdr, HDR_PROXY_CONNECTION);	return str && !strcasecmp(str, directive);    }    if (httpHeaderHas(hdr, HDR_CONNECTION)) {	String str = httpHeaderGetList(hdr, HDR_CONNECTION);	const int res = strListIsMember(&str, directive, ',');	stringClean(&str);	return res;    }    return 0;}/* returns true iff "m" is a member of the list */intstrListIsMember(const String * list, const char *m, char del){    const char *pos = NULL;    const char *item;    assert(list && m);    while (strListGetItem(list, del, &item, NULL, &pos)) {	if (!strcasecmp(item, m))	    return 1;    }    return 0;}/* returns true iff "s" is a substring of a member of the list */intstrListIsSubstr(const String * list, const char *s, char del){    const char *pos = NULL;    const char *item;    assert(list && s);    while (strListGetItem(list, del, &item, NULL, &pos)) {	if (strstr(item, s))	    return 1;    }    return 0;}/* appends an item to the list */voidstrListAdd(String * str, const char *item, char del){    assert(str && item);    if (strLen(*str)) {	char buf[3];	buf[0] = del;	buf[1] = ' ';	buf[2] = '\0';	stringAppend(str, buf, 2);    }    stringAppend(str, item, strlen(item));}/* * iterates through a 0-terminated string of items separated by 'del's. * white space around 'del' is considered to be a part of 'del' * like strtok, but preserves the source, and can iterate several strings at once * * returns true if next item is found. * init pos with NULL to start iteration. */intstrListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos){    size_t len;    assert(str && item && pos);    if (*pos) {	if (!**pos)		/* end of string */	    return 0;	else	    (*pos)++;    } else {	*pos = strBuf(*str);	if (!*pos)	    return 0;    }    /* skip leading ws (ltrim) */    *pos += xcountws(*pos);    *item = *pos;		/* remember item's start */    /* find next delimiter */    *pos = strchr(*item, del);    if (!*pos)			/* last item */	*pos = *item + strlen(*item);    len = *pos - *item;		/* *pos points to del or '\0' */    /* rtrim */    while (len > 0 && xisspace((*item)[len - 1]))	len--;    if (ilen)	*ilen = len;    return len > 0;}/* handy to printf prefixes of potentially very long buffers */const char *getStringPrefix(const char *str, const char *end){#define SHORT_PREFIX_SIZE 512    LOCAL_ARRAY(char, buf, SHORT_PREFIX_SIZE);    const int sz = 1 + (end ? end - str : strlen(str));    xstrncpy(buf, str, (sz > SHORT_PREFIX_SIZE) ? SHORT_PREFIX_SIZE : sz);    return buf;}/* * parses an int field, complains if soemthing went wrong, returns true on * success */inthttpHeaderParseInt(const char *start, int *value){    assert(value);    *value = atoi(start);    if (!*value && !xisdigit(*start)) {	debug(66, 2) ("failed to parse an int header field near '%s'\n", start);	return 0;    }    return 1;}inthttpHeaderParseSize(const char *start, size_t * value){    int v;    const int res = httpHeaderParseInt(start, &v);    assert(value);    *value = res ? v : 0;    return res;}/* * parses a given string then packs compiled headers and compares the result * with the original, reports discrepancies */voidhttpHeaderTestParser(const char *hstr){    static int bug_count = 0;    int hstr_len;    int parse_success;    HttpHeader hdr;    int pos;    Packer p;    MemBuf mb;    assert(hstr);    /* skip start line if any */    if (!strncasecmp(hstr, "HTTP/", 5)) {	const char *p = strchr(hstr, '\n');	if (p)	    hstr = p + 1;    }    /* skip invalid first line if any */    if (xisspace(*hstr)) {	const char *p = strchr(hstr, '\n');	if (p)	    hstr = p + 1;    }    hstr_len = strlen(hstr);    /* skip terminator if any */    if (strstr(hstr, "\n\r\n"))	hstr_len -= 2;    else if (strstr(hstr, "\n\n"))	hstr_len -= 1;    httpHeaderInit(&hdr, hoReply);    /* debugLevels[55] = 8; */    parse_success = httpHeaderParse(&hdr, hstr, hstr + hstr_len);    /* debugLevels[55] = 2; */    if (!parse_success) {	debug(66, 2) ("TEST (%d): failed to parsed a header: {\n%s}\n", bug_count, hstr);	return;    }    /* we think that we parsed it, veryfy */    memBufDefInit(&mb);    packerToMemInit(&p, &mb);    httpHeaderPackInto(&hdr, &p);    if ((pos = abs(httpHeaderStrCmp(hstr, mb.buf, hstr_len)))) {	bug_count++;	debug(66, 2) ("TEST (%d): hdr parsing bug (pos: %d near '%s'): expected: {\n%s} got: {\n%s}\n",	    bug_count, pos, hstr + pos, hstr, mb.buf);    }    httpHeaderClean(&hdr);    packerClean(&p);    memBufClean(&mb);}/* like strncasecmp but ignores ws characters */static inthttpHeaderStrCmp(const char *h1, const char *h2, int len){    int len1 = 0;    int len2 = 0;    assert(h1 && h2);    /* fast check first */    if (!strncasecmp(h1, h2, len))	return 0;    while (1) {	const char c1 = xtoupper(h1[len1 += xcountws(h1 + len1)]);	const char c2 = xtoupper(h2[len2 += xcountws(h2 + len2)]);	if (c1 < c2)	    return -len1;	if (c1 > c2)	    return +len1;	if (!c1 && !c2)	    return 0;	if (c1)	    len1++;	if (c2)	    len2++;    }    return 0;}

⌨️ 快捷键说明

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