refresh.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 22 Refresh Calculation */
10 
11 #ifndef USE_POSIX_REGEX
12 #define USE_POSIX_REGEX /* put before includes; always use POSIX */
13 #endif
14 
15 #include "squid.h"
16 #include "base/PackableStream.h"
17 #include "HttpHdrCc.h"
18 #include "HttpReply.h"
19 #include "HttpRequest.h"
20 #include "MemObject.h"
21 #include "mgr/Registration.h"
22 #include "refresh.h"
23 #include "RefreshPattern.h"
24 #include "SquidConfig.h"
25 #include "Store.h"
26 #include "util.h"
27 
28 typedef enum {
31 #if USE_HTCP
33 #endif
34 #if USE_CACHE_DIGESTS
36 #endif
40 
44 typedef struct {
45  bool expires;
46  bool min;
47  bool lmfactor;
48  bool max;
49 } stale_flags;
50 
51 /*
52  * This enumerated list assigns specific values, ala HTTP/FTP status
53  * codes. All Fresh codes are in the range 100-199 and all stale
54  * codes are 200-299. We might want to use these codes in logging,
55  * so best to keep them consistent over time.
56  */
57 enum {
74 };
75 
76 static struct RefreshCounts {
77  const char *proto;
78  int total;
81 
83 static int refreshStaleness(const StoreEntry * entry, time_t check_time, const time_t age, const RefreshPattern * R, stale_flags * sf);
84 
85 static RefreshPattern DefaultRefresh(nullptr);
86 
91 const RefreshPattern *
92 refreshLimits(const char *url)
93 {
94  for (auto R = Config.Refresh; R; R = R->next) {
95  ++(R->stats.matchTests);
96  if (R->regex().match(url)) {
97  ++(R->stats.matchCount);
98  return R;
99  }
100  }
101 
102  return nullptr;
103 }
104 
106 static const RefreshPattern *
108 {
109  for (auto R = Config.Refresh; R; R = R->next) {
110  if (R->regex().isDot())
111  return R;
112  }
113 
114  return nullptr;
115 }
116 
138 static int
139 refreshStaleness(const StoreEntry * entry, time_t check_time, const time_t age, const RefreshPattern * R, stale_flags * sf)
140 {
141  // 1. If the cached object has an explicit expiration time, then we rely on this and
142  // completely ignore the Min, Percent and Max values in the refresh_pattern.
143  if (entry->expires > -1) {
144  sf->expires = true;
145 
146  if (entry->expires > check_time) {
147  debugs(22, 3, "FRESH: expires " << entry->expires << " > check_time " << check_time);
148  return -1;
149  } else {
150  debugs(22, 3, "STALE: expires " << entry->expires << " <= check_time " << check_time);
151  return (check_time - entry->expires);
152  }
153  }
154 
155  debugs(22, 3, "No explicit expiry given, using heuristics to determine freshness");
156 
157  // 2. If the entry is older than the maximum age in the refresh_pattern, it is STALE.
158  if (age > R->max) {
159  debugs(22, 3, "STALE: age " << age << " > max " << R->max);
160  sf->max = true;
161  return (age - R->max);
162  }
163 
164  // 3. If there is a Last-Modified header, try the last-modified factor algorithm.
165  const time_t lastmod_delta = entry->timestamp - entry->lastModified();
166  if (lastmod_delta > 0) {
167  /* stale_age is the age of the response when it became/becomes stale according to
168  * the last-modified factor algorithm. It's how long we can consider the response
169  * fresh from the time we cached it.
170  */
171  time_t stale_age = static_cast<time_t>(lastmod_delta * R->pct);
172 
173  debugs(22,3, "Last modified " << lastmod_delta << " sec before we cached it, L-M factor " <<
174  (100.0 * R->pct) << "% = " << stale_age << " sec freshness lifetime");
175  sf->lmfactor = true;
176 
177  if (age >= stale_age) {
178  debugs(22, 3, "STALE: age " << age << " > stale_age " << stale_age);
179  return (age - stale_age);
180  } else {
181  debugs(22, 3, "FRESH: age " << age << " <= stale_age " << stale_age);
182  return -1;
183  }
184  }
185 
186  // 4. If the entry is not as old as the minimum age in the refresh_pattern, it is FRESH.
187  if (age < R->min) {
188  debugs(22, 3, "FRESH: age (" << age << " sec) is less than configured minimum (" << R->min << " sec)");
189  sf->min = true;
190  return -1;
191  }
192 
193  // 5. default is stale, by the amount we missed the minimum by
194  debugs(22, 3, "STALE: No explicit expiry, no last modified, and older than configured minimum.");
195  return (age - R->min);
196 }
197 
252 static int
253 refreshCheck(const StoreEntry * entry, HttpRequest * request, time_t delta)
254 {
255  time_t age = 0;
256  time_t check_time = squid_curtime + delta;
257  int staleness;
258  stale_flags sf;
259 
260  // get the URL of this entry, if there is one
261  static const SBuf nilUri("<none>");
262  SBuf uri = nilUri;
263  if (entry->mem_obj)
264  uri = entry->mem_obj->storeId();
265  else if (request)
266  uri = request->effectiveRequestUri();
267 
268  debugs(22, 3, "checking freshness of " << *entry << " with URI: " << uri);
269 
270  // age is not necessarily the age now, but the age at the given check_time
271  if (check_time > entry->timestamp)
272  age = check_time - entry->timestamp;
273 
274  // XXX: what to do when age < 0 or counter overflow?
275  assert(age >= 0);
276 
277  /* We need a refresh rule. In order of preference:
278  *
279  * 1. the rule that matches this URI by regex
280  * 2. the "." rule from the config file
281  * 3. the default "." rule
282  */
283  // XXX: performance regression. c_str() reallocates
284  const RefreshPattern *R = (uri != nilUri) ? refreshLimits(uri.c_str()) : refreshFirstDotRule();
285  if (nullptr == R)
286  R = &DefaultRefresh;
287 
288  debugs(22, 3, "Matched '" << *R << '\'');
289 
290  debugs(22, 3, "\tage:\t" << age);
291 
292  debugs(22, 3, "\tcheck_time:\t" << Time::FormatRfc1123(check_time));
293 
294  debugs(22, 3, "\tentry->timestamp:\t" << Time::FormatRfc1123(entry->timestamp));
295 
296  if (request && !request->flags.ignoreCc) {
297  const HttpHdrCc *const cc = request->cache_control;
298  int minFresh = -1;
299  if (cc && cc->hasMinFresh(&minFresh)) {
300  debugs(22, 3, "\tage + min-fresh:\t" << age << " + " <<
301  minFresh << " = " << age + minFresh);
302  debugs(22, 3, "\tcheck_time + min-fresh:\t" << check_time << " + "
303  << minFresh << " = " <<
304  Time::FormatRfc1123(check_time + minFresh));
305  age += minFresh;
306  check_time += minFresh;
307  }
308  }
309 
310  memset(&sf, '\0', sizeof(sf));
311 
312  staleness = refreshStaleness(entry, check_time, age, R, &sf);
313 
314  debugs(22, 3, "Staleness = " << staleness);
315 
316  const auto reply = entry->hasFreshestReply(); // may be nil
317 
318  // stale-if-error requires any failure be passed thru when its period is over.
319  int staleIfError = -1;
320  if (request && reply && reply->cache_control &&
321  reply->cache_control->hasStaleIfError(&staleIfError) &&
322  staleIfError < staleness) {
323 
324  debugs(22, 3, "stale-if-error period expired. Will produce error if validation fails.");
325  request->flags.failOnValidationError = true;
326  }
327 
328  /* If the origin server specified either of:
329  * Cache-Control: must-revalidate
330  * Cache-Control: proxy-revalidate
331  * the spec says the response must always be revalidated if stale.
332  */
333  const bool revalidateAlways = EBIT_TEST(entry->flags, ENTRY_REVALIDATE_ALWAYS);
334  if (revalidateAlways || (staleness > -1 &&
336  debugs(22, 3, "YES: Must revalidate stale object (origin set " <<
337  (revalidateAlways ? "no-cache or private" :
338  "must-revalidate, proxy-revalidate or s-maxage") << ")");
339  if (request)
340  request->flags.failOnValidationError = true;
341  return STALE_MUST_REVALIDATE;
342  }
343 
344  /* request-specific checks */
345  if (request && !request->flags.ignoreCc) {
346  HttpHdrCc *cc = request->cache_control;
347 
348  /* If the request is an IMS request, and squid is configured NOT to service this from cache
349  * (either by 'refresh-ims' in the refresh pattern or 'refresh_all_ims on' globally)
350  * then force a reload from the origin.
351  */
352  if (request->flags.ims && (R->flags.refresh_ims || Config.onoff.refresh_all_ims)) {
353  // The client's no-cache header is changed into a IMS query
354  debugs(22, 3, "YES: Client IMS request forcing revalidation of object (refresh-ims option)");
355  return STALE_FORCED_RELOAD;
356  }
357 
358 #if USE_HTTP_VIOLATIONS
359  /* Normally a client reload request ("Cache-Control: no-cache" or "Pragma: no-cache")
360  * means we must treat this response as STALE and fetch a new one.
361  *
362  * However, some options exist to override this behaviour. For example, we might just
363  * revalidate our existing response, or even just serve it up without revalidating it.
364  *
365  * ---- Note on the meaning of nocache_hack -----
366  *
367  * The nocache_hack flag has a very specific and complex meaning:
368  *
369  * (a) this is a reload request ("Cache-Control: no-cache" or "Pragma: no-cache" header)
370  * and (b) the configuration file either has at least one refresh_pattern with
371  * ignore-reload or reload-into-ims (not necessarily the rule matching this request) or
372  * the global reload_into_ims is set to on
373  *
374  * In other words: this is a client reload, and we might need to override
375  * the default behaviour (but we might not).
376  *
377  * "nocache_hack" is a pretty deceptive name for such a complicated meaning.
378  */
379  if (request->flags.noCacheHack()) {
380 
381  if (R->flags.ignore_reload) {
382  /* The client's no-cache header is ignored completely - we'll try to serve
383  * what we have (assuming it's still fresh, etc.)
384  */
385  debugs(22, 3, "MAYBE: Ignoring client reload request - trying to serve from cache (ignore-reload option)");
386  } else if (R->flags.reload_into_ims || Config.onoff.reload_into_ims) {
387  /* The client's no-cache header is not honoured completely - we'll just try
388  * to revalidate our cached copy (IMS to origin) instead of fetching a new
389  * copy with an unconditional GET.
390  */
391  debugs(22, 3, "YES: Client reload request - cheating, only revalidating with origin (reload-into-ims option)");
392  return STALE_RELOAD_INTO_IMS;
393  } else {
394  /* The client's no-cache header is honoured - we fetch a new copy from origin */
395  debugs(22, 3, "YES: Client reload request - fetching new copy from origin");
396  request->flags.noCache = true;
397  return STALE_FORCED_RELOAD;
398  }
399  }
400 #endif
401 
402  // Check the Cache-Control client request header
403  if (nullptr != cc) {
404 
405  // max-age directive
406  int maxAge = -1;
407  if (cc->hasMaxAge(&maxAge)) {
408 
409  // RFC 8246: reply contains CC:immutable then ignore client CC:max-age=N
410  if (reply && reply->cache_control && reply->cache_control->hasImmutable()) {
411  debugs(22, 3, "MAYBE: Ignoring client CC:max-age=" << maxAge << " request - 'Cache-Control: immutable'");
412 
413 #if USE_HTTP_VIOLATIONS
414  // Ignore of client "Cache-Control: max-age=0" header
415  } else if (R->flags.ignore_reload && maxAge == 0) {
416  debugs(22, 3, "MAYBE: Ignoring client reload request - trying to serve from cache (ignore-reload option)");
417 #endif
418 
419  // Honour client "Cache-Control: max-age=x" header
420  } else if (age > maxAge || maxAge == 0) {
421  debugs(22, 3, "YES: Revalidating object - client 'Cache-Control: max-age=" << maxAge << "'");
423  }
424  }
425 
426  // max-stale directive
427  int maxStale = -1;
428  if (cc->hasMaxStale(&maxStale) && staleness > -1) {
429  if (maxStale==HttpHdrCc::MAX_STALE_ANY) {
430  debugs(22, 3, "NO: Client accepts a stale response of any age - 'Cache-Control: max-stale'");
432  } else if (staleness < maxStale) {
433  debugs(22, 3, "NO: Client accepts a stale response - 'Cache-Control: max-stale=" << maxStale << "'");
435  }
436  }
437  }
438  }
439 
440  // If the object is fresh, return the right FRESH_ code
441  if (-1 == staleness) {
442  debugs(22, 3, "Object isn't stale..");
443  if (sf.expires) {
444  debugs(22, 3, "returning FRESH_EXPIRES");
445  return FRESH_EXPIRES;
446  }
447 
448  assert(!sf.max);
449 
450  if (sf.lmfactor) {
451  debugs(22, 3, "returning FRESH_LMFACTOR_RULE");
452  return FRESH_LMFACTOR_RULE;
453  }
454 
455  assert(sf.min);
456 
457  debugs(22, 3, "returning FRESH_MIN_RULE");
458  return FRESH_MIN_RULE;
459  }
460 
461  /*
462  * At this point the response is stale, unless one of
463  * the override options kicks in.
464  * NOTE: max-stale config blocks the overrides.
465  */
466  int max_stale = (R->max_stale >= 0 ? R->max_stale : Config.maxStale);
467  if ( max_stale >= 0 && staleness > max_stale) {
468  debugs(22, 3, "YES: refresh_pattern max-stale=N limit from squid.conf");
469  if (request)
470  request->flags.failOnValidationError = true;
471  return STALE_MAX_STALE;
472  }
473 
474  if (sf.expires) {
475 #if USE_HTTP_VIOLATIONS
476 
477  if (R->flags.override_expire && age < R->min) {
478  debugs(22, 3, "NO: Serving from cache - even though explicit expiry has passed, we enforce Min value (override-expire option)");
479  return FRESH_OVERRIDE_EXPIRES;
480  }
481 
482 #endif
483  debugs(22, 3, "returning STALE_EXPIRES");
484  return STALE_EXPIRES;
485  }
486 
487  if (sf.max) {
488  debugs(22, 3, "returning STALE_MAX_RULE");
489  return STALE_MAX_RULE;
490  }
491 
492  if (sf.lmfactor) {
493 #if USE_HTTP_VIOLATIONS
494  if (R->flags.override_lastmod && age < R->min) {
495  debugs(22, 3, "NO: Serving from cache - even though L-M factor says the object is stale, we enforce Min value (override-lastmod option)");
496  return FRESH_OVERRIDE_LASTMOD;
497  }
498 #endif
499  debugs(22, 3, "YES: L-M factor says the object is stale'");
500  return STALE_LMFACTOR_RULE;
501  }
502 
503  debugs(22, 3, "returning STALE_DEFAULT");
504  return STALE_DEFAULT;
505 }
506 
517 bool
519 {
520  /*
521  * Don't look at the request to avoid no-cache and other nuisances.
522  * the object should have a mem_obj so the URL will be found there.
523  * minimum_expiry_time seconds delta (defaults to 60 seconds), to
524  * avoid objects which expire almost immediately, and which can't
525  * be refreshed.
526  *
527  * No hittingRequiresCollapsing() or didCollapse concerns here: This
528  * incoming response is fresh now, but we want to check whether it can be
529  * refreshed Config.minimum_expiry_time seconds later.
530  */
531  int reason = refreshCheck(entry, nullptr, Config.minimum_expiry_time);
533  ++ refreshCounts[rcStore].status[reason];
534 
535  if (reason < STALE_MUST_REVALIDATE)
536  /* Does not need refresh. This is certainly cachable */
537  return true;
538 
539  if (entry->lastModified() < 0)
540  /* We should know entry's modification time to do a refresh */
541  return false;
542 
543  if (entry->mem_obj == nullptr)
544  /* no mem_obj? */
545  return true;
546 
547  if (entry->mem_obj->baseReply().content_length == 0)
548  /* No use refreshing (caching?) 0 byte objects */
549  return false;
550 
551  /* This seems to be refreshable. Cache it */
552  return true;
553 }
554 
556 static bool
557 refreshIsStaleIfHit(const int reason)
558 {
559  switch (reason) {
560  case FRESH_MIN_RULE:
561  case FRESH_LMFACTOR_RULE:
562  case FRESH_EXPIRES:
563  return false;
564  default:
565  return true;
566  }
567 }
568 
581 int
582 refreshCheckHTTP(const StoreEntry * entry, HttpRequest * request)
583 {
584  int reason = refreshCheck(entry, request, 0);
586  ++ refreshCounts[rcHTTP].status[reason];
587  request->flags.staleIfHit = refreshIsStaleIfHit(reason);
588  return (Config.onoff.offline || reason < 200) ? 0 : 1;
589 }
590 
592 int
593 refreshCheckICP(const StoreEntry * entry, HttpRequest * request)
594 {
595  int reason = refreshCheck(entry, request, 30);
597  ++ refreshCounts[rcICP].status[reason];
598  return (reason < 200) ? 0 : 1;
599 }
600 
601 #if USE_HTCP
602 int
604 refreshCheckHTCP(const StoreEntry * entry, HttpRequest * request)
605 {
606  int reason = refreshCheck(entry, request, 10);
608  ++ refreshCounts[rcHTCP].status[reason];
609  return (reason < 200) ? 0 : 1;
610 }
611 
612 #endif
613 
614 #if USE_CACHE_DIGESTS
615 int
617 refreshCheckDigest(const StoreEntry * entry, time_t delta)
618 {
619  int reason = refreshCheck(entry,
620  entry->mem_obj ? entry->mem_obj->request.getRaw() : nullptr,
621  delta);
623  ++ refreshCounts[rcCDigest].status[reason];
624  return (reason < 200) ? 0 : 1;
625 }
626 #endif
627 
638 time_t
639 getMaxAge(const char *url)
640 {
641  const RefreshPattern *R;
642  debugs(22, 3, "getMaxAge: '" << url << "'");
643 
644  if ((R = refreshLimits(url)))
645  return R->max;
646  else
647  return REFRESH_DEFAULT_MAX;
648 }
649 
650 static int
651 refreshCountsStatsEntry(StoreEntry * sentry, struct RefreshCounts &rc, int code, const char *desc)
652 {
653  storeAppendPrintf(sentry, "%6d\t%6.2f\t%s\n", rc.status[code], xpercent(rc.status[code], rc.total), desc);
654  return rc.status[code];
655 }
656 
657 static void
659 {
660  if (!rc.total)
661  return;
662 
663  storeAppendPrintf(sentry, "\n\n%s histogram:\n", rc.proto);
664  storeAppendPrintf(sentry, "Count\t%%Total\tCategory\n");
665 
666  refreshCountsStatsEntry(sentry, rc, FRESH_REQUEST_MAX_STALE_ALL, "Fresh: request max-stale wildcard");
667  refreshCountsStatsEntry(sentry, rc, FRESH_REQUEST_MAX_STALE_VALUE, "Fresh: request max-stale value");
668  refreshCountsStatsEntry(sentry, rc, FRESH_EXPIRES, "Fresh: expires time not reached");
669  refreshCountsStatsEntry(sentry, rc, FRESH_LMFACTOR_RULE, "Fresh: refresh_pattern last-mod factor percentage");
670  refreshCountsStatsEntry(sentry, rc, FRESH_MIN_RULE, "Fresh: refresh_pattern min value");
671  refreshCountsStatsEntry(sentry, rc, FRESH_OVERRIDE_EXPIRES, "Fresh: refresh_pattern override-expires");
672  refreshCountsStatsEntry(sentry, rc, FRESH_OVERRIDE_LASTMOD, "Fresh: refresh_pattern override-lastmod");
673  refreshCountsStatsEntry(sentry, rc, STALE_MUST_REVALIDATE, "Stale: response has must-revalidate");
674  refreshCountsStatsEntry(sentry, rc, STALE_RELOAD_INTO_IMS, "Stale: changed reload into IMS");
675  refreshCountsStatsEntry(sentry, rc, STALE_FORCED_RELOAD, "Stale: request has no-cache directive");
676  refreshCountsStatsEntry(sentry, rc, STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE, "Stale: age exceeds request max-age value");
677  refreshCountsStatsEntry(sentry, rc, STALE_EXPIRES, "Stale: expires time reached");
678  refreshCountsStatsEntry(sentry, rc, STALE_MAX_RULE, "Stale: refresh_pattern max age rule");
679  refreshCountsStatsEntry(sentry, rc, STALE_LMFACTOR_RULE, "Stale: refresh_pattern last-mod factor percentage");
680  refreshCountsStatsEntry(sentry, rc, STALE_DEFAULT, "Stale: by default");
681  storeAppendPrintf(sentry, "\n");
682 }
683 
684 static void
686 {
687  // display per-rule counts of usage and tests
688  storeAppendPrintf(sentry, "\nRefresh pattern usage:\n\n");
689  storeAppendPrintf(sentry, " Used \tChecks \t%% Matches\tPattern\n");
690  for (const RefreshPattern *R = Config.Refresh; R; R = R->next) {
691  storeAppendPrintf(sentry, " %10" PRIu64 "\t%10" PRIu64 "\t%6.2f\t",
692  R->stats.matchCount,
693  R->stats.matchTests,
694  xpercent(R->stats.matchCount, R->stats.matchTests));
695  PackableStream os(*sentry);
696  R->printPattern(os);
697  os << "\n";
698  }
699 
700  int i;
701  int total = 0;
702 
703  /* get total usage count */
704 
705  for (i = 0; i < rcCount; ++i)
706  total += refreshCounts[i].total;
707 
708  /* protocol usage histogram */
709  storeAppendPrintf(sentry, "\nRefreshCheck calls per protocol\n\n");
710 
711  storeAppendPrintf(sentry, "Protocol\t#Calls\t%%Calls\n");
712 
713  for (i = 0; i < rcCount; ++i)
714  storeAppendPrintf(sentry, "%10s\t%6d\t%6.2f\n",
715  refreshCounts[i].proto,
716  refreshCounts[i].total,
717  xpercent(refreshCounts[i].total, total));
718 
719  /* per protocol histograms */
720  storeAppendPrintf(sentry, "\n\nRefreshCheck histograms for various protocols\n");
721 
722  for (i = 0; i < rcCount; ++i)
723  refreshCountsStats(sentry, refreshCounts[i]);
724 }
725 
726 const RegexPattern &
728 {
729  assert(regex_);
730  return *regex_;
731 }
732 
733 void
734 RefreshPattern::printPattern(std::ostream &os) const
735 {
736  if (regex_)
737  regex_->print(os, nullptr); // refresh lines do not inherit line flags
738  else
739  os << "<none>";
740 }
741 
742 void
743 RefreshPattern::printHead(std::ostream &os) const
744 {
745  printPattern(os);
746  os <<
747  // these adjustments are safe: raw values were configured using integers
748  ' ' << intmax_t(min/60) << // to minutes
749  ' ' << intmax_t(100.0 * pct + 0.5) << '%' << // to percentage points
750  ' ' << intmax_t(max/60); // to minutes
751 }
752 
753 static void
755 {
756  Mgr::RegisterAction("refresh", "Refresh Algorithm Statistics", refreshStats, 0, 1);
757 }
758 
759 void
761 {
762  memset(refreshCounts, 0, sizeof(refreshCounts));
763  refreshCounts[rcHTTP].proto = "HTTP";
764  refreshCounts[rcICP].proto = "ICP";
765 #if USE_HTCP
766 
767  refreshCounts[rcHTCP].proto = "HTCP";
768 #endif
769 
770  refreshCounts[rcStore].proto = "On Store";
771 #if USE_CACHE_DIGESTS
772 
773  refreshCounts[rcCDigest].proto = "Cache Digests";
774 #endif
775 
777 }
778 
static OBJH refreshStats
Definition: refresh.cc:82
time_t timestamp
Definition: Store.h:223
time_t maxStale
Definition: SquidConfig.h:104
static int refreshCountsStatsEntry(StoreEntry *sentry, struct RefreshCounts &rc, int code, const char *desc)
Definition: refresh.cc:651
const char * storeId() const
Definition: MemObject.cc:53
MemObject * mem_obj
Definition: Store.h:220
RequestFlags flags
Definition: HttpRequest.h:141
@ STALE_RELOAD_INTO_IMS
Definition: refresh.cc:66
bool min
Heuristic minimum age limited.
Definition: refresh.cc:46
bool hasMinFresh(int32_t *val=nullptr) const
Definition: HttpHdrCc.h:140
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:855
int refreshCheckICP(const StoreEntry *entry, HttpRequest *request)
Definition: refresh.cc:593
Definition: SBuf.h:93
a representation of a refresh pattern.
#define PRIu64
Definition: types.h:114
struct SquidConfig::@97 onoff
int refreshCheckHTCP(const StoreEntry *entry, HttpRequest *request)
Definition: refresh.cc:604
@ STALE_MAX_STALE
Definition: refresh.cc:72
C * getRaw() const
Definition: RefCount.h:89
uint16_t flags
Definition: Store.h:231
@ STALE_EXPIRES
Definition: refresh.cc:69
time_t expires
Definition: Store.h:225
time_t getMaxAge(const char *url)
Definition: refresh.cc:639
@ FRESH_OVERRIDE_LASTMOD
Definition: refresh.cc:64
const char * proto
Definition: refresh.cc:77
int refreshCheckHTTP(const StoreEntry *entry, HttpRequest *request)
Definition: refresh.cc:582
bool hasMaxStale(int32_t *val=nullptr) const
Definition: HttpHdrCc.h:132
@ rcICP
Definition: refresh.cc:30
static void refreshCountsStats(StoreEntry *sentry, struct RefreshCounts &rc)
Definition: refresh.cc:658
bool noCacheHack() const
Definition: RequestFlags.h:133
@ FRESH_MIN_RULE
Definition: refresh.cc:62
static const int32_t MAX_STALE_ANY
Definition: HttpHdrCc.h:53
RefreshPattern * Refresh
Definition: SquidConfig.h:421
const char * FormatRfc1123(time_t)
Definition: rfc1123.cc:202
struct RefreshPattern::@80 flags
void OBJH(StoreEntry *)
Definition: forward.h:44
@ FRESH_EXPIRES
Definition: refresh.cc:60
static struct RefreshCounts refreshCounts[rcCount]
const HttpReply & baseReply() const
Definition: MemObject.h:60
const RefreshPattern * refreshLimits(const char *url)
Definition: refresh.cc:92
double xpercent(double part, double whole)
Definition: util.cc:40
refreshCountsEnum
Definition: refresh.cc:28
static void refreshRegisterWithCacheManager(void)
Definition: refresh.cc:754
#define EBIT_TEST(flag, bit)
Definition: defines.h:67
bool failOnValidationError
Definition: RequestFlags.h:52
#define REFRESH_DEFAULT_MAX
@ FRESH_OVERRIDE_EXPIRES
Definition: refresh.cc:63
#define assert(EX)
Definition: assert.h:17
HttpHdrCc * cache_control
Definition: Message.h:76
@ FRESH_REQUEST_MAX_STALE_VALUE
Definition: refresh.cc:59
const RegexPattern & regex() const
configured regex; do not use except when iterating configured rules
Definition: refresh.cc:727
bool expires
Expires: header absolute timestamp limit.
Definition: refresh.cc:45
int refresh_all_ims
Definition: SquidConfig.h:290
static const RefreshPattern * refreshFirstDotRule()
the first explicit refresh_pattern rule that uses a "." regex (or nil)
Definition: refresh.cc:107
const char * c_str()
Definition: SBuf.cc:516
time_t squid_curtime
Definition: stub_libtime.cc:20
static int refreshCheck(const StoreEntry *entry, HttpRequest *request, time_t delta)
Definition: refresh.cc:253
int64_t content_length
Definition: Message.h:83
int code
Definition: smb-errors.c:145
@ FRESH_LMFACTOR_RULE
Definition: refresh.cc:61
RegexPointer regex_
configured regex or, for the implicit refresh_pattern rule, nil
bool hasStaleIfError(int32_t *val=nullptr) const
Definition: HttpHdrCc.h:150
void refreshInit(void)
Definition: refresh.cc:760
@ STALE_FORCED_RELOAD
Definition: refresh.cc:67
int status[STALE_DEFAULT+1]
Definition: refresh.cc:79
@ rcHTCP
Definition: refresh.cc:32
@ rcCDigest
Definition: refresh.cc:35
static int refreshStaleness(const StoreEntry *entry, time_t check_time, const time_t age, const RefreshPattern *R, stale_flags *sf)
Definition: refresh.cc:139
static bool refreshIsStaleIfHit(const int reason)
whether reply is stale if it is a hit
Definition: refresh.cc:557
bool hasMaxAge(int32_t *val=nullptr) const
Definition: HttpHdrCc.h:122
int reload_into_ims
Definition: SquidConfig.h:293
@ STALE_LMFACTOR_RULE
Definition: refresh.cc:71
void RegisterAction(char const *action, char const *desc, OBJH *handler, Protected, Atomic, Format)
Definition: Registration.cc:54
bool refreshIsCachable(const StoreEntry *entry)
Definition: refresh.cc:518
static RefreshPattern DefaultRefresh(nullptr)
@ STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE
Definition: refresh.cc:68
int refreshCheckDigest(const StoreEntry *entry, time_t delta)
Definition: refresh.cc:617
time_t minimum_expiry_time
Definition: SquidConfig.h:502
void printPattern(std::ostream &os) const
reports the configured pattern or a fake pattern of the implicit rule
Definition: refresh.cc:734
@ STALE_MUST_REVALIDATE
Definition: refresh.cc:65
void lastModified(const time_t when)
Definition: Store.h:175
@ rcStore
Definition: refresh.cc:37
@ FRESH_REQUEST_MAX_STALE_ALL
Definition: refresh.cc:58
@ ENTRY_REVALIDATE_STALE
Definition: enums.h:95
bool lmfactor
Last-Modified with heuristic determines limit.
Definition: refresh.cc:47
@ rcCount
Definition: refresh.cc:38
RefreshPattern * next
@ ENTRY_REVALIDATE_ALWAYS
Definition: enums.h:80
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
Definition: HttpRequest.cc:744
void printHead(std::ostream &) const
reports configuration excluding trailing options
Definition: refresh.cc:743
const HttpReply * hasFreshestReply() const
Definition: Store.h:53
bool max
Configured maximum age limit.
Definition: refresh.cc:48
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
const A & min(A const &lhs, A const &rhs)
HttpRequestPointer request
Definition: MemObject.h:205
@ STALE_MAX_RULE
Definition: refresh.cc:70
class SquidConfig Config
Definition: SquidConfig.cc:12
@ STALE_DEFAULT
Definition: refresh.cc:73
@ rcHTTP
Definition: refresh.cc:29

 

Introduction

Documentation

Support

Miscellaneous