]> git.ipfire.org Git - thirdparty/squid.git/blame - src/refresh.cc
Merged from trunk
[thirdparty/squid.git] / src / refresh.cc
CommitLineData
e4e6a8db 1
2/*
9e4b5932 3 * $Id: refresh.cc,v 1.76 2007/05/24 01:45:03 hno Exp $
e4e6a8db 4 *
5 * DEBUG: section 22 Refresh Calculation
6 * AUTHOR: Harvest Derived
7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 9 * ----------------------------------------------------------
e4e6a8db 10 *
2b6662ba 11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
e4e6a8db 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
e4e6a8db 34 */
35
36#ifndef USE_POSIX_REGEX
37#define USE_POSIX_REGEX /* put before includes; always use POSIX */
38#endif
39
40#include "squid.h"
62ee09ca 41#include "CacheManager.h"
e6ccf245 42#include "Store.h"
528b2c61 43#include "MemObject.h"
a2ac85d9 44#include "HttpRequest.h"
924f73bc 45#include "HttpReply.h"
985c86bc 46#include "SquidTime.h"
e4e6a8db 47
7d47d8e6 48typedef enum {
65fa5c61 49 rcHTTP,
50 rcICP,
51#if USE_HTCP
52 rcHTCP,
53#endif
54#if USE_CACHE_DIGESTS
55 rcCDigest,
56#endif
57 rcStore,
58 rcCount
7d47d8e6 59} refreshCountsEnum;
829a9357 60
62e76326 61typedef struct
62{
1f848b2c 63 bool expires;
64 bool min;
65 bool lmfactor;
66 bool max;
2fadd50d 67} stale_flags;
65fa5c61 68
69/*
70 * This enumerated list assigns specific values, ala HTTP/FTP status
71 * codes. All Fresh codes are in the range 100-199 and all stale
72 * codes are 200-299. We might want to use these codes in logging,
73 * so best to keep them consistent over time.
74 */
75enum {
76 FRESH_REQUEST_MAX_STALE_ALL = 100,
77 FRESH_REQUEST_MAX_STALE_VALUE,
78 FRESH_EXPIRES,
79 FRESH_LMFACTOR_RULE,
80 FRESH_MIN_RULE,
81 FRESH_OVERRIDE_EXPIRES,
82 FRESH_OVERRIDE_LASTMOD,
83 STALE_MUST_REVALIDATE = 200,
84 STALE_RELOAD_INTO_IMS,
85 STALE_FORCED_RELOAD,
86 STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE,
87 STALE_EXPIRES,
88 STALE_MAX_RULE,
89 STALE_LMFACTOR_RULE,
90 STALE_DEFAULT = 299
91};
92
62e76326 93static struct RefreshCounts
94{
829a9357 95 const char *proto;
1c3e77cd 96 int total;
65fa5c61 97 int status[STALE_DEFAULT + 1];
62e76326 98}
99
100refreshCounts[rcCount];
1c3e77cd 101
e4e6a8db 102/*
103 * Defaults:
104 * MIN NONE
105 * PCT 20%
106 * MAX 3 days
107 */
48f44632 108#define REFRESH_DEFAULT_MIN (time_t)0
c3f6d204 109#define REFRESH_DEFAULT_PCT 0.20
48f44632 110#define REFRESH_DEFAULT_MAX (time_t)259200
e4e6a8db 111
2b5133db 112static const refresh_t *refreshUncompiledPattern(const char *);
1c3e77cd 113static OBJH refreshStats;
65fa5c61 114static int refreshStaleness(const StoreEntry *, time_t, time_t, const refresh_t *, stale_flags *);
115
116static refresh_t DefaultRefresh;
2b5133db 117
38f9c547 118const refresh_t *
6018f0de 119refreshLimits(const char *url)
120{
121 const refresh_t *R;
62e76326 122
6018f0de 123 for (R = Config.Refresh; R; R = R->next) {
62e76326 124 if (!regexec(&(R->compiled_pattern), url, 0, 0, 0))
125 return R;
6018f0de 126 }
62e76326 127
6018f0de 128 return NULL;
129}
130
2b5133db 131static const refresh_t *
132refreshUncompiledPattern(const char *pat)
133{
134 const refresh_t *R;
62e76326 135
2b5133db 136 for (R = Config.Refresh; R; R = R->next) {
62e76326 137 if (0 == strcmp(R->pattern, pat))
138 return R;
2b5133db 139 }
62e76326 140
2b5133db 141 return NULL;
142}
143
65fa5c61 144/*
145 * Calculate how stale the response is (or will be at the check_time).
146 * Staleness calculation is based on the following: (1) response
147 * expiration time, (2) age greater than configured maximum, (3)
148 * last-modified factor, and (4) age less than configured minimum.
149 *
150 * If the response is fresh, return -1. Otherwise return its
151 * staleness. NOTE return value of 0 means the response is stale.
152 *
153 * The 'stale_flags' structure is used to tell the calling function
154 * _why_ this response is fresh or stale. Its used, for example,
155 * when the admin wants to override expiration and last-modified
156 * times.
157 */
158static int
159refreshStaleness(const StoreEntry * entry, time_t check_time, time_t age, const refresh_t * R, stale_flags * sf)
160{
161 /*
162 * Check for an explicit expiration time.
163 */
62e76326 164
65fa5c61 165 if (entry->expires > -1) {
1f848b2c 166 sf->expires = true;
62e76326 167
168 if (entry->expires > check_time) {
4a7a3d56 169 debugs(22, 3, "FRESH: expires " << entry->expires <<
170 " >= check_time " << check_time << " ");
bf8fe701 171
62e76326 172 return -1;
173 } else {
4a7a3d56 174 debugs(22, 3, "STALE: expires " << entry->expires <<
175 " < check_time " << check_time << " ");
bf8fe701 176
62e76326 177 return (check_time - entry->expires);
178 }
65fa5c61 179 }
62e76326 180
65fa5c61 181 assert(age >= 0);
182 /*
183 * Use local heuristics to determine staleness. Start with the
184 * max age from the refresh_pattern rule.
185 */
62e76326 186
65fa5c61 187 if (age > R->max) {
4a7a3d56 188 debugs(22, 3, "STALE: age " << age << " > max " << R->max << " ");
1f848b2c 189 sf->max = true;
62e76326 190 return (age - R->max);
65fa5c61 191 }
62e76326 192
65fa5c61 193 /*
194 * Try the last-modified factor algorithm.
195 */
196 if (entry->lastmod > -1 && entry->timestamp > entry->lastmod) {
62e76326 197 /*
198 * stale_age is the Age of the response when it became/becomes
199 * stale according to the last-modified factor algorithm.
200 */
201 time_t stale_age = static_cast<time_t>((entry->timestamp - entry->lastmod) * R->pct);
1f848b2c 202 sf->lmfactor = true;
62e76326 203
204 if (age >= stale_age) {
4a7a3d56 205 debugs(22, 3, "STALE: age " << age << " > stale_age " << stale_age);
62e76326 206 return (age - stale_age);
207 } else {
4a7a3d56 208 debugs(22, 3, "FRESH: age " << age << " <= stale_age " << stale_age);
62e76326 209 return -1;
210 }
65fa5c61 211 }
62e76326 212
65fa5c61 213 /*
214 * If we are here, staleness is determined by the refresh_pattern
215 * configured minimum age.
216 */
9e4b5932 217 if (age < R->min) {
218 debugs(22, 3, "FRESH: age " << age << " < min " << R->min);
1f848b2c 219 sf->min = true;
62e76326 220 return -1;
65fa5c61 221 }
62e76326 222
9e4b5932 223 debugs(22, 3, "STALE: age " << age << " >= min " << R->min);
65fa5c61 224 return (age - R->min);
225}
226
829a9357 227/* return 1 if the entry must be revalidated within delta seconds
228 * 0 otherwise
229 *
230 * note: request maybe null (e.g. for cache digests build)
e4e6a8db 231 */
829a9357 232static int
190154cf 233refreshCheck(const StoreEntry * entry, HttpRequest * request, time_t delta)
e4e6a8db 234{
6018f0de 235 const refresh_t *R;
829a9357 236 const char *uri = NULL;
65fa5c61 237 time_t age = 0;
a207429f 238 time_t check_time = squid_curtime + delta;
65fa5c61 239 int staleness;
240 stale_flags sf;
62e76326 241
9b5d1d21 242 if (entry->mem_obj)
62e76326 243 uri = entry->mem_obj->url;
7d47d8e6 244 else if (request)
62e76326 245 uri = urlCanonical(request);
7d47d8e6 246
bf8fe701 247 debugs(22, 3, "refreshCheck: '" << (uri ? uri : "<none>") << "'");
65fa5c61 248
249 if (check_time > entry->timestamp)
62e76326 250 age = check_time - entry->timestamp;
251
65fa5c61 252 R = uri ? refreshLimits(uri) : refreshUncompiledPattern(".");
62e76326 253
65fa5c61 254 if (NULL == R)
62e76326 255 R = &DefaultRefresh;
256
65fa5c61 257 memset(&sf, '\0', sizeof(sf));
62e76326 258
65fa5c61 259 staleness = refreshStaleness(entry, check_time, age, R, &sf);
62e76326 260
bf8fe701 261 debugs(22, 3, "Staleness = " << staleness);
262
263 debugs(22, 3, "refreshCheck: Matched '" << R->pattern << " " <<
264 (int) R->min << " " << (int) (100.0 * R->pct) << "%% " <<
265 (int) R->max << "'");
65fa5c61 266
62e76326 267
4a7a3d56 268 debugs(22, 3, "refreshCheck: age = " << age);
62e76326 269
bf8fe701 270 debugs(22, 3, "\tcheck_time:\t" << mkrfc1123(check_time));
62e76326 271
bf8fe701 272 debugs(22, 3, "\tentry->timestamp:\t" << mkrfc1123(entry->timestamp));
65fa5c61 273
274 if (EBIT_TEST(entry->flags, ENTRY_REVALIDATE) && staleness > -1) {
bf8fe701 275 debugs(22, 3, "refreshCheck: YES: Must revalidate stale response");
62e76326 276 return STALE_MUST_REVALIDATE;
65fa5c61 277 }
62e76326 278
829a9357 279 /* request-specific checks */
280 if (request) {
62e76326 281 HttpHdrCc *cc = request->cache_control;
4c3ef9b2 282
283 if (request->flags.ims && (R->flags.refresh_ims || Config.onoff.refresh_all_ims)) {
284 /* The clients no-cache header is changed into a IMS query */
bf8fe701 285 debugs(22, 3, "refreshCheck: YES: refresh-ims");
4c3ef9b2 286 return STALE_FORCED_RELOAD;
287 }
288
9f60cfdf 289#if HTTP_VIOLATIONS
62e76326 290
291 if (!request->flags.nocache_hack) {
292 (void) 0;
293 } else if (R->flags.ignore_reload) {
294 /* The clients no-cache header is ignored */
bf8fe701 295 debugs(22, 3, "refreshCheck: MAYBE: ignore-reload");
62e76326 296 } else if (R->flags.reload_into_ims || Config.onoff.reload_into_ims) {
297 /* The clients no-cache header is changed into a IMS query */
bf8fe701 298 debugs(22, 3, "refreshCheck: YES: reload-into-ims");
62e76326 299 return STALE_RELOAD_INTO_IMS;
300 } else {
301 /* The clients no-cache header is not overridden on this request */
bf8fe701 302 debugs(22, 3, "refreshCheck: YES: client reload");
62e76326 303 request->flags.nocache = 1;
304 return STALE_FORCED_RELOAD;
305 }
306
9f60cfdf 307#endif
62e76326 308 if (NULL != cc) {
309 if (cc->max_age > -1) {
085008f9 310#if HTTP_VIOLATIONS
62e76326 311 if (R->flags.ignore_reload && cc->max_age == 0) {} else
528b2c61 312#endif
62e76326 313 {
528b2c61 314#if 0
62e76326 315
316 if (cc->max_age == 0) {
bf8fe701 317 debugs(22, 3, "refreshCheck: YES: client-max-age = 0");
62e76326 318 return STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE;
319 }
320
085008f9 321#endif
62e76326 322 if (age > cc->max_age) {
bf8fe701 323 debugs(22, 3, "refreshCheck: YES: age > client-max-age");
62e76326 324 return STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE;
325 }
326 }
327 }
328
329 if (EBIT_TEST(cc->mask, CC_MAX_STALE) && staleness > -1) {
330 if (cc->max_stale < 0) {
331 /* max-stale directive without a value */
bf8fe701 332 debugs(22, 3, "refreshCheck: NO: max-stale wildcard");
62e76326 333 return FRESH_REQUEST_MAX_STALE_ALL;
334 } else if (staleness < cc->max_stale) {
bf8fe701 335 debugs(22, 3, "refreshCheck: NO: staleness < max-stale");
62e76326 336 return FRESH_REQUEST_MAX_STALE_VALUE;
337 }
338 }
339 }
48f44632 340 }
62e76326 341
65fa5c61 342 if (-1 == staleness) {
bf8fe701 343 debugs(22, 3, "refreshCheck: object isn't stale..");
ed1de692 344 if (sf.expires) {
bf8fe701 345 debugs(22, 3, "refreshCheck: returning FRESH_EXPIRES");
62e76326 346 return FRESH_EXPIRES;
ed1de692 347 }
62e76326 348
349 assert(!sf.max);
350
ed1de692 351 if (sf.lmfactor) {
bf8fe701 352 debugs(22, 3, "refreshCheck: returning FRESH_LMFACTOR_RULE");
62e76326 353 return FRESH_LMFACTOR_RULE;
ed1de692 354 }
62e76326 355
356 assert(sf.min);
357
bf8fe701 358 debugs(22, 3, "refreshCheck: returning FRESH_MIN_RULE");
62e76326 359 return FRESH_MIN_RULE;
1dfa1d81 360 }
62e76326 361
65fa5c61 362 /*
363 * At this point the response is stale, unless one of
542c4d60 364 * the override options kicks in.
65fa5c61 365 */
366 if (sf.expires) {
367#if HTTP_VIOLATIONS
62e76326 368
369 if (R->flags.override_expire && age < R->min) {
bf8fe701 370 debugs(22, 3, "refreshCheck: NO: age < min && override-expire");
62e76326 371 return FRESH_OVERRIDE_EXPIRES;
372 }
373
65fa5c61 374#endif
62e76326 375 return STALE_EXPIRES;
e4e6a8db 376 }
62e76326 377
65fa5c61 378 if (sf.max)
62e76326 379 return STALE_MAX_RULE;
380
65fa5c61 381 if (sf.lmfactor) {
9f60cfdf 382#if HTTP_VIOLATIONS
62e76326 383
384 if (R->flags.override_lastmod && age < R->min) {
bf8fe701 385 debugs(22, 3, "refreshCheck: NO: age < min && override-lastmod");
62e76326 386 return FRESH_OVERRIDE_LASTMOD;
387 }
388
65fa5c61 389#endif
62e76326 390 return STALE_LMFACTOR_RULE;
e4e6a8db 391 }
62e76326 392
bf8fe701 393 debugs(22, 3, "refreshCheck: returning STALE_DEFAULT");
65fa5c61 394 return STALE_DEFAULT;
e4e6a8db 395}
48f44632 396
cfa9f1cb 397int
398refreshIsCachable(const StoreEntry * entry)
399{
400 /*
401 * Don't look at the request to avoid no-cache and other nuisances.
402 * the object should have a mem_obj so the URL will be found there.
6a2f3fcf 403 * minimum_expiry_time seconds delta (defaults to 60 seconds), to
404 * avoid objects which expire almost immediately, and which can't
405 * be refreshed.
cfa9f1cb 406 */
6a2f3fcf 407 int reason = refreshCheck(entry, NULL, Config.minimum_expiry_time);
65fa5c61 408 refreshCounts[rcStore].total++;
409 refreshCounts[rcStore].status[reason]++;
62e76326 410
451c8350 411 if (reason < STALE_MUST_REVALIDATE)
62e76326 412 /* Does not need refresh. This is certainly cachable */
413 return 1;
414
cfa9f1cb 415 if (entry->lastmod < 0)
62e76326 416 /* Last modified is needed to do a refresh */
417 return 0;
418
cfa9f1cb 419 if (entry->mem_obj == NULL)
62e76326 420 /* no mem_obj? */
421 return 1;
422
528b2c61 423 if (entry->getReply() == NULL)
62e76326 424 /* no reply? */
425 return 1;
426
528b2c61 427 if (entry->getReply()->content_length == 0)
62e76326 428 /* No use refreshing (caching?) 0 byte objects */
429 return 0;
430
cfa9f1cb 431 /* This seems to be refreshable. Cache it */
432 return 1;
433}
434
829a9357 435/* refreshCheck... functions below are protocol-specific wrappers around
436 * refreshCheck() function above */
437
438int
190154cf 439refreshCheckHTTP(const StoreEntry * entry, HttpRequest * request)
7d47d8e6 440{
65fa5c61 441 int reason = refreshCheck(entry, request, 0);
442 refreshCounts[rcHTTP].total++;
443 refreshCounts[rcHTTP].status[reason]++;
444 return (reason < 200) ? 0 : 1;
829a9357 445}
446
447int
190154cf 448refreshCheckICP(const StoreEntry * entry, HttpRequest * request)
7d47d8e6 449{
65fa5c61 450 int reason = refreshCheck(entry, request, 30);
451 refreshCounts[rcICP].total++;
452 refreshCounts[rcICP].status[reason]++;
453 return (reason < 200) ? 0 : 1;
829a9357 454}
455
65fa5c61 456#if USE_HTCP
32b3cf93 457int
190154cf 458refreshCheckHTCP(const StoreEntry * entry, HttpRequest * request)
32b3cf93 459{
65fa5c61 460 int reason = refreshCheck(entry, request, 10);
461 refreshCounts[rcHTCP].total++;
462 refreshCounts[rcHTCP].status[reason]++;
463 return (reason < 200) ? 0 : 1;
32b3cf93 464}
62e76326 465
65fa5c61 466#endif
32b3cf93 467
65fa5c61 468#if USE_CACHE_DIGESTS
829a9357 469int
7d47d8e6 470refreshCheckDigest(const StoreEntry * entry, time_t delta)
471{
65fa5c61 472 int reason = refreshCheck(entry,
62e76326 473 entry->mem_obj ? entry->mem_obj->request : NULL,
474 delta);
65fa5c61 475 refreshCounts[rcCDigest].total++;
476 refreshCounts[rcCDigest].status[reason]++;
477 return (reason < 200) ? 0 : 1;
6018f0de 478}
62e76326 479
65fa5c61 480#endif
6018f0de 481
48f44632 482time_t
483getMaxAge(const char *url)
484{
6018f0de 485 const refresh_t *R;
bf8fe701 486 debugs(22, 3, "getMaxAge: '" << url << "'");
62e76326 487
6018f0de 488 if ((R = refreshLimits(url)))
62e76326 489 return R->max;
6018f0de 490 else
62e76326 491 return REFRESH_DEFAULT_MAX;
48f44632 492}
1c3e77cd 493
829a9357 494static void
62e76326 495
829a9357 496refreshCountsStats(StoreEntry * sentry, struct RefreshCounts *rc)
497{
cc7cfa8e 498 int sum = 0;
499 int tot = rc->total;
500
829a9357 501 storeAppendPrintf(sentry, "\n\n%s histogram:\n", rc->proto);
65fa5c61 502 storeAppendPrintf(sentry, "Count\t%%Total\tCategory\n");
829a9357 503
65fa5c61 504#define refreshCountsStatsEntry(code,desc) { \
505 storeAppendPrintf(sentry, "%6d\t%6.2f\t%s\n", \
506 rc->status[code], xpercent(rc->status[code], tot), desc); \
507 sum += rc->status[code]; \
cc7cfa8e 508}
65fa5c61 509
510 refreshCountsStatsEntry(FRESH_REQUEST_MAX_STALE_ALL,
62e76326 511 "Fresh: request max-stale wildcard");
65fa5c61 512 refreshCountsStatsEntry(FRESH_REQUEST_MAX_STALE_VALUE,
62e76326 513 "Fresh: request max-stale value");
65fa5c61 514 refreshCountsStatsEntry(FRESH_EXPIRES,
62e76326 515 "Fresh: expires time not reached");
65fa5c61 516 refreshCountsStatsEntry(FRESH_LMFACTOR_RULE,
62e76326 517 "Fresh: refresh_pattern last-mod factor percentage");
65fa5c61 518 refreshCountsStatsEntry(FRESH_MIN_RULE,
62e76326 519 "Fresh: refresh_pattern min value");
65fa5c61 520 refreshCountsStatsEntry(FRESH_OVERRIDE_EXPIRES,
62e76326 521 "Fresh: refresh_pattern override expires");
65fa5c61 522 refreshCountsStatsEntry(FRESH_OVERRIDE_LASTMOD,
62e76326 523 "Fresh: refresh_pattern override lastmod");
65fa5c61 524 refreshCountsStatsEntry(STALE_MUST_REVALIDATE,
62e76326 525 "Stale: response has must-revalidate");
65fa5c61 526 refreshCountsStatsEntry(STALE_RELOAD_INTO_IMS,
62e76326 527 "Stale: changed reload into IMS");
65fa5c61 528 refreshCountsStatsEntry(STALE_FORCED_RELOAD,
62e76326 529 "Stale: request has no-cache directive");
65fa5c61 530 refreshCountsStatsEntry(STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE,
62e76326 531 "Stale: age exceeds request max-age value");
65fa5c61 532 refreshCountsStatsEntry(STALE_EXPIRES,
62e76326 533 "Stale: expires time reached");
65fa5c61 534 refreshCountsStatsEntry(STALE_MAX_RULE,
62e76326 535 "Stale: refresh_pattern max age rule");
65fa5c61 536 refreshCountsStatsEntry(STALE_LMFACTOR_RULE,
62e76326 537 "Stale: refresh_pattern last-mod factor percentage");
65fa5c61 538 refreshCountsStatsEntry(STALE_DEFAULT,
62e76326 539 "Stale: by default");
65fa5c61 540
7d47d8e6 541 tot = sum; /* paranoid: "total" line shows 100% if we forgot nothing */
65fa5c61 542 storeAppendPrintf(sentry, "%6d\t%6.2f\tTOTAL\n",
62e76326 543 rc->total, xpercent(rc->total, tot));
65fa5c61 544 \
62e76326 545 storeAppendPrintf(sentry, "\n");
829a9357 546}
547
1c3e77cd 548static void
549refreshStats(StoreEntry * sentry)
550{
829a9357 551 int i;
552 int total = 0;
553
554 /* get total usage count */
62e76326 555
829a9357 556 for (i = 0; i < rcCount; ++i)
62e76326 557 total += refreshCounts[i].total;
829a9357 558
559 /* protocol usage histogram */
560 storeAppendPrintf(sentry, "\nRefreshCheck calls per protocol\n\n");
62e76326 561
829a9357 562 storeAppendPrintf(sentry, "Protocol\t#Calls\t%%Calls\n");
62e76326 563
829a9357 564 for (i = 0; i < rcCount; ++i)
62e76326 565 storeAppendPrintf(sentry, "%10s\t%6d\t%6.2f\n",
566 refreshCounts[i].proto,
567 refreshCounts[i].total,
568 xpercent(refreshCounts[i].total, total));
829a9357 569
570 /* per protocol histograms */
571 storeAppendPrintf(sentry, "\n\nRefreshCheck histograms for various protocols\n");
62e76326 572
829a9357 573 for (i = 0; i < rcCount; ++i)
62e76326 574 refreshCountsStats(sentry, &refreshCounts[i]);
1c3e77cd 575}
576
577void
9bc73deb 578refreshInit(void)
1c3e77cd 579{
829a9357 580 memset(refreshCounts, 0, sizeof(refreshCounts));
581 refreshCounts[rcHTTP].proto = "HTTP";
582 refreshCounts[rcICP].proto = "ICP";
65fa5c61 583#if USE_HTCP
62e76326 584
32b3cf93 585 refreshCounts[rcHTCP].proto = "HTCP";
65fa5c61 586#endif
62e76326 587
cfa9f1cb 588 refreshCounts[rcStore].proto = "On Store";
65fa5c61 589#if USE_CACHE_DIGESTS
62e76326 590
829a9357 591 refreshCounts[rcCDigest].proto = "Cache Digests";
65fa5c61 592#endif
62e76326 593
65fa5c61 594 memset(&DefaultRefresh, '\0', sizeof(DefaultRefresh));
595 DefaultRefresh.pattern = "<none>";
596 DefaultRefresh.min = REFRESH_DEFAULT_MIN;
597 DefaultRefresh.pct = REFRESH_DEFAULT_PCT;
598 DefaultRefresh.max = REFRESH_DEFAULT_MAX;
1c3e77cd 599}
62ee09ca 600
601void
b8083b1c 602refreshRegisterWithCacheManager(void)
62ee09ca 603{
b8083b1c
FC
604 CacheManager::GetInstance()->
605 registerAction("refresh", "Refresh Algorithm Statistics", refreshStats, 0, 1);
62ee09ca 606}