HttpHdrCc.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 65 HTTP Cache Control Header */
10
11#include "squid.h"
12#include "base/LookupTable.h"
13#include "HttpHdrCc.h"
14#include "HttpHeader.h"
15#include "HttpHeaderFieldStat.h"
16#include "HttpHeaderStat.h"
17#include "HttpHeaderTools.h"
18#include "sbuf/SBuf.h"
19#include "StatHist.h"
20#include "Store.h"
21#include "StrList.h"
22#include "util.h"
23
24#include <map>
25#include <vector>
26#include <ostream>
27
28// invariant: row[j].id == j
30 {"public", HttpHdrCcType::CC_PUBLIC},
31 {"private", HttpHdrCcType::CC_PRIVATE},
32 {"no-cache", HttpHdrCcType::CC_NO_CACHE},
33 {"no-store", HttpHdrCcType::CC_NO_STORE},
34 {"no-transform", HttpHdrCcType::CC_NO_TRANSFORM},
35 {"must-revalidate", HttpHdrCcType::CC_MUST_REVALIDATE},
36 {"proxy-revalidate", HttpHdrCcType::CC_PROXY_REVALIDATE},
37 {"max-age", HttpHdrCcType::CC_MAX_AGE},
38 {"s-maxage", HttpHdrCcType::CC_S_MAXAGE},
39 {"max-stale", HttpHdrCcType::CC_MAX_STALE},
40 {"min-fresh", HttpHdrCcType::CC_MIN_FRESH},
41 {"only-if-cached", HttpHdrCcType::CC_ONLY_IF_CACHED},
42 {"stale-if-error", HttpHdrCcType::CC_STALE_IF_ERROR},
43 {"immutable", HttpHdrCcType::CC_IMMUTABLE},
44 {"Other,", HttpHdrCcType::CC_OTHER}, /* ',' will protect from matches */
46};
48std::vector<HttpHeaderFieldStat> ccHeaderStats(HttpHdrCcType::CC_ENUM_END);
49
51static HttpHdrCcType &
53{
54 int tmp = (int)aHeader;
55 aHeader = (HttpHdrCcType)(++tmp);
56 return aHeader;
57}
58
60void
62{
63 // check invariant on initialization table
64 for (unsigned int j = 0; CcAttrs[j].name != nullptr; ++j) {
65 assert(static_cast<decltype(j)>(CcAttrs[j].id) == j);
66 }
67}
68
69void
71{
72 *this=HttpHdrCc();
73}
74
77void
78HttpHdrCc::setValue(int32_t &value, int32_t new_value, HttpHdrCcType hdr, bool setting)
79{
80 if (setting) {
81 if (new_value < 0) {
82 debugs(65, 3, "rejecting negative-value Cache-Control directive " << hdr
83 << " value " << new_value);
84 return;
85 }
86 } else {
87 new_value = -1; //rely on the convention that "unknown" is -1
88 }
89
90 value = new_value;
91 setMask(hdr,setting);
92}
93
94bool
96{
97 const char *item;
98 const char *p; /* '=' parameter */
99 const char *pos = nullptr;
100 int ilen;
101 int nlen;
102
103 /* iterate through comma separated list */
104
105 while (strListGetItem(&str, ',', &item, &ilen, &pos)) {
106 /* isolate directive name */
107
108 if ((p = (const char *)memchr(item, '=', ilen)) && (p - item < ilen)) {
109 nlen = p - item;
110 ++p;
111 } else {
112 nlen = ilen;
113 }
114
115 /* find type */
116 const HttpHdrCcType type = ccLookupTable.lookup(SBuf(item,nlen));
117
118 // ignore known duplicate directives
119 if (isSet(type)) {
120 if (type != HttpHdrCcType::CC_OTHER) {
121 debugs(65, 2, "hdr cc: ignoring duplicate cache-directive: near '" << item << "' in '" << str << "'");
122 ++ ccHeaderStats[type].repCount;
123 continue;
124 }
125 }
126
127 /* special-case-parsing and attribute-setting */
128 switch (type) {
129
131 if (!p || !httpHeaderParseInt(p, &max_age) || max_age < 0) {
132 debugs(65, 2, "cc: invalid max-age specs near '" << item << "'");
133 clearMaxAge();
134 } else {
135 setMask(type,true);
136 }
137 break;
138
140 if (!p || !httpHeaderParseInt(p, &s_maxage) || s_maxage < 0) {
141 debugs(65, 2, "cc: invalid s-maxage specs near '" << item << "'");
142 clearSMaxAge();
143 } else {
144 setMask(type,true);
145 }
146 break;
147
149 if (!p || !httpHeaderParseInt(p, &max_stale) || max_stale < 0) {
150 debugs(65, 2, "cc: max-stale directive is valid without value");
152 } else {
153 setMask(type,true);
154 }
155 break;
156
158 if (!p || !httpHeaderParseInt(p, &min_fresh) || min_fresh < 0) {
159 debugs(65, 2, "cc: invalid min-fresh specs near '" << item << "'");
161 } else {
162 setMask(type,true);
163 }
164 break;
165
167 if (!p || !httpHeaderParseInt(p, &stale_if_error) || stale_if_error < 0) {
168 debugs(65, 2, "cc: invalid stale-if-error specs near '" << item << "'");
170 } else {
171 setMask(type,true);
172 }
173 break;
174
176 String temp;
177 if (!p) {
178 // Value parameter is optional.
179 private_.clean();
180 } else if (/* p &&*/ httpHeaderParseQuotedString(p, (ilen-nlen-1), &temp)) {
181 private_.append(temp);
182 } else {
183 debugs(65, 2, "cc: invalid private= specs near '" << item << "'");
184 }
185 // to be safe we ignore broken parameters, but always remember the 'private' part.
186 setMask(type,true);
187 }
188 break;
189
191 String temp;
192 if (!p) {
193 // On Requests, missing value parameter is expected syntax.
194 // On Responses, value parameter is optional.
195 setMask(type,true);
196 no_cache.clean();
197 } else if (/* p &&*/ httpHeaderParseQuotedString(p, (ilen-nlen-1), &temp)) {
198 // On Requests, a value parameter is invalid syntax.
199 // XXX: identify when parsing request header and dump err message here.
200 setMask(type,true);
201 no_cache.append(temp);
202 } else {
203 debugs(65, 2, "cc: invalid no-cache= specs near '" << item << "'");
204 }
205 }
206 break;
207
209 Public(true);
210 break;
212 noStore(true);
213 break;
215 noTransform(true);
216 break;
218 mustRevalidate(true);
219 break;
221 proxyRevalidate(true);
222 break;
224 onlyIfCached(true);
225 break;
227 Immutable(true);
228 break;
229
231 if (other.size())
232 other.append(", ");
233
234 other.append(item, ilen);
235 break;
236
237 default:
238 /* note that we ignore most of '=' specs (RFCVIOLATION) */
239 break;
240 }
241 }
242
243 return (mask != 0);
244}
245
246void
248{
249 // optimization: if the mask is empty do nothing
250 if (mask==0)
251 return;
252
253 HttpHdrCcType flag;
254 int pcount = 0;
255 assert(p);
256
257 for (flag = HttpHdrCcType::CC_PUBLIC; flag < HttpHdrCcType::CC_ENUM_END; ++flag) {
258 if (isSet(flag) && flag != HttpHdrCcType::CC_OTHER) {
259
260 /* print option name for all options */
261 p->appendf((pcount ? ", %s": "%s"), CcAttrs[flag].name);
262
263 /* for all options having values, "=value" after the name */
264 switch (flag) {
266 break;
268 if (private_.size())
270 break;
271
273 if (no_cache.size())
275 break;
277 break;
279 break;
281 break;
283 break;
285 p->appendf("=%d", max_age);
286 break;
288 p->appendf("=%d", s_maxage);
289 break;
291 /* max-stale's value is optional.
292 If we didn't receive it, don't send it */
294 p->appendf("=%d", max_stale);
295 break;
297 p->appendf("=%d", min_fresh);
298 break;
300 break;
302 p->appendf("=%d", stale_if_error);
303 break;
305 break;
308 // done below after the loop
309 break;
310 }
311
312 ++pcount;
313 }
314 }
315
316 if (other.size() != 0)
318}
319
320void
322{
323 assert(cc);
324
326 if (cc->isSet(c))
327 hist->count(c);
328}
329
330void
331httpHdrCcStatDumper(StoreEntry * sentry, int, double val, double, int count)
332{
333 extern const HttpHeaderStat *dump_stat; /* argh! */
334 const int id = static_cast<int>(val);
335 const bool valid_id = id >= 0 && id < static_cast<int>(HttpHdrCcType::CC_ENUM_END);
336 const char *name = valid_id ? CcAttrs[id].name : "INVALID";
337
338 if (count || valid_id)
339 storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n",
340 id, name, count, xdiv(count, dump_stat->ccParsedCount));
341}
342
343std::ostream &
344operator<< (std::ostream &s, HttpHdrCcType c)
345{
346 const unsigned char ic = static_cast<int>(c);
348 s << CcAttrs[ic].name << '[' << ic << ']' ;
349 else
350 s << "*invalid hdrcc* [" << ic << ']';
351 return s;
352}
353
void httpHdrCcUpdateStats(const HttpHdrCc *cc, StatHist *hist)
Definition: HttpHdrCc.cc:321
void httpHdrCcInitModule(void)
Module initialization hook.
Definition: HttpHdrCc.cc:61
LookupTable< HttpHdrCcType > ccLookupTable(HttpHdrCcType::CC_OTHER, CcAttrs)
static LookupTable< HttpHdrCcType >::Record CcAttrs[]
Definition: HttpHdrCc.cc:29
std::ostream & operator<<(std::ostream &s, HttpHdrCcType c)
Definition: HttpHdrCc.cc:344
void httpHdrCcStatDumper(StoreEntry *sentry, int, double val, double, int count)
Definition: HttpHdrCc.cc:331
static HttpHdrCcType & operator++(HttpHdrCcType &aHeader)
used to walk a table of http_header_cc_type structs
Definition: HttpHdrCc.cc:52
std::vector< HttpHeaderFieldStat > ccHeaderStats(HttpHdrCcType::CC_ENUM_END)
HttpHdrCcType
Definition: HttpHdrCc.h:20
@ CC_MUST_REVALIDATE
Definition: HttpHdrCc.h:26
@ CC_S_MAXAGE
Definition: HttpHdrCc.h:29
@ CC_ONLY_IF_CACHED
Definition: HttpHdrCc.h:32
@ CC_OTHER
Definition: HttpHdrCc.h:35
@ CC_ENUM_END
Definition: HttpHdrCc.h:36
@ CC_NO_STORE
Definition: HttpHdrCc.h:24
@ CC_PUBLIC
Definition: HttpHdrCc.h:21
@ CC_PRIVATE
Definition: HttpHdrCc.h:22
@ CC_MAX_STALE
Definition: HttpHdrCc.h:30
@ CC_STALE_IF_ERROR
Definition: HttpHdrCc.h:33
@ CC_IMMUTABLE
Definition: HttpHdrCc.h:34
@ CC_PROXY_REVALIDATE
Definition: HttpHdrCc.h:27
@ CC_NO_CACHE
Definition: HttpHdrCc.h:23
@ CC_MAX_AGE
Definition: HttpHdrCc.h:28
@ CC_NO_TRANSFORM
Definition: HttpHdrCc.h:25
@ CC_MIN_FRESH
Definition: HttpHdrCc.h:31
int httpHeaderParseInt(const char *start, int *value)
const HttpHeaderStat * dump_stat
Definition: HttpHeader.cc:1562
int httpHeaderParseQuotedString(const char *start, const int len, String *val)
#define SQUIDSTRINGPH
Definition: SquidString.h:21
#define SQUIDSTRINGPRINT(s)
Definition: SquidString.h:22
int strListGetItem(const String *str, char del, const char **item, int *ilen, const char **pos)
Definition: StrList.cc:86
#define assert(EX)
Definition: assert.h:17
void clear()
reset data-members to default state
Definition: HttpHdrCc.cc:70
String no_cache
List of headers sent as value for CC:no-cache="...". May be empty/undefined if the value is missing.
Definition: HttpHdrCc.h:180
void mustRevalidate(bool v)
Definition: HttpHdrCc.h:113
void clearMinFresh()
Definition: HttpHdrCc.h:142
void Immutable(bool v)
Definition: HttpHdrCc.h:156
void Public(bool v)
Definition: HttpHdrCc.h:70
void noTransform(bool v)
Definition: HttpHdrCc.h:108
void setMask(HttpHdrCcType id, bool newval=true)
low-level part of the public set method, performs no checks
Definition: HttpHdrCc.h:194
bool parse(const String &s)
parse a header-string and fill in appropriate values.
Definition: HttpHdrCc.cc:95
void clearMaxAge()
Definition: HttpHdrCc.h:124
bool isSet(HttpHdrCcType id) const
check whether the attribute value supplied by id is set
Definition: HttpHdrCc.h:160
String private_
List of headers sent as value for CC:private="...". May be empty/undefined if the value is missing.
Definition: HttpHdrCc.h:179
int32_t max_stale
Definition: HttpHdrCc.h:176
void onlyIfCached(bool v)
Definition: HttpHdrCc.h:146
void clearSMaxAge()
Definition: HttpHdrCc.h:129
static const int32_t MAX_STALE_ANY
Definition: HttpHdrCc.h:53
void setValue(int32_t &value, int32_t new_value, HttpHdrCcType hdr, bool setting=true)
Definition: HttpHdrCc.cc:78
int32_t mask
Definition: HttpHdrCc.h:173
int32_t min_fresh
Definition: HttpHdrCc.h:178
void clearStaleIfError()
Definition: HttpHdrCc.h:152
int32_t max_age
Definition: HttpHdrCc.h:174
HttpHdrCc()
Definition: HttpHdrCc.h:57
void noStore(bool v)
Definition: HttpHdrCc.h:103
String other
Definition: HttpHdrCc.h:207
void maxStale(int32_t v)
Definition: HttpHdrCc.h:136
void proxyRevalidate(bool v)
Definition: HttpHdrCc.h:118
int32_t s_maxage
Definition: HttpHdrCc.h:175
void packInto(Packable *p) const
Definition: HttpHdrCc.cc:247
int32_t stale_if_error
Definition: HttpHdrCc.h:177
HTTP per header statistics.
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
Definition: SBuf.h:94
void count(double val)
Definition: StatHist.cc:55
void clean()
Definition: String.cc:103
void append(char const *buf, int len)
Definition: String.cc:130
size_type size() const
Definition: SquidString.h:73
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:841
int unsigned int
Definition: stub_fd.cc:19
SQUIDCEXTERN double xdiv(double nom, double denom)
Definition: util.c:53

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors