]> git.ipfire.org Git - thirdparty/squid.git/blame - src/HttpHdrCc.cc
merge changes from SQUID_2_3 branch
[thirdparty/squid.git] / src / HttpHdrCc.cc
CommitLineData
7faf2bdb 1
2/*
7e3ce7b9 3 * $Id: HttpHdrCc.cc,v 1.19 1999/12/30 17:36:16 wessels Exp $
7faf2bdb 4 *
5 * DEBUG: section 65 HTTP Cache Control Header
6 * AUTHOR: Alex Rousskov
7 *
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
e25c139f 9 * ----------------------------------------------------------
7faf2bdb 10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
e25c139f 13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
7faf2bdb 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.
e25c139f 24 *
7faf2bdb 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.
e25c139f 29 *
7faf2bdb 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.
7faf2bdb 33 *
34 */
35
36#include "squid.h"
37
de336bbe 38/* this table is used for parsing cache control header */
39static const HttpHeaderFieldAttrs CcAttrs[CC_ENUM_END] =
7faf2bdb 40{
41 {"public", CC_PUBLIC},
42 {"private", CC_PRIVATE},
43 {"no-cache", CC_NO_CACHE},
44 {"no-store", CC_NO_STORE},
45 {"no-transform", CC_NO_TRANSFORM},
46 {"must-revalidate", CC_MUST_REVALIDATE},
47 {"proxy-revalidate", CC_PROXY_REVALIDATE},
d8b249ef 48 {"only-if-cached", CC_ONLY_IF_CACHED},
49 {"max-age", CC_MAX_AGE},
7e3ce7b9 50 {"s-maxage", CC_S_MAXAGE},
8a21872b 51 {"Other,", CC_OTHER} /* ',' will protect from matches */
7faf2bdb 52};
de336bbe 53HttpHeaderFieldInfo *CcFieldsInfo = NULL;
7faf2bdb 54
b5107edb 55/* local prototypes */
5999b776 56static int httpHdrCcParseInit(HttpHdrCc * cc, const String * str);
7faf2bdb 57
58
59/* module initialization */
60
61void
9bc73deb 62httpHdrCcInitModule(void)
7faf2bdb 63{
de336bbe 64 CcFieldsInfo = httpHeaderBuildFieldsInfo(CcAttrs, CC_ENUM_END);
65}
66
67void
9bc73deb 68httpHdrCcCleanModule(void)
de336bbe 69{
70 httpHeaderDestroyFieldsInfo(CcFieldsInfo, CC_ENUM_END);
71 CcFieldsInfo = NULL;
7faf2bdb 72}
73
74/* implementation */
75
76HttpHdrCc *
9bc73deb 77httpHdrCcCreate(void)
7faf2bdb 78{
79 HttpHdrCc *cc = memAllocate(MEM_HTTP_HDR_CC);
7e3ce7b9 80 cc->max_age = cc->s_maxage = -1;
7faf2bdb 81 return cc;
82}
83
84/* creates an cc object from a 0-terminating string */
85HttpHdrCc *
5999b776 86httpHdrCcParseCreate(const String * str)
7faf2bdb 87{
88 HttpHdrCc *cc = httpHdrCcCreate();
b5107edb 89 if (!httpHdrCcParseInit(cc, str)) {
90 httpHdrCcDestroy(cc);
91 cc = NULL;
92 }
7faf2bdb 93 return cc;
94}
95
96/* parses a 0-terminating string and inits cc */
b5107edb 97static int
5999b776 98httpHdrCcParseInit(HttpHdrCc * cc, const String * str)
7faf2bdb 99{
100 const char *item;
101 const char *p; /* '=' parameter */
102 const char *pos = NULL;
103 int type;
104 int ilen;
105 assert(cc && str);
106
7faf2bdb 107 /* iterate through comma separated list */
108 while (strListGetItem(str, ',', &item, &ilen, &pos)) {
109 /* strip '=' statements @?@ */
110 if ((p = strchr(item, '=')) && (p - item < ilen))
111 ilen = p++ - item;
112 /* find type */
113 type = httpHeaderIdByName(item, ilen,
d8b249ef 114 CcFieldsInfo, CC_ENUM_END);
7faf2bdb 115 if (type < 0) {
99edd1c3 116 debug(65, 2) ("hdr cc: unknown cache-directive: near '%s' in '%s'\n", item, strBuf(*str));
d8b249ef 117 type = CC_OTHER;
7faf2bdb 118 }
119 if (EBIT_TEST(cc->mask, type)) {
d8b249ef 120 if (type != CC_OTHER)
99edd1c3 121 debug(65, 2) ("hdr cc: ignoring duplicate cache-directive: near '%s' in '%s'\n", item, strBuf(*str));
de336bbe 122 CcFieldsInfo[type].stat.repCount++;
7faf2bdb 123 continue;
124 }
125 /* update mask */
126 EBIT_SET(cc->mask, type);
127 /* post-processing special cases */
128 switch (type) {
129 case CC_MAX_AGE:
d8b249ef 130 if (!p || !httpHeaderParseInt(p, &cc->max_age)) {
20198c7a 131 debug(65, 2) ("cc: invalid max-age specs near '%s'\n", item);
7faf2bdb 132 cc->max_age = -1;
133 EBIT_CLR(cc->mask, type);
134 }
135 break;
7e3ce7b9 136 case CC_S_MAXAGE:
137 if (!p || !httpHeaderParseInt(p, &cc->s_maxage)) {
138 debug(65, 2) ("cc: invalid s-maxage specs near '%s'\n", item);
139 cc->s_maxage = -1;
140 EBIT_CLR(cc->mask, type);
141 }
142 break;
7faf2bdb 143 default:
d8b249ef 144 /* note that we ignore most of '=' specs */
7faf2bdb 145 break;
146 }
147 }
b5107edb 148 return cc->mask != 0;
7faf2bdb 149}
150
151void
152httpHdrCcDestroy(HttpHdrCc * cc)
153{
154 assert(cc);
db1cd23c 155 memFree(cc, MEM_HTTP_HDR_CC);
7faf2bdb 156}
157
158HttpHdrCc *
02922e76 159httpHdrCcDup(const HttpHdrCc * cc)
7faf2bdb 160{
161 HttpHdrCc *dup;
162 assert(cc);
163 dup = httpHdrCcCreate();
164 dup->mask = cc->mask;
165 dup->max_age = cc->max_age;
7e3ce7b9 166 dup->s_maxage = cc->s_maxage;
7faf2bdb 167 return dup;
168}
169
170void
d76fcfa7 171httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p)
7faf2bdb 172{
173 http_hdr_cc_type flag;
174 int pcount = 0;
175 assert(cc && p);
7faf2bdb 176 for (flag = 0; flag < CC_ENUM_END; flag++) {
91274dd0 177 if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) {
178
179 /* print option name */
99edd1c3 180 packerPrintf(p, (pcount ? ", %s" : "%s"), strBuf(CcFieldsInfo[flag].name));
91274dd0 181
182 /* handle options with values */
183 if (flag == CC_MAX_AGE)
184 packerPrintf(p, "=%d", (int) cc->max_age);
185
7e3ce7b9 186 if (flag == CC_S_MAXAGE)
187 packerPrintf(p, "=%d", (int) cc->s_maxage);
188
7faf2bdb 189 pcount++;
190 }
191 }
192}
193
194void
02922e76 195httpHdrCcJoinWith(HttpHdrCc * cc, const HttpHdrCc * new_cc)
7faf2bdb 196{
197 assert(cc && new_cc);
198 if (cc->max_age < 0)
199 cc->max_age = new_cc->max_age;
7e3ce7b9 200 if (cc->s_maxage < 0)
201 cc->s_maxage = new_cc->s_maxage;
7faf2bdb 202 cc->mask |= new_cc->mask;
203}
204
99edd1c3 205/* negative max_age will clean old max_Age setting */
206void
207httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age)
208{
209 assert(cc);
210 cc->max_age = max_age;
211 if (max_age >= 0)
212 EBIT_SET(cc->mask, CC_MAX_AGE);
213 else
214 EBIT_CLR(cc->mask, CC_MAX_AGE);
215}
216
7e3ce7b9 217/* negative s_maxage will clean old s-maxage setting */
218void
219httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage)
220{
221 assert(cc);
222 cc->s_maxage = s_maxage;
223 if (s_maxage >= 0)
224 EBIT_SET(cc->mask, CC_S_MAXAGE);
225 else
226 EBIT_CLR(cc->mask, CC_S_MAXAGE);
227}
228
7faf2bdb 229void
230httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist)
231{
232 http_hdr_cc_type c;
233 assert(cc);
234 for (c = 0; c < CC_ENUM_END; c++)
235 if (EBIT_TEST(cc->mask, c))
236 statHistCount(hist, c);
237}
238
239void
240httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count)
241{
0cdcddb9 242 extern const HttpHeaderStat *dump_stat; /* argh! */
7faf2bdb 243 const int id = (int) val;
244 const int valid_id = id >= 0 && id < CC_ENUM_END;
de336bbe 245 const char *name = valid_id ? strBuf(CcFieldsInfo[id].name) : "INVALID";
7faf2bdb 246 if (count || valid_id)
247 storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n",
fcd2d3ef 248 id, name, count, xdiv(count, dump_stat->ccParsedCount));
7faf2bdb 249}