From: Amos Jeffries Date: Tue, 25 May 2010 10:30:55 +0000 (+1200) Subject: Author: Mark Nottingham X-Git-Tag: SQUID_3_2_0_1~198 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3d8b6ba4c6e56fa095348ff59329b858d2eae5a7;p=thirdparty%2Fsquid.git Author: Mark Nottingham Bug 2631: store-stale refresh_pattern option RFC2616 allows almost anything to be cached*; most of the constraints are on what can be used out of cache. For example, this response: HTTP/1.1 200 OK Content-Type: text/html Date: [date] [ content ] is cacheable as per HTTP; it just is considered stale as soon as it is cached. However, Squid (and many others) don't cache all of these responses, at least in part because doing so would decrease cache efficiency, and introduce more load (e.g., on disk subsystems, etc.). In particular, Squid won't cache a response unless it has either explicit freshness (e.g., Expires, CC: max-age) or a validator (Last-Modified or ETag). Nevertheless, doing so is desirable in some circumstances, because in some deployments the client wants to be able to ask for a stale response. For example; GET /foo HTTP/1.1 Host: example.com Cache-Control: max-age=3600, max-stale Should retrieve the above response from cache, as long as it is less than an hour old. This patch adds a 'store-stale' refresh_pattern option that allows this. --- diff --git a/src/cache_cf.cc b/src/cache_cf.cc index b81cc47e99..c391c34f05 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -2254,6 +2254,9 @@ dump_refreshpattern(StoreEntry * entry, const char *name, refresh_t * head) if (head->flags.refresh_ims) storeAppendPrintf(entry, " refresh-ims"); + if (head->flags.store_stale) + storeAppendPrintf(entry, " store-stale"); + #if HTTP_VIOLATIONS if (head->flags.override_expire) @@ -2300,6 +2303,8 @@ parse_refreshpattern(refresh_t ** head) double pct = 0.0; time_t max = 0; int refresh_ims = 0; + int store_stale = 0; + #if HTTP_VIOLATIONS int override_expire = 0; @@ -2355,6 +2360,8 @@ parse_refreshpattern(refresh_t ** head) while ((token = strtok(NULL, w_space)) != NULL) { if (!strcmp(token, "refresh-ims")) { refresh_ims = 1; + } else if (!strcmp(token, "store-stale")) { + store_stale = 1; #if HTTP_VIOLATIONS } else if (!strcmp(token, "override-expire")) @@ -2408,6 +2415,9 @@ parse_refreshpattern(refresh_t ** head) if (refresh_ims) t->flags.refresh_ims = 1; + if (store_stale) + t->flags.store_stale = 1; + #if HTTP_VIOLATIONS if (override_expire) diff --git a/src/cf.data.pre b/src/cf.data.pre index 32b93edba5..30acb60522 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -3445,6 +3445,7 @@ DOC_START ignore-private ignore-auth refresh-ims + store-stale override-expire enforces min age even if the server sent an explicit expiry time (e.g., with the @@ -3502,6 +3503,12 @@ DOC_START ensures that the client will receive an updated version if one is available. + store-stale stores responses even if they don't have explicit + freshness or a validator (i.e., Last-Modified or an ETag) + present, or if they're already stale. By default, Squid will + not cache such responses because they usually can't be + reused. Note that such responses will be stale by default. + Basically a cached object is: FRESH if expires < now, else STALE diff --git a/src/http.cc b/src/http.cc index c14060cb1b..6bf8bab74a 100644 --- a/src/http.cc +++ b/src/http.cc @@ -438,7 +438,7 @@ HttpStateData::cacheableReply() * unless we know how to refresh it. */ - if (!refreshIsCachable(entry)) { + if (!refreshIsCachable(entry) && !REFRESH_OVERRIDE(store_stale)) { debugs(22, 3, "refreshIsCachable() returned non-cacheable.."); return 0; } diff --git a/src/structs.h b/src/structs.h index 4217ff81d3..266861bf74 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1082,6 +1082,7 @@ struct _refresh_t { struct { unsigned int icase:1; unsigned int refresh_ims:1; + unsigned int store_stale:1; #if HTTP_VIOLATIONS unsigned int override_expire:1; unsigned int override_lastmod:1;