]>
Commit | Line | Data |
---|---|---|
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 */ |
35 | static 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 | 48 | HttpHeaderFieldInfo *CcFieldsInfo = NULL; |
7faf2bdb | 49 | |
50 | /* counters */ | |
b5107edb | 51 | static int CcParsedCount = 0; |
52 | ||
53 | /* local prototypes */ | |
54 | static int httpHdrCcParseInit(HttpHdrCc * cc, const char *str); | |
7faf2bdb | 55 | |
56 | ||
57 | /* module initialization */ | |
58 | ||
59 | void | |
60 | httpHdrCcInitModule() | |
61 | { | |
de336bbe | 62 | CcFieldsInfo = httpHeaderBuildFieldsInfo(CcAttrs, CC_ENUM_END); |
63 | } | |
64 | ||
65 | void | |
66 | httpHdrCcCleanModule() | |
67 | { | |
68 | httpHeaderDestroyFieldsInfo(CcFieldsInfo, CC_ENUM_END); | |
69 | CcFieldsInfo = NULL; | |
7faf2bdb | 70 | } |
71 | ||
72 | /* implementation */ | |
73 | ||
74 | HttpHdrCc * | |
75 | httpHdrCcCreate() | |
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 */ | |
83 | HttpHdrCc * | |
84 | httpHdrCcParseCreate(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 | 95 | static int |
7faf2bdb | 96 | httpHdrCcParseInit(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 | ||
143 | void | |
144 | httpHdrCcDestroy(HttpHdrCc * cc) | |
145 | { | |
146 | assert(cc); | |
147 | memFree(MEM_HTTP_HDR_CC, cc); | |
148 | } | |
149 | ||
150 | HttpHdrCc * | |
02922e76 | 151 | httpHdrCcDup(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 | ||
161 | void | |
d76fcfa7 | 162 | httpHdrCcPackInto(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 | ||
179 | void | |
02922e76 | 180 | httpHdrCcJoinWith(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 | ||
188 | void | |
189 | httpHdrCcUpdateStats(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 | ||
198 | void | |
199 | httpHdrCcStatDumper(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 | } |