Example #1
0
int
errorMapStart(const errormap * map, request_t * client_req, HttpReply * reply, const char *aclname, ERRMAPCB * callback, void *callback_data)
{
    char squid_error[100];
    int len = 0;
    const char *errorUrl;
    ErrorMapState *state;
    const char *tmp;
    http_status status;
    request_t *req;
    HttpHeaderPos hdrpos;
    HttpHeaderEntry *hdr;

    if (!client_req || !reply)
	return 0;

    status = reply->sline.status;

    tmp = httpHeaderGetStr(&reply->header, HDR_X_SQUID_ERROR);
    squid_error[0] = '\0';
    if (tmp) {
	xstrncpy(squid_error, tmp, sizeof(squid_error));
	len = strcspn(squid_error, " ");
    }
    squid_error[len] = '\0';
    errorUrl = getErrorMap(map, status, squid_error, aclname);
    if (!errorUrl)
	return 0;
    req = urlParse(urlMethodGetKnownByCode(METHOD_GET), (char *) errorUrl);
    if (!req) {
	debug(0, 0) ("errorMapStart: Invalid error URL '%s'\n", errorUrl);
	return 0;
    }
    req->urlgroup = xstrdup("error");

    state = cbdataAlloc(ErrorMapState);
    state->req = requestLink(req);
    state->e = storeCreateEntry(errorUrl, req->flags, req->method);
    state->sc = storeClientRegister(state->e, state);
    state->callback = callback;
    state->callback_data = callback_data;
    cbdataLock(callback_data);

    hdrpos = HttpHeaderInitPos;
    while ((hdr = httpHeaderGetEntry(&client_req->header, &hdrpos)) != NULL) {
	if (CBIT_TEST(client_headers, hdr->id))
	    httpHeaderAddClone(&req->header, hdr);
    }
    hdrpos = HttpHeaderInitPos;
    while ((hdr = httpHeaderGetEntry(&reply->header, &hdrpos)) != NULL) {
	if (CBIT_TEST(server_headers, hdr->id))
	    httpHeaderAddClone(&req->header, hdr);
    }
    httpHeaderPutInt(&req->header, HDR_X_ERROR_STATUS, (int) reply->sline.status);
    httpHeaderPutStr(&req->header, HDR_X_REQUEST_URI, urlCanonical(client_req));

    fwdStart(-1, state->e, req);
    storeClientRef(state->sc, state->e, 0, 0, SM_PAGE_SIZE, errorMapFetchHeaders, state);
    return 1;
}
/* return a list of entries with the same id separated by ',' and ws */
String
httpHeaderGetList(const HttpHeader * hdr, http_hdr_type id)
{
    String s = StringNull;
    HttpHeaderEntry *e;
    HttpHeaderPos pos = HttpHeaderInitPos;
    debug(55, 6) ("%p: joining for id %d\n", hdr, id);
    /* only fields from ListHeaders array can be "listed" */
    assert(CBIT_TEST(ListHeadersMask, id));
    if (!CBIT_TEST(hdr->mask, id))
	return s;
    while ((e = httpHeaderGetEntry(hdr, &pos))) {
	if (e->id == id)
	    strListAdd(&s, strBuf(e->value), ',');
    }
    /*
     * note: we might get an empty (len==0) string if there was an "empty"
     * header; we must not get a NULL string though.
     */
    assert(strBuf(s));
    /* temporary warning: remove it! @?@ @?@ @?@ */
    if (!strLen(s))
	debug(55, 3) ("empty list header: %s (%d)\n", strBuf(Headers[id].name), id);
    debug(55, 6) ("%p: joined for id %d: %s\n", hdr, id, strBuf(s));
    return s;
}
Example #3
0
/* use fresh entries to replace old ones */
void
httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask)
{
    const HttpHeaderEntry *e;
    HttpHeaderPos pos = HttpHeaderInitPos;

    assert(old && fresh);
    assert(old != fresh);
    debug(55, 7) ("updating hdr: %p <- %p\n", old, fresh);

    while ((e = httpHeaderGetEntry(fresh, &pos))) {
	/* deny bad guys (ok to check for HDR_OTHER) here */
	if (denied_mask && CBIT_TEST(*denied_mask, e->id))
	    continue;
	if (e->id != HDR_OTHER)
	    httpHeaderDelById(old, e->id);
	else
	    httpHeaderDelByName(old, strBuf(e->name));
    }
    pos = HttpHeaderInitPos;
    while ((e = httpHeaderGetEntry(fresh, &pos))) {
	/* deny bad guys (ok to check for HDR_OTHER) here */
	if (denied_mask && CBIT_TEST(*denied_mask, e->id))
	    continue;
	httpHeaderAddClone(old, e);
    }

    /* And now, repack the array to "fill in the holes" */
    httpHeaderRepack(old);
}
Example #4
0
/* returns true if the key belongs to the digest */
int
cacheDigestTest(const CacheDigest * cd, const cache_key * key)
{
	assert(cd && key);
	/* hash */
	cacheDigestHashKey(cd, key);
	/* test corresponding bits */
	return
		CBIT_TEST(cd->mask, hashed_keys[0]) &&
		CBIT_TEST(cd->mask, hashed_keys[1]) &&
		CBIT_TEST(cd->mask, hashed_keys[2]) &&
		CBIT_TEST(cd->mask, hashed_keys[3]);
}
Example #5
0
/*
 *?µIJ??ҷ?ʽ??һЩsquid??????????header?IJ???
 */
static HttpHeaderEntry* httpHeaderFindEntry2(const HttpHeader * hdr, http_hdr_type id)
{
	//zhb:let it be faster
	HttpHeaderPos pos = HttpHeaderInitPos + HDR_ENUM_END;
	HttpHeaderEntry *e;         
	assert(hdr);
	//assert_eid(id);

	/* check mask first */
	if (!CBIT_TEST(hdr->mask, id))
		return NULL;
	
	if(id != HDR_OTHER)
	{
		return hdr->entries.items[hdr->pSearch[id]];
	}
	/* looks like we must have it, do linear search */
	while ((e = httpHeaderGetEntryPlus(hdr, &pos)))
	{
		if (e->id == id)
			return e;
	}

	/* hm.. we thought it was there, but it was not found */
	assert(0);            
	return NULL;        /* not reached */
}
Example #6
0
/* returns mask utilization parameters */
static void
cacheDigestStats(const CacheDigest * cd, CacheDigestStats * stats)
{
	int on_count = 0;
	int pos = cd->mask_size * 8;
	int seq_len_sum = 0;
	int seq_count = 0;
	int cur_seq_len = 0;
	int cur_seq_type = 1;
	assert(stats);
	memset(stats, 0, sizeof(*stats));
	while (pos-- > 0)
	{
		const int is_on = CBIT_TEST(cd->mask, pos);
		if (is_on)
			on_count++;
		if (is_on != cur_seq_type || !pos)
		{
			seq_len_sum += cur_seq_len;
			seq_count++;
			cur_seq_type = is_on;
			cur_seq_len = 0;
		}
		cur_seq_len++;
	}
	stats->bit_count = cd->mask_size * 8;
	stats->bit_on_count = on_count;
	stats->bseq_len_sum = seq_len_sum;
	stats->bseq_count = seq_count;
}
Example #7
0
/* returns true if header is allowed to be passed on */
int
httpRequestHdrAllowedByName(http_hdr_type id)
{
    /* check with anonymizer tables */
    if (CBIT_TEST(Config.anonymize_headers, id))
	return 0;
    return 1;
}
/* test if a field is present */
int
httpHeaderHas(const HttpHeader * hdr, http_hdr_type id)
{
    assert(hdr);
    assert_eid(id);
    assert(id != HDR_OTHER);
    debug(55, 7) ("%p lookup for %d\n", hdr, id);
    return CBIT_TEST(hdr->mask, id);
}
Example #9
0
/* returns true if header is allowed to be passed on */
int
httpRequestHdrAllowed(const HttpHeaderEntry * e, String * strConn)
{
    assert(e);
    /* check with anonymizer tables */
    if (CBIT_TEST(Config.anonymize_headers, e->id))
	return 0;
    /* check connection header */
    if (strConn && strListIsMember(strConn, strBuf(e->name), ','))
	return 0;
    return 1;
}
/*
 * same as httpHeaderFindEntry
 */
static HttpHeaderEntry *
httpHeaderFindLastEntry(const HttpHeader * hdr, http_hdr_type id)
{
    HttpHeaderPos pos = HttpHeaderInitPos;
    HttpHeaderEntry *e;
    HttpHeaderEntry *result = NULL;
    assert(hdr);
    assert_eid(id);
    assert(!CBIT_TEST(ListHeadersMask, id));

    /* check mask first */
    if (!CBIT_TEST(hdr->mask, id))
	return NULL;
    /* looks like we must have it, do linear search */
    while ((e = httpHeaderGetEntry(hdr, &pos))) {
	if (e->id == id)
	    result = e;
    }
    assert(result);		/* must be there! */
    return result;
}
/* calculates a bit mask of a given array; does not reset mask! */
void
httpHeaderCalcMask(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]);
    }
}
/*
 * returns a pointer to a specified entry if any 
 * note that we return one entry so it does not make much sense to ask for
 * "list" headers
 */
HttpHeaderEntry *
httpHeaderFindEntry(const HttpHeader * hdr, http_hdr_type id)
{
    HttpHeaderPos pos = HttpHeaderInitPos;
    HttpHeaderEntry *e;
    assert(hdr);
    assert_eid(id);
    assert(!CBIT_TEST(ListHeadersMask, id));

    /* check mask first */
    if (!CBIT_TEST(hdr->mask, id))
	return NULL;
    /* looks like we must have it, do linear search */
    while ((e = httpHeaderGetEntry(hdr, &pos))) {
	if (e->id == id)
	    return e;
    }
    /* hm.. we thought it was there, but it was not found */
    assert(0);
    return NULL;		/* not reached */
}
Example #13
0
void
cacheDigestAdd(CacheDigest * cd, const cache_key * key)
{
	assert(cd && key);
	/* hash */
	cacheDigestHashKey(cd, key);
	/* turn on corresponding bits */
#if CD_FAST_ADD
	CBIT_SET(cd->mask, hashed_keys[0]);
	CBIT_SET(cd->mask, hashed_keys[1]);
	CBIT_SET(cd->mask, hashed_keys[2]);
	CBIT_SET(cd->mask, hashed_keys[3]);
#else
	{
		int on_xition_cnt = 0;
		if (!CBIT_TEST(cd->mask, hashed_keys[0]))
		{
			CBIT_SET(cd->mask, hashed_keys[0]);
			on_xition_cnt++;
		}
		if (!CBIT_TEST(cd->mask, hashed_keys[1]))
		{
			CBIT_SET(cd->mask, hashed_keys[1]);
			on_xition_cnt++;
		}
		if (!CBIT_TEST(cd->mask, hashed_keys[2]))
		{
			CBIT_SET(cd->mask, hashed_keys[2]);
			on_xition_cnt++;
		}
		if (!CBIT_TEST(cd->mask, hashed_keys[3]))
		{
			CBIT_SET(cd->mask, hashed_keys[3]);
			on_xition_cnt++;
		}
		statHistCount(&statCounter.cd.on_xition_count, on_xition_cnt);
	}
#endif
	cd->count++;
}
static void
httpHeaderFieldStatDumper(StoreEntry * sentry, int idx, double val, double size, int count)
{
    const int id = (int) val;
    const int valid_id = id >= 0 && id < HDR_ENUM_END;
    const char *name = valid_id ? strBuf(Headers[id].name) : "INVALID";
    int visible = count > 0;
    /* for entries with zero count, list only those that belong to current type of message */
    if (!visible && valid_id && dump_stat->owner_mask)
	visible = CBIT_TEST(*dump_stat->owner_mask, id);
    if (visible)
	storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n",
	    id, name, count, xdiv(count, dump_stat->busyDestroyedCount));
}
/* return a string or list of entries with the same id separated by ',' and ws */
String
httpHeaderGetStrOrList(const HttpHeader * hdr, http_hdr_type id)
{
    HttpHeaderEntry *e;

    if (CBIT_TEST(ListHeadersMask, id))
	return httpHeaderGetList(hdr, id);
    if ((e = httpHeaderFindEntry(hdr, id))) {
	String s;
	stringInit(&s, strBuf(e->value));
	return s;
    }
    return StringNull;
}
HttpHdrCc *
httpHeaderGetCc(const HttpHeader * hdr)
{
    HttpHdrCc *cc;
    String s;
    if (!CBIT_TEST(hdr->mask, HDR_CACHE_CONTROL))
	return NULL;
    s = httpHeaderGetList(hdr, HDR_CACHE_CONTROL);
    cc = httpHdrCcParseCreate(&s);
    HttpHeaderStats[hdr->owner].ccParsedCount++;
    if (cc)
	httpHdrCcUpdateStats(cc, &HttpHeaderStats[hdr->owner].ccTypeDistr);
    httpHeaderNoteParsedEntry(HDR_CACHE_CONTROL, s, !cc);
    stringClean(&s);
    return cc;
}
/* appends an entry; 
 * does not call httpHeaderEntryClone() so one should not reuse "*e"
 */
void
httpHeaderAddEntry(HttpHeader * hdr, HttpHeaderEntry * e)
{
    assert(hdr && e);
    assert_eid(e->id);

    debug(55, 7) ("%p adding entry: %d at %d\n",
	hdr, e->id, hdr->entries.count);
    if (CBIT_TEST(hdr->mask, e->id))
	Headers[e->id].stat.repCount++;
    else
	CBIT_SET(hdr->mask, e->id);
    arrayAppend(&hdr->entries, e);
    /* increment header length, allow for ": " and crlf */
    hdr->len += strLen(e->name) + 2 + strLen(e->value) + 2;
}
/* use fresh entries to replace old ones */
void
httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask)
{
    const HttpHeaderEntry *e;
    HttpHeaderPos pos = HttpHeaderInitPos;
    assert(old && fresh);
    assert(old != fresh);
    debug(55, 7) ("updating hdr: %p <- %p\n", old, fresh);

    while ((e = httpHeaderGetEntry(fresh, &pos))) {
	/* deny bad guys (ok to check for HDR_OTHER) here */
	if (denied_mask && CBIT_TEST(*denied_mask, e->id))
	    continue;
	httpHeaderDelByName(old, strBuf(e->name));
	httpHeaderAddEntry(old, httpHeaderEntryClone(e));
    }
}
/* deletes all entries with a given id, returns the #entries deleted */
int
httpHeaderDelById(HttpHeader * hdr, http_hdr_type id)
{
    int count = 0;
    HttpHeaderPos pos = HttpHeaderInitPos;
    HttpHeaderEntry *e;
    debug(55, 8) ("%p del-by-id %d\n", hdr, id);
    assert(hdr);
    assert_eid(id);
    assert(id != HDR_OTHER);	/* does not make sense */
    if (!CBIT_TEST(hdr->mask, id))
	return 0;
    while ((e = httpHeaderGetEntry(hdr, &pos))) {
	if (e->id == id) {
	    httpHeaderDelAt(hdr, pos);
	    count++;
	}
    }
    CBIT_CLR(hdr->mask, id);
    assert(count);
    return count;
}