]> git.ipfire.org Git - thirdparty/squid.git/blob - src/Notes.cc
Merge from trunk
[thirdparty/squid.git] / src / Notes.cc
1 /*
2 * SQUID Web Proxy Cache http://www.squid-cache.org/
3 * ----------------------------------------------------------
4 *
5 * Squid is the result of efforts by numerous individuals from
6 * the Internet community; see the CONTRIBUTORS file for full
7 * details. Many organizations have provided support for Squid's
8 * development; see the SPONSORS file for full details. Squid is
9 * Copyrighted (C) 2001 by the Regents of the University of
10 * California; see the COPYRIGHT file for full details. Squid
11 * incorporates software developed and/or copyrighted by other
12 * sources; see the CREDITS file for full details.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
27 *
28 */
29
30 #include "squid.h"
31 #include "AccessLogEntry.h"
32 #include "acl/FilledChecklist.h"
33 #include "acl/Gadgets.h"
34 #include "ConfigParser.h"
35 #include "globals.h"
36 #include "HttpReply.h"
37 #include "HttpRequest.h"
38 #include "SquidConfig.h"
39 #include "Store.h"
40 #include "StrList.h"
41
42 #include <algorithm>
43 #include <string>
44
45 Note::Value::~Value()
46 {
47 aclDestroyAclList(&aclList);
48 }
49
50 Note::Value::Pointer
51 Note::addValue(const String &value)
52 {
53 Value::Pointer v = new Value(value);
54 values.push_back(v);
55 return v;
56 }
57
58 const char *
59 Note::match(HttpRequest *request, HttpReply *reply, const AccessLogEntry::Pointer &al)
60 {
61
62 typedef Values::iterator VLI;
63 ACLFilledChecklist ch(NULL, request, NULL);
64 ch.reply = reply;
65 if (reply)
66 HTTPMSGLOCK(ch.reply);
67
68 for (VLI i = values.begin(); i != values.end(); ++i ) {
69 const int ret= ch.fastCheck((*i)->aclList);
70 debugs(93, 5, HERE << "Check for header name: " << key << ": " << (*i)->value
71 <<", HttpRequest: " << request << " HttpReply: " << reply << " matched: " << ret);
72 if (ret == ACCESS_ALLOWED) {
73 if (al != NULL && (*i)->valueFormat != NULL) {
74 static MemBuf mb;
75 mb.reset();
76 (*i)->valueFormat->assemble(mb, al, 0);
77 return mb.content();
78 } else
79 return (*i)->value.termedBuf();
80 }
81 }
82 return NULL;
83 }
84
85 Note::Pointer
86 Notes::add(const String &noteKey)
87 {
88 typedef Notes::NotesList::iterator AMLI;
89 for (AMLI i = notes.begin(); i != notes.end(); ++i) {
90 if ((*i)->key == noteKey)
91 return (*i);
92 }
93
94 Note::Pointer note = new Note(noteKey);
95 notes.push_back(note);
96 return note;
97 }
98
99 Note::Pointer
100 Notes::parse(ConfigParser &parser)
101 {
102 String key = ConfigParser::NextToken();
103 ConfigParser::EnableMacros();
104 String value = ConfigParser::NextQuotedToken();
105 ConfigParser::DisableMacros();
106 bool valueWasQuoted = ConfigParser::LastTokenWasQuoted();
107 Note::Pointer note = add(key);
108 Note::Value::Pointer noteValue = note->addValue(value);
109
110 String label(key);
111 label.append('=');
112 label.append(value);
113 aclParseAclList(parser, &noteValue->aclList, label.termedBuf());
114 if (formattedValues && valueWasQuoted) {
115 noteValue->valueFormat = new Format::Format(descr ? descr : "Notes");
116 noteValue->valueFormat->parse(value.termedBuf());
117 }
118 if (blacklisted) {
119 for (int i = 0; blacklisted[i] != NULL; ++i) {
120 if (note->key.caseCmp(blacklisted[i]) == 0) {
121 fatalf("%s:%d: meta key \"%s\" is a reserved %s name",
122 cfg_filename, config_lineno, note->key.termedBuf(),
123 descr ? descr : "");
124 }
125 }
126 }
127
128 return note;
129 }
130
131 void
132 Notes::dump(StoreEntry *entry, const char *key)
133 {
134 typedef Notes::NotesList::iterator AMLI;
135 for (AMLI m = notes.begin(); m != notes.end(); ++m) {
136 typedef Note::Values::iterator VLI;
137 for (VLI v =(*m)->values.begin(); v != (*m)->values.end(); ++v ) {
138 storeAppendPrintf(entry, "%s " SQUIDSTRINGPH " %s",
139 key, SQUIDSTRINGPRINT((*m)->key), ConfigParser::QuoteString((*v)->value));
140 dump_acl_list(entry, (*v)->aclList);
141 storeAppendPrintf(entry, "\n");
142 }
143 }
144 }
145
146 void
147 Notes::clean()
148 {
149 notes.clear();
150 }
151
152 NotePairs::~NotePairs()
153 {
154 while (!entries.empty()) {
155 delete entries.back();
156 entries.pop_back();
157 }
158 }
159
160 const char *
161 NotePairs::find(const char *noteKey, const char *sep) const
162 {
163 static String value;
164 value.clean();
165 for (std::vector<NotePairs::Entry *>::const_iterator i = entries.begin(); i != entries.end(); ++i) {
166 if ((*i)->name.cmp(noteKey) == 0) {
167 if (value.size())
168 value.append(sep);
169 value.append((*i)->value);
170 }
171 }
172 return value.size() ? value.termedBuf() : NULL;
173 }
174
175 const char *
176 NotePairs::toString(const char *sep) const
177 {
178 static String value;
179 value.clean();
180 for (std::vector<NotePairs::Entry *>::const_iterator i = entries.begin(); i != entries.end(); ++i) {
181 value.append((*i)->name);
182 value.append(": ");
183 value.append((*i)->value);
184 value.append(sep);
185 }
186 return value.size() ? value.termedBuf() : NULL;
187 }
188
189 const char *
190 NotePairs::findFirst(const char *noteKey) const
191 {
192 for (std::vector<NotePairs::Entry *>::const_iterator i = entries.begin(); i != entries.end(); ++i) {
193 if ((*i)->name.cmp(noteKey) == 0)
194 return (*i)->value.termedBuf();
195 }
196 return NULL;
197 }
198
199 void
200 NotePairs::add(const char *key, const char *note)
201 {
202 entries.push_back(new NotePairs::Entry(key, note));
203 }
204
205 void
206 NotePairs::addStrList(const char *key, const char *values)
207 {
208 String strValues(values);
209 const char *item;
210 const char *pos = NULL;
211 int ilen = 0;
212 while (strListGetItem(&strValues, ',', &item, &ilen, &pos)) {
213 String v;
214 v.append(item, ilen);
215 entries.push_back(new NotePairs::Entry(key, v.termedBuf()));
216 }
217 }
218
219 bool
220 NotePairs::hasPair(const char *key, const char *value) const
221 {
222 for (std::vector<NotePairs::Entry *>::const_iterator i = entries.begin(); i != entries.end(); ++i) {
223 if ((*i)->name.cmp(key) == 0 && (*i)->value.cmp(value) == 0)
224 return true;
225 }
226 return false;
227 }
228
229 void
230 NotePairs::append(const NotePairs *src)
231 {
232 for (std::vector<NotePairs::Entry *>::const_iterator i = src->entries.begin(); i != src->entries.end(); ++i) {
233 entries.push_back(new NotePairs::Entry((*i)->name.termedBuf(), (*i)->value.termedBuf()));
234 }
235 }
236
237 void
238 NotePairs::appendNewOnly(const NotePairs *src)
239 {
240 for (std::vector<NotePairs::Entry *>::const_iterator i = src->entries.begin(); i != src->entries.end(); ++i) {
241 if (!hasPair((*i)->name.termedBuf(), (*i)->value.termedBuf()))
242 entries.push_back(new NotePairs::Entry((*i)->name.termedBuf(), (*i)->value.termedBuf()));
243 }
244 }
245
246 NotePairs &
247 SyncNotes(AccessLogEntry &ale, HttpRequest &request)
248 {
249 // XXX: auth code only has access to HttpRequest being authenticated
250 // so we must handle the case where HttpRequest is set without ALE being set.
251
252 if (!ale.notes) {
253 if (!request.notes)
254 request.notes = new NotePairs;
255 ale.notes = request.notes;
256 } else {
257 assert(ale.notes == request.notes);
258 }
259 return *ale.notes;
260 }