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

📄 refresh.c

📁 -
💻 C
字号:
/* * $Id: refresh.c,v 1.47 1999/01/19 23:18:01 wessels Exp $ * * DEBUG: section 22    Refresh Calculation * 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. * */#ifndef USE_POSIX_REGEX#define USE_POSIX_REGEX		/* put before includes; always use POSIX */#endif#include "squid.h"typedef enum {    rcHTTP, rcICP, rcCDigest, rcStore, rcCount} refreshCountsEnum;static struct RefreshCounts {    const char *proto;    int total;    int revalidate_stale;    int request_max_age_stale;    int request_reload2ims_stale;    int request_reload_stale;    int negative_age_stale;    int min_age_override_exp_fresh;    int min_age_override_lmt_fresh;    int response_expires_stale;    int response_expires_fresh;    int conf_max_age_stale;    int last_modified_factor_fresh;    int last_modified_factor_stale;    int response_lmt_now_stale;    int conf_min_age_fresh;    int default_stale;    /* maybe-counters -- intermediate decisions that may affect the result */    int request_reload_ignore_maybe;    int response_lmt_future_maybe;} refreshCounts[rcCount];/* * Defaults: *      MIN     NONE *      PCT     20% *      MAX     3 days */#define REFRESH_DEFAULT_MIN	(time_t)0#define REFRESH_DEFAULT_PCT	0.20#define REFRESH_DEFAULT_MAX	(time_t)259200static const refresh_t *refreshLimits(const char *);static const refresh_t *refreshUncompiledPattern(const char *);static OBJH refreshStats;static const refresh_t *refreshLimits(const char *url){    const refresh_t *R;    for (R = Config.Refresh; R; R = R->next) {	if (!regexec(&(R->compiled_pattern), url, 0, 0, 0))	    return R;    }    return NULL;}static const refresh_t *refreshUncompiledPattern(const char *pat){    const refresh_t *R;    for (R = Config.Refresh; R; R = R->next) {	if (0 == strcmp(R->pattern, pat))	    return R;    }    return NULL;}/*  return 1 if the entry must be revalidated within delta seconds *         0 otherwise * *  note: request maybe null (e.g. for cache digests build) */static intrefreshCheck(const StoreEntry * entry, request_t * request, time_t delta, struct RefreshCounts *rc){    const refresh_t *R;    const char *uri = NULL;    time_t min = REFRESH_DEFAULT_MIN;    double pct = REFRESH_DEFAULT_PCT;    time_t max = REFRESH_DEFAULT_MAX;#if HTTP_VIOLATIONS    int override_expire = 0;    int override_lastmod = 0;    int reload_into_ims = 0;    int ignore_reload = 0;#endif    const char *pattern = "<none>";    time_t age;    double factor;    time_t check_time = squid_curtime + delta;    if (entry->mem_obj)	uri = entry->mem_obj->url;    else if (request)	uri = urlCanonical(request);    debug(22, 3) ("refreshCheck(%s): '%s'\n", rc->proto, uri ? uri : "<none>");    rc->total++;    if (EBIT_TEST(entry->flags, ENTRY_REVALIDATE)) {	debug(22, 3) ("refreshCheck: YES: Required Authorization\n");	rc->revalidate_stale++;	return 1;    }    if ((R = uri ? refreshLimits(uri) : refreshUncompiledPattern("."))) {	min = R->min;	pct = R->pct;	max = R->max;	pattern = R->pattern;#if HTTP_VIOLATIONS	override_expire = R->flags.override_expire;	override_lastmod = R->flags.override_lastmod;	reload_into_ims = R->flags.reload_into_ims;	ignore_reload = R->flags.ignore_reload;#endif    }#if HTTP_VIOLATIONS    if (!reload_into_ims)	reload_into_ims = Config.onoff.reload_into_ims;#endif    debug(22, 3) ("refreshCheck: Matched '%s %d %d%% %d'\n",	pattern, (int) min, (int) (100.0 * pct), (int) max);    age = check_time - entry->timestamp;    debug(22, 3) ("refreshCheck: age = %d\n", (int) age);    debug(22, 3) ("\tcheck_time:\t%s\n", mkrfc1123(check_time));    debug(22, 3) ("\tentry->timestamp:\t%s\n", mkrfc1123(entry->timestamp));    /* request-specific checks */    if (request) {#if HTTP_VIOLATIONS	if (request->flags.nocache_hack) {	    if (ignore_reload) {		/* The clients no-cache header is ignored */		debug(22, 3) ("refreshCheck: MAYBE: ignore-reload\n");		rc->request_reload_ignore_maybe++;	    } else if (reload_into_ims) {		/* The clients no-cache header is changed into a IMS query */		debug(22, 3) ("refreshCheck: YES: reload-into-ims\n");		rc->request_reload2ims_stale++;		return 1;	    } else {		/* The clients no-cache header is not overridden on this request */		debug(22, 3) ("refreshCheck: YES: client reload\n");		request->flags.nocache = 1;		rc->request_reload_stale++;		return 1;	    }	}#endif	if (age < 0) {	    debug(22, 3) ("refreshCheck: YES: age < 0\n");	    rc->negative_age_stale++;	    return 1;	}	if (request->cache_control && request->cache_control->max_age > -1) {	    if (age > request->cache_control->max_age) {		debug(22, 3) ("refreshCheck: YES: age > client-max-age\n");		rc->request_max_age_stale++;		return 1;	    }	}    }#if HTTP_VIOLATIONS    if (override_expire && age <= min) {	debug(22, 3) ("refreshCheck: NO: age < min && override_expire\n");	rc->min_age_override_exp_fresh++;	return 0;    }#endif    if (entry->expires > -1) {	if (entry->expires <= check_time) {	    debug(22, 3) ("refreshCheck: YES: expires <= curtime\n");	    rc->response_expires_stale++;	    return 1;	} else {	    debug(22, 3) ("refreshCheck: NO: expires > curtime\n");	    rc->response_expires_fresh++;	    return 0;	}    }    if (age > max) {	debug(22, 3) ("refreshCheck: YES: age > max\n");	rc->conf_max_age_stale++;	return 1;    }#if HTTP_VIOLATIONS    if (override_lastmod && age <= min) {	debug(22, 3) ("refreshCheck: NO: age < min && override_lastmod\n");	rc->min_age_override_lmt_fresh++;	return 0;    }#endif    if (entry->lastmod > -1 && entry->timestamp > entry->lastmod) {	factor = (double) age / (double) (entry->timestamp - entry->lastmod);	debug(22, 3) ("refreshCheck: factor = %f\n", factor);	if (factor < pct) {	    debug(22, 3) ("refreshCheck: NO: factor < pct\n");	    rc->last_modified_factor_fresh++;	    return 0;	} else {	    debug(22, 3) ("refreshCheck: YES: factor >= pct\n");	    rc->last_modified_factor_stale++;	    return 1;	}    } else if (entry->lastmod > -1 && entry->timestamp == entry->lastmod) {	debug(22, 3) ("refreshCheck: YES: last-modified 'now'\n");	rc->response_lmt_now_stale++;	return 1;    } else if (entry->lastmod > -1 && entry->timestamp < entry->lastmod) {	debug(22, 3) ("refreshCheck: MAYBE: last-modified in the future\n");	rc->response_lmt_future_maybe++;    }    if (age <= min) {	debug(22, 3) ("refreshCheck: NO: age <= min\n");	rc->conf_min_age_fresh++;	return 0;    }    debug(22, 3) ("refreshCheck: YES: default stale\n");    rc->default_stale++;    return 1;}intrefreshIsCachable(const StoreEntry * entry){    /*     * Don't look at the request to avoid no-cache and other nuisances.     * the object should have a mem_obj so the URL will be found there.     * 60 seconds delta, to avoid objects which expire almost     * immediately, and which can't be refreshed.     */    if (!refreshCheck(entry, NULL, 60, &refreshCounts[rcStore]))	/* Does not need refresh. This is certainly cachable */	return 1;    if (entry->lastmod < 0)	/* Last modified is needed to do a refresh */	return 0;    if (entry->mem_obj == NULL)	/* no mem_obj? */	return 1;    if (entry->mem_obj->reply)	/* no reply? */	return 1;    if (entry->mem_obj->reply->content_length == 0)	/* No use refreshing (caching?) 0 byte objects */	return 0;    /* This seems to be refreshable. Cache it */    return 1;}/* refreshCheck... functions below are protocol-specific wrappers around * refreshCheck() function above */intrefreshCheckHTTP(const StoreEntry * entry, request_t * request){    return refreshCheck(entry, request, 0, &refreshCounts[rcHTTP]);}intrefreshCheckICP(const StoreEntry * entry, request_t * request){    return refreshCheck(entry, request, 30, &refreshCounts[rcICP]);}intrefreshCheckDigest(const StoreEntry * entry, time_t delta){    return refreshCheck(entry,	entry->mem_obj ? entry->mem_obj->request : NULL,	delta,	&refreshCounts[rcCDigest]);}time_tgetMaxAge(const char *url){    const refresh_t *R;    debug(22, 3) ("getMaxAge: '%s'\n", url);    if ((R = refreshLimits(url)))	return R->max;    else	return REFRESH_DEFAULT_MAX;}static voidrefreshCountsStats(StoreEntry * sentry, struct RefreshCounts *rc){    int sum = 0;    int tot = rc->total;    storeAppendPrintf(sentry, "\n\n%s histogram:\n", rc->proto);    storeAppendPrintf(sentry, "Category\tCount\t%%Total\n");#define refreshCountsStatsEntry(name) { \    if (rc->name || !strcmp(#name, "total")) \	storeAppendPrintf(sentry, "%s\t%6d\t%6.2f\n", \	    #name, rc->name, xpercent(rc->name, tot)); \    sum += rc->name; \}    refreshCountsStatsEntry(revalidate_stale);    refreshCountsStatsEntry(request_reload2ims_stale);    refreshCountsStatsEntry(request_reload_stale);    refreshCountsStatsEntry(request_max_age_stale);    refreshCountsStatsEntry(min_age_override_exp_fresh);    refreshCountsStatsEntry(response_expires_stale);    refreshCountsStatsEntry(response_expires_fresh);    refreshCountsStatsEntry(conf_max_age_stale);    refreshCountsStatsEntry(min_age_override_lmt_fresh);    refreshCountsStatsEntry(last_modified_factor_fresh);    refreshCountsStatsEntry(last_modified_factor_stale);    refreshCountsStatsEntry(response_lmt_now_stale);    refreshCountsStatsEntry(conf_min_age_fresh);    refreshCountsStatsEntry(default_stale);    tot = sum;			/* paranoid: "total" line shows 100% if we forgot nothing */    refreshCountsStatsEntry(total);    /* maybe counters */    refreshCountsStatsEntry(request_reload_ignore_maybe);    refreshCountsStatsEntry(response_lmt_future_maybe);}static voidrefreshStats(StoreEntry * sentry){    int i;    int total = 0;    /* get total usage count */    for (i = 0; i < rcCount; ++i)	total += refreshCounts[i].total;    /* protocol usage histogram */    storeAppendPrintf(sentry, "\nRefreshCheck calls per protocol\n\n");    storeAppendPrintf(sentry, "Protocol\t#Calls\t%%Calls\n");    for (i = 0; i < rcCount; ++i)	storeAppendPrintf(sentry, "%10s\t%6d\t%6.2f\n",	    refreshCounts[i].proto,	    refreshCounts[i].total,	    xpercent(refreshCounts[i].total, total));    /* per protocol histograms */    storeAppendPrintf(sentry, "\n\nRefreshCheck histograms for various protocols\n");    for (i = 0; i < rcCount; ++i)	refreshCountsStats(sentry, &refreshCounts[i]);}voidrefreshInit(){    memset(refreshCounts, 0, sizeof(refreshCounts));    refreshCounts[rcHTTP].proto = "HTTP";    refreshCounts[rcICP].proto = "ICP";    refreshCounts[rcStore].proto = "On Store";    refreshCounts[rcCDigest].proto = "Cache Digests";    cachemgrRegister("refresh",	"Refresh Algorithm Statistics",	refreshStats,	0,	1);}

⌨️ 快捷键说明

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