3 * SQUID Web Proxy Cache http://www.squid-cache.org/
4 * ----------------------------------------------------------
6 * Squid is the result of efforts by numerous individuals from
7 * the Internet community; see the CONTRIBUTORS file for full
8 * details. Many organizations have provided support for Squid's
9 * development; see the SPONSORS file for full details. Squid is
10 * Copyrighted (C) 2001 by the Regents of the University of
11 * California; see the COPYRIGHT file for full details. Squid
12 * incorporates software developed and/or copyrighted by other
13 * sources; see the CREDITS file for full details.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
32 #include "acl/FilledChecklist.h"
33 #include "acl/Gadgets.h"
34 #include "adaptation/AccessRule.h"
35 #include "adaptation/Config.h"
36 #include "adaptation/History.h"
37 #include "adaptation/Service.h"
38 #include "adaptation/ServiceGroups.h"
39 #include "base/Vector.h"
40 #include "ConfigParser.h"
42 #include "HttpReply.h"
43 #include "HttpRequest.h"
46 bool Adaptation::Config::Enabled
= false;
47 char *Adaptation::Config::masterx_shared_name
= NULL
;
48 int Adaptation::Config::service_iteration_limit
= 16;
49 int Adaptation::Config::send_client_ip
= false;
50 int Adaptation::Config::send_username
= false;
51 int Adaptation::Config::use_indirect_client
= true;
52 const char *metasBlacklist
[] = {
69 Notes
Adaptation::Config::metaHeaders("ICAP header", metasBlacklist
);
71 Adaptation::ServiceConfig
*
72 Adaptation::Config::newServiceConfig() const
74 return new ServiceConfig();
78 Adaptation::Config::removeService(const String
& service
)
81 const Groups
& groups
= AllGroups();
82 for (unsigned int i
= 0; i
< groups
.size(); ) {
83 const ServiceGroupPointer group
= groups
[i
];
84 const ServiceGroup::Store
& services
= group
->services
;
85 typedef ServiceGroup::Store::const_iterator SGSI
;
86 for (SGSI it
= services
.begin(); it
!= services
.end(); ++it
) {
88 group
->removedServices
.push_back(service
);
89 group
->services
.prune(service
);
90 debugs(93, 5, HERE
<< "adaptation service " << service
<<
91 " removed from group " << group
->id
);
95 if (services
.empty()) {
96 removeRule(group
->id
);
97 AllGroups().prune(group
);
105 Adaptation::Config::removeRule(const String
& id
)
107 typedef AccessRules::const_iterator ARI
;
108 const AccessRules
& rules
= AllRules();
109 for (ARI it
= rules
.begin(); it
!= rules
.end(); ++it
) {
110 AccessRule
* rule
= *it
;
111 if (rule
->groupId
== id
) {
112 debugs(93, 5, HERE
<< "removing access rules for:" << id
);
113 AllRules().prune(rule
);
121 Adaptation::Config::clear()
123 debugs(93, 3, HERE
<< "rules: " << AllRules().size() << ", groups: " <<
124 AllGroups().size() << ", services: " << serviceConfigs
.size());
125 typedef ServiceConfigs::const_iterator SCI
;
126 const ServiceConfigs
& configs
= serviceConfigs
;
127 for (SCI cfg
= configs
.begin(); cfg
!= configs
.end(); ++cfg
)
128 removeService((*cfg
)->key
);
129 serviceConfigs
.clean();
130 debugs(93, 3, HERE
<< "rules: " << AllRules().size() << ", groups: " <<
131 AllGroups().size() << ", services: " << serviceConfigs
.size());
135 Adaptation::Config::parseService()
137 ServiceConfigPointer cfg
= newServiceConfig();
139 fatalf("%s:%d: malformed adaptation service configuration",
140 cfg_filename
, config_lineno
);
142 serviceConfigs
.push_back(cfg
);
146 Adaptation::Config::freeService()
153 serviceConfigs
.clean();
157 Adaptation::Config::dumpService(StoreEntry
*entry
, const char *name
) const
159 typedef Services::iterator SCI
;
160 for (SCI i
= AllServices().begin(); i
!= AllServices().end(); ++i
) {
161 const ServiceConfig
&cfg
= (*i
)->cfg();
162 storeAppendPrintf(entry
, "%s " SQUIDSTRINGPH
"_%s %s %d " SQUIDSTRINGPH
"\n",
164 SQUIDSTRINGPRINT(cfg
.key
),
165 cfg
.methodStr(), cfg
.vectPointStr(), cfg
.bypass
,
166 SQUIDSTRINGPRINT(cfg
.uri
));
171 Adaptation::Config::finalize()
178 // create service reps from service configs
181 typedef ServiceConfigs::const_iterator VISCI
;
182 const ServiceConfigs
&configs
= serviceConfigs
;
183 for (VISCI i
= configs
.begin(); i
!= configs
.end(); ++i
) {
184 const ServiceConfigPointer cfg
= *i
;
185 if (FindService(cfg
->key
) != NULL
) {
186 debugs(93, DBG_CRITICAL
, "ERROR: Duplicate adaptation service name: " <<
188 continue; // TODO: make fatal
190 ServicePointer s
= createService(cfg
);
192 AllServices().push_back(s
);
197 debugs(93,3, HERE
<< "Created " << created
<< " adaptation services");
199 // services remember their configs; we do not have to
200 serviceConfigs
.clean();
205 template <class Collection
>
207 FinalizeEach(Collection
&collection
, const char *label
)
209 typedef typename
Collection::iterator CI
;
210 for (CI i
= collection
.begin(); i
!= collection
.end(); ++i
)
213 debugs(93,2, HERE
<< "Initialized " << collection
.size() << ' ' << label
);
217 Adaptation::Config::Finalize(bool enabled
)
220 debugs(93, DBG_IMPORTANT
, "Adaptation support is " << (Enabled
? "on" : "off."));
222 FinalizeEach(AllServices(), "message adaptation services");
223 FinalizeEach(AllGroups(), "message adaptation service groups");
224 FinalizeEach(AllRules(), "message adaptation access rules");
228 Adaptation::Config::ParseServiceSet()
230 Adaptation::Config::ParseServiceGroup(new ServiceSet
);
234 Adaptation::Config::ParseServiceChain()
236 Adaptation::Config::ParseServiceGroup(new ServiceChain
);
240 Adaptation::Config::ParseServiceGroup(ServiceGroupPointer g
)
244 AllGroups().push_back(g
);
248 Adaptation::Config::FreeServiceGroups()
250 while (!AllGroups().empty()) {
251 // groups are refcounted so we do not explicitly delete them
252 AllGroups().pop_back();
257 Adaptation::Config::DumpServiceGroups(StoreEntry
*entry
, const char *name
)
259 typedef Groups::iterator GI
;
260 for (GI i
= AllGroups().begin(); i
!= AllGroups().end(); ++i
)
261 storeAppendPrintf(entry
, "%s " SQUIDSTRINGPH
"\n", name
, SQUIDSTRINGPRINT((*i
)->id
));
265 Adaptation::Config::ParseAccess(ConfigParser
&parser
)
268 ConfigParser::ParseString(&groupId
);
270 if (!(r
=FindRuleByGroupId(groupId
))) {
271 r
= new AccessRule(groupId
);
272 AllRules().push_back(r
);
278 Adaptation::Config::FreeAccess()
280 while (!AllRules().empty()) {
281 delete AllRules().back();
282 AllRules().pop_back();
287 Adaptation::Config::DumpAccess(StoreEntry
*entry
, const char *name
)
289 LOCAL_ARRAY(char, nom
, 64);
291 typedef AccessRules::iterator CI
;
292 for (CI i
= AllRules().begin(); i
!= AllRules().end(); ++i
) {
293 snprintf(nom
, 64, "%s " SQUIDSTRINGPH
, name
, SQUIDSTRINGPRINT((*i
)->groupId
));
294 dump_acl_access(entry
, nom
, (*i
)->acl
);
298 Adaptation::Config::Config() :
299 onoff(0), service_failure_limit(0), oldest_service_failure(0),
300 service_revival_delay(0)
303 // XXX: this is called for ICAP and eCAP configs, but deals mostly
304 // with global arrays shared by those individual configs
305 Adaptation::Config::~Config()