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