]> git.ipfire.org Git - thirdparty/squid.git/blame - src/HttpHdrCc.cc
- Separated raw HTTP headers from their "compiled" values. Squid is now
[thirdparty/squid.git] / src / HttpHdrCc.cc
CommitLineData
7faf2bdb 1
2/*
d8b249ef 3 * $Id: HttpHdrCc.cc,v 1.8 1998/03/20 18:06:37 rousskov 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/
9 * --------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by
14 * the National Science Foundation.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 */
31
32#include "squid.h"
33
de336bbe 34/* this table is used for parsing cache control header */
35static const HttpHeaderFieldAttrs CcAttrs[CC_ENUM_END] =
7faf2bdb 36{
37 {"public", CC_PUBLIC},
38 {"private", CC_PRIVATE},
39 {"no-cache", CC_NO_CACHE},
40 {"no-store", CC_NO_STORE},
41 {"no-transform", CC_NO_TRANSFORM},
42 {"must-revalidate", CC_MUST_REVALIDATE},
43 {"proxy-revalidate", CC_PROXY_REVALIDATE},
d8b249ef 44 {"only-if-cached", CC_ONLY_IF_CACHED},
45 {"max-age", CC_MAX_AGE},
46 {"Other,", CC_OTHER} /* ',' will protect from matches */
7faf2bdb 47};
de336bbe 48HttpHeaderFieldInfo *CcFieldsInfo = NULL;
7faf2bdb 49
50/* counters */
b5107edb 51static int CcParsedCount = 0;
52
53/* local prototypes */
54static int httpHdrCcParseInit(HttpHdrCc * cc, const char *str);
7faf2bdb 55
56
57/* module initialization */
58
59void
60httpHdrCcInitModule()
61{
de336bbe 62 CcFieldsInfo = httpHeaderBuildFieldsInfo(CcAttrs, CC_ENUM_END);
63}
64
65void
66httpHdrCcCleanModule()
67{
68 httpHeaderDestroyFieldsInfo(CcFieldsInfo, CC_ENUM_END);
69 CcFieldsInfo = NULL;
7faf2bdb 70}
71
72/* implementation */
73
74HttpHdrCc *
75httpHdrCcCreate()
76{
77 HttpHdrCc *cc = memAllocate(MEM_HTTP_HDR_CC);
78 cc->max_age = -1;
79 return cc;
80}
81
82/* creates an cc object from a 0-terminating string */
83HttpHdrCc *
84httpHdrCcParseCreate(const char *str)
85{
86 HttpHdrCc *cc = httpHdrCcCreate();
b5107edb 87 if (!httpHdrCcParseInit(cc, str)) {
88 httpHdrCcDestroy(cc);
89 cc = NULL;
90 }
7faf2bdb 91 return cc;
92}
93
94/* parses a 0-terminating string and inits cc */
b5107edb 95static int
7faf2bdb 96httpHdrCcParseInit(HttpHdrCc * cc, const char *str)
97{
98 const char *item;
99 const char *p; /* '=' parameter */
100 const char *pos = NULL;
101 int type;
102 int ilen;
103 assert(cc && str);
104
b5107edb 105 CcParsedCount++;
7faf2bdb 106 /* iterate through comma separated list */
107 while (strListGetItem(str, ',', &item, &ilen, &pos)) {
108 /* strip '=' statements @?@ */
109 if ((p = strchr(item, '=')) && (p - item < ilen))
110 ilen = p++ - item;
111 /* find type */
112 type = httpHeaderIdByName(item, ilen,
d8b249ef 113 CcFieldsInfo, CC_ENUM_END);
7faf2bdb 114 if (type < 0) {
20198c7a 115 debug(65, 2) ("hdr cc: unknown cache-directive: near '%s' in '%s'\n", item, str);
d8b249ef 116 type = CC_OTHER;
7faf2bdb 117 }
118 if (EBIT_TEST(cc->mask, type)) {
d8b249ef 119 if (type != CC_OTHER)
120 debug(65, 2) ("hdr cc: ignoring duplicate cache-directive: near '%s' in '%s'\n", item, str);
de336bbe 121 CcFieldsInfo[type].stat.repCount++;
7faf2bdb 122 continue;
123 }
124 /* update mask */
125 EBIT_SET(cc->mask, type);
126 /* post-processing special cases */
127 switch (type) {
128 case CC_MAX_AGE:
d8b249ef 129 if (!p || !httpHeaderParseInt(p, &cc->max_age)) {
20198c7a 130 debug(65, 2) ("cc: invalid max-age specs near '%s'\n", item);
7faf2bdb 131 cc->max_age = -1;
132 EBIT_CLR(cc->mask, type);
133 }
134 break;
135 default:
d8b249ef 136 /* note that we ignore most of '=' specs */
7faf2bdb 137 break;
138 }
139 }
b5107edb 140 return cc->mask != 0;
7faf2bdb 141}
142
143void
144httpHdrCcDestroy(HttpHdrCc * cc)
145{
146 assert(cc);
147 memFree(MEM_HTTP_HDR_CC, cc);
148}
149
150HttpHdrCc *
02922e76 151httpHdrCcDup(const HttpHdrCc * cc)
7faf2bdb 152{
153 HttpHdrCc *dup;
154 assert(cc);
155 dup = httpHdrCcCreate();
156 dup->mask = cc->mask;
157 dup->max_age = cc->max_age;
158 return dup;
159}
160
161void
d76fcfa7 162httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p)
7faf2bdb 163{
164 http_hdr_cc_type flag;
165 int pcount = 0;
166 assert(cc && p);
167 if (cc->max_age >= 0) {
f92c7f89 168 packerPrintf(p, "max-age=%d", (int) cc->max_age);
7faf2bdb 169 pcount++;
170 }
171 for (flag = 0; flag < CC_ENUM_END; flag++) {
d8b249ef 172 if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) {
de336bbe 173 packerPrintf(p, pcount ? ", %s" : "%s", CcFieldsInfo[flag].name);
7faf2bdb 174 pcount++;
175 }
176 }
177}
178
179void
02922e76 180httpHdrCcJoinWith(HttpHdrCc * cc, const HttpHdrCc * new_cc)
7faf2bdb 181{
182 assert(cc && new_cc);
183 if (cc->max_age < 0)
184 cc->max_age = new_cc->max_age;
185 cc->mask |= new_cc->mask;
186}
187
188void
189httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist)
190{
191 http_hdr_cc_type c;
192 assert(cc);
193 for (c = 0; c < CC_ENUM_END; c++)
194 if (EBIT_TEST(cc->mask, c))
195 statHistCount(hist, c);
196}
197
198void
199httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count)
200{
201 const int id = (int) val;
202 const int valid_id = id >= 0 && id < CC_ENUM_END;
de336bbe 203 const char *name = valid_id ? strBuf(CcFieldsInfo[id].name) : "INVALID";
7faf2bdb 204 if (count || valid_id)
205 storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n",
b5107edb 206 id, name, count, xdiv(count, CcParsedCount));
7faf2bdb 207}