]> git.ipfire.org Git - thirdparty/squid.git/blame - src/HttpHdrCc.h
NoNewGlobals for HttpHdrCc:ccLookupTable (#1750)
[thirdparty/squid.git] / src / HttpHdrCc.h
CommitLineData
0abdd70d 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
0abdd70d 3 *
bbc27441
AJ
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.
0abdd70d
FC
7 */
8
ff9d9458
FC
9#ifndef SQUID_SRC_HTTPHDRCC_H
10#define SQUID_SRC_HTTPHDRCC_H
0abdd70d 11
22056ef8 12#include "defines.h"
b56ab9e7 13#include "dlink.h"
ed6e9fb9 14#include "mem/forward.h"
0abdd70d 15#include "SquidString.h"
6b1c9146 16#include <iosfwd>
0abdd70d 17
17802cf1 18class Packable;
43ca19e0 19
1da82544 20enum HttpHdrCcType : unsigned char {
b56ab9e7
FC
21 CC_PUBLIC = 0,
22 CC_PRIVATE,
23 CC_NO_CACHE,
24 CC_NO_STORE,
25 CC_NO_TRANSFORM,
26 CC_MUST_REVALIDATE,
27 CC_PROXY_REVALIDATE,
28 CC_MAX_AGE,
29 CC_S_MAXAGE,
30 CC_MAX_STALE,
31 CC_MIN_FRESH,
32 CC_ONLY_IF_CACHED,
33 CC_STALE_IF_ERROR,
8311b837 34 CC_IMMUTABLE, /* RFC 8246 */
b56ab9e7
FC
35 CC_OTHER,
36 CC_ENUM_END /* also used to mean "invalid" */
1da82544 37};
b56ab9e7 38
7ebe76de 39/** Http Cache-Control header representation
ce394734 40 *
7ebe76de 41 * Store and parse the Cache-Control HTTP header.
ce394734 42 */
0abdd70d
FC
43class HttpHdrCc
44{
741c2986 45 MEMPROXY_CLASS(HttpHdrCc);
0abdd70d
FC
46
47public:
77da1817
A
48 static const int32_t MAX_AGE_UNKNOWN=-1; //max-age is unset
49 static const int32_t S_MAXAGE_UNKNOWN=-1; //s-maxage is unset
50 static const int32_t MAX_STALE_UNKNOWN=-1; //max-stale is unset
51 ///used to mark a valueless Cache-Control: max-stale directive, which instructs
52 /// us to treat responses of any age as fresh
53 static const int32_t MAX_STALE_ANY=0x7fffffff;
54 static const int32_t STALE_IF_ERROR_UNKNOWN=-1; //stale_if_error is unset
55 static const int32_t MIN_FRESH_UNKNOWN=-1; //min_fresh is unset
70aff22f 56
c57b8f05 57 HttpHdrCc() :
f53969cc
SM
58 mask(0), max_age(MAX_AGE_UNKNOWN), s_maxage(S_MAXAGE_UNKNOWN),
59 max_stale(MAX_STALE_UNKNOWN), stale_if_error(STALE_IF_ERROR_UNKNOWN),
60 min_fresh(MIN_FRESH_UNKNOWN) {}
ce394734 61
c57b8f05 62 /// reset data-members to default state
ce394734 63 void clear();
c57b8f05
FC
64
65 /// parse a header-string and fill in appropriate values.
1ba0611a 66 bool parse(const String & s);
70aff22f 67
cf7c2e94 68 //manipulation for Cache-Control: public header
1da82544 69 bool hasPublic() const {return isSet(HttpHdrCcType::CC_PUBLIC);}
1da82544
FC
70 void Public(bool v) {setMask(HttpHdrCcType::CC_PUBLIC,v);}
71 void clearPublic() {setMask(HttpHdrCcType::CC_PUBLIC,false);}
cf7c2e94
FC
72
73 //manipulation for Cache-Control: private header
810d879f 74 bool hasPrivate(const String **val = nullptr) const { return hasDirective(HttpHdrCcType::CC_PRIVATE, &private_, val); }
43446566 75 void Private(const String &v) {
1da82544 76 setMask(HttpHdrCcType::CC_PRIVATE,true);
43446566
AR
77 if (!v.size())
78 return;
1259f9cf 79 // uses append for multi-line headers
b38b26cb 80 if (private_.size() > 0)
1259f9cf
AJ
81 private_.append(",");
82 private_.append(v);
83 }
1da82544 84 void clearPrivate() {setMask(HttpHdrCcType::CC_PRIVATE,false); private_.clean();}
cf7c2e94
FC
85
86 //manipulation for Cache-Control: no-cache header
810d879f
EB
87 bool hasNoCacheWithParameters() const { return hasNoCache() && no_cache.size(); }
88 bool hasNoCacheWithoutParameters() const { return hasNoCache() && !no_cache.size(); }
89 bool hasNoCache(const String **val = nullptr) const { return hasDirective(HttpHdrCcType::CC_NO_CACHE, &no_cache, val); }
43446566 90 void noCache(const String &v) {
1da82544 91 setMask(HttpHdrCcType::CC_NO_CACHE,true);
43446566
AR
92 if (!v.size())
93 return;
1259f9cf 94 // uses append for multi-line headers
43446566 95 if (no_cache.size() > 0 && v.size() > 0)
1259f9cf
AJ
96 no_cache.append(",");
97 no_cache.append(v);
98 }
1da82544 99 void clearNoCache() {setMask(HttpHdrCcType::CC_NO_CACHE,false); no_cache.clean();}
cf7c2e94
FC
100
101 //manipulation for Cache-Control: no-store header
1da82544 102 bool hasNoStore() const {return isSet(HttpHdrCcType::CC_NO_STORE);}
1da82544
FC
103 void noStore(bool v) {setMask(HttpHdrCcType::CC_NO_STORE,v);}
104 void clearNoStore() {setMask(HttpHdrCcType::CC_NO_STORE,false);}
cf7c2e94
FC
105
106 //manipulation for Cache-Control: no-transform header
1da82544 107 bool hasNoTransform() const {return isSet(HttpHdrCcType::CC_NO_TRANSFORM);}
1da82544
FC
108 void noTransform(bool v) {setMask(HttpHdrCcType::CC_NO_TRANSFORM,v);}
109 void clearNoTransform() {setMask(HttpHdrCcType::CC_NO_TRANSFORM,false);}
cf7c2e94
FC
110
111 //manipulation for Cache-Control: must-revalidate header
1da82544 112 bool hasMustRevalidate() const {return isSet(HttpHdrCcType::CC_MUST_REVALIDATE);}
1da82544
FC
113 void mustRevalidate(bool v) {setMask(HttpHdrCcType::CC_MUST_REVALIDATE,v);}
114 void clearMustRevalidate() {setMask(HttpHdrCcType::CC_MUST_REVALIDATE,false);}
cf7c2e94
FC
115
116 //manipulation for Cache-Control: proxy-revalidate header
1da82544 117 bool hasProxyRevalidate() const {return isSet(HttpHdrCcType::CC_PROXY_REVALIDATE);}
1da82544
FC
118 void proxyRevalidate(bool v) {setMask(HttpHdrCcType::CC_PROXY_REVALIDATE,v);}
119 void clearProxyRevalidate() {setMask(HttpHdrCcType::CC_PROXY_REVALIDATE,false);}
cf7c2e94
FC
120
121 //manipulation for Cache-Control: max-age header
810d879f 122 bool hasMaxAge(int32_t *val = nullptr) const { return hasDirective(HttpHdrCcType::CC_MAX_AGE, max_age, val); }
1da82544
FC
123 void maxAge(int32_t v) {setValue(max_age,v,HttpHdrCcType::CC_MAX_AGE); }
124 void clearMaxAge() {setValue(max_age,MAX_AGE_UNKNOWN,HttpHdrCcType::CC_MAX_AGE,false);}
cf7c2e94 125
4ce6e3b5 126 //manipulation for Cache-Control: s-maxage header
810d879f 127 bool hasSMaxAge(int32_t *val = nullptr) const { return hasDirective(HttpHdrCcType::CC_S_MAXAGE, s_maxage, val); }
1da82544
FC
128 void sMaxAge(int32_t v) {setValue(s_maxage,v,HttpHdrCcType::CC_S_MAXAGE); }
129 void clearSMaxAge() {setValue(s_maxage,MAX_AGE_UNKNOWN,HttpHdrCcType::CC_S_MAXAGE,false);}
4ce6e3b5
FC
130
131 //manipulation for Cache-Control: max-stale header
810d879f 132 bool hasMaxStale(int32_t *val = nullptr) const { return hasDirective(HttpHdrCcType::CC_MAX_STALE, max_stale, val); }
d74ad83f 133 // max-stale has a special value (MAX_STALE_ANY) which correspond to having
4ce6e3b5
FC
134 // the directive without a numeric specification, and directs to consider the object
135 // as always-expired.
1da82544
FC
136 void maxStale(int32_t v) {setValue(max_stale,v,HttpHdrCcType::CC_MAX_STALE);}
137 void clearMaxStale() {setValue(max_stale,MAX_STALE_UNKNOWN,HttpHdrCcType::CC_MAX_STALE,false);}
4ce6e3b5
FC
138
139 //manipulation for Cache-Control:min-fresh header
e0072b1d 140 bool hasMinFresh(int32_t *val = nullptr) const { return hasDirective(HttpHdrCcType::CC_MIN_FRESH, min_fresh, val); }
1da82544
FC
141 void minFresh(int32_t v) {if (v < 0) return; setValue(min_fresh,v,HttpHdrCcType::CC_MIN_FRESH); }
142 void clearMinFresh() {setValue(min_fresh,MIN_FRESH_UNKNOWN,HttpHdrCcType::CC_MIN_FRESH,false);}
4ce6e3b5
FC
143
144 //manipulation for Cache-Control: only-if-cached header
1da82544 145 bool hasOnlyIfCached() const {return isSet(HttpHdrCcType::CC_ONLY_IF_CACHED);}
1da82544
FC
146 void onlyIfCached(bool v) {setMask(HttpHdrCcType::CC_ONLY_IF_CACHED,v);}
147 void clearOnlyIfCached() {setMask(HttpHdrCcType::CC_ONLY_IF_CACHED,false);}
4ce6e3b5
FC
148
149 //manipulation for Cache-Control: stale-if-error header
810d879f 150 bool hasStaleIfError(int32_t *val = nullptr) const { return hasDirective(HttpHdrCcType::CC_STALE_IF_ERROR, stale_if_error, val); }
1da82544
FC
151 void staleIfError(int32_t v) {setValue(stale_if_error,v,HttpHdrCcType::CC_STALE_IF_ERROR); }
152 void clearStaleIfError() {setValue(stale_if_error,STALE_IF_ERROR_UNKNOWN,HttpHdrCcType::CC_STALE_IF_ERROR,false);}
cf7c2e94 153
caf65351 154 //manipulation for Cache-Control: immutable header
810d879f 155 bool hasImmutable() const {return isSet(HttpHdrCcType::CC_IMMUTABLE);}
caf65351
AJ
156 void Immutable(bool v) {setMask(HttpHdrCcType::CC_IMMUTABLE,v);}
157 void clearImmutable() {setMask(HttpHdrCcType::CC_IMMUTABLE,false);}
158
cf7c2e94 159 /// check whether the attribute value supplied by id is set
22056ef8
AJ
160 bool isSet(HttpHdrCcType id) const {
161 assert(id < HttpHdrCcType::CC_ENUM_END);
162 return EBIT_TEST(mask, static_cast<long>(id));
163 }
cf7c2e94 164
17802cf1 165 void packInto(Packable * p) const;
4ce6e3b5 166
c57b8f05
FC
167 /** bit-mask representing what header values are set among those
168 * recognized by squid.
169 *
170 * managed via EBIT_SET/TEST/CLR
171 */
1ba0611a 172private:
b17b9d8d 173 int32_t mask;
7ebe76de
FC
174 int32_t max_age;
175 int32_t s_maxage;
176 int32_t max_stale;
177 int32_t stale_if_error;
178 int32_t min_fresh;
1259f9cf
AJ
179 String private_; ///< List of headers sent as value for CC:private="...". May be empty/undefined if the value is missing.
180 String no_cache; ///< List of headers sent as value for CC:no-cache="...". May be empty/undefined if the value is missing.
181
810d879f
EB
182 /// implements typical has*() method logic
183 template<class Value>
184 bool hasDirective(const HttpHdrCcType hdrType, const Value &parsedVal, Value *outVal = nullptr) const {
185 if (isSet(hdrType)) {
186 if (outVal)
187 *outVal = parsedVal;
188 return true;
189 }
190 return false;
191 }
192
cf7c2e94 193 /// low-level part of the public set method, performs no checks
22056ef8
AJ
194 void setMask(HttpHdrCcType id, bool newval=true) {
195 if (newval)
196 EBIT_SET(mask,static_cast<long>(id));
197 else
198 EBIT_CLR(mask, static_cast<long>(id));
199 }
200
201 void setValue(int32_t &value, int32_t new_value, HttpHdrCcType hdr, bool setting=true);
cf7c2e94 202
422acb7f 203public:
c57b8f05
FC
204 /**comma-separated representation of the header values which were
205 * received but are not recognized.
206 */
7ebe76de 207 String other;
0abdd70d
FC
208};
209
9a117495
FC
210class StatHist;
211class StoreEntry;
212
8a648e8d
FC
213void httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist);
214void httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count);
9a117495 215
22056ef8 216std::ostream & operator<< (std::ostream &, HttpHdrCcType);
9774b48e 217
ff9d9458 218#endif /* SQUID_SRC_HTTPHDRCC_H */
f53969cc 219