]> git.ipfire.org Git - thirdparty/squid.git/blame - src/adaptation/Config.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / adaptation / Config.cc
CommitLineData
64bdef96 1/*
f70aedc4 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
64bdef96 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
64bdef96
AR
7 */
8
582c2af2 9#include "squid.h"
71be37e0 10#include "acl/FilledChecklist.h"
582c2af2
FC
11#include "acl/Gadgets.h"
12#include "adaptation/AccessRule.h"
64bdef96 13#include "adaptation/Config.h"
582c2af2 14#include "adaptation/History.h"
64bdef96 15#include "adaptation/Service.h"
62c7f90e 16#include "adaptation/ServiceGroups.h"
582c2af2
FC
17#include "ConfigParser.h"
18#include "globals.h"
19#include "HttpReply.h"
71be37e0 20#include "HttpRequest.h"
582c2af2 21#include "Store.h"
64bdef96 22
c8ea3cc0
FC
23#include <algorithm>
24
8f361c50 25bool Adaptation::Config::Enabled = false;
3ff65596 26char *Adaptation::Config::masterx_shared_name = NULL;
a22e6cd3 27int Adaptation::Config::service_iteration_limit = 16;
22fff3bf
AR
28int Adaptation::Config::send_client_ip = false;
29int Adaptation::Config::send_username = false;
30int Adaptation::Config::use_indirect_client = true;
4668df3d
CT
31static const char *protectedFieldNamesRaw[] = {
32 "Allow",
33 "Date",
d7f4a0b7 34 "Encapsulated",
4668df3d 35 "ISTag",
d7f4a0b7 36 "Max-Connections",
4668df3d
CT
37 "Methods",
38 "Opt-body-type",
d7f4a0b7 39 "Options-TTL",
d7f4a0b7 40 "Preview",
4668df3d
CT
41 "Service",
42 "Service-ID",
d7f4a0b7 43 "Transfer-Complete",
4668df3d
CT
44 "Transfer-Ignore",
45 "Transfer-Preview"
d7f4a0b7 46};
4668df3d
CT
47static const Notes::Keys protectedFieldNames(std::begin(protectedFieldNamesRaw), std::end(protectedFieldNamesRaw));
48Notes Adaptation::Config::metaHeaders("ICAP header", &protectedFieldNames);
c302ddb5 49bool Adaptation::Config::needHistory = false;
8f361c50 50
e1e90d26
AR
51Adaptation::ServiceConfig*
52Adaptation::Config::newServiceConfig() const
53{
54 return new ServiceConfig();
55}
56
7e8c4ee9
CT
57void
58Adaptation::Config::removeService(const String& service)
59{
60 removeRule(service);
61 const Groups& groups = AllGroups();
62 for (unsigned int i = 0; i < groups.size(); ) {
63 const ServiceGroupPointer group = groups[i];
64 const ServiceGroup::Store& services = group->services;
65 typedef ServiceGroup::Store::const_iterator SGSI;
66 for (SGSI it = services.begin(); it != services.end(); ++it) {
67 if (*it == service) {
68 group->removedServices.push_back(service);
6e1410f9
FC
69 ServiceGroup::Store::iterator newend;
70 newend = std::remove(group->services.begin(), group->services.end(), service);
71 group->services.resize(newend-group->services.begin());
c8ea3cc0 72 debugs(93, 5, "adaptation service " << service <<
7e8c4ee9
CT
73 " removed from group " << group->id);
74 break;
75 }
76 }
77 if (services.empty()) {
78 removeRule(group->id);
6e1410f9
FC
79 Groups::iterator newend;
80 newend = std::remove(AllGroups().begin(), AllGroups().end(), group);
81 AllGroups().resize(newend-AllGroups().begin());
7e8c4ee9
CT
82 } else {
83 ++i;
84 }
85 }
86}
87
c302ddb5
CT
88Adaptation::ServiceConfigPointer
89Adaptation::Config::findServiceConfig(const String &service)
90{
91 typedef ServiceConfigs::const_iterator SCI;
92 const ServiceConfigs& configs = serviceConfigs;
93 for (SCI cfg = configs.begin(); cfg != configs.end(); ++cfg) {
94 if ((*cfg)->key == service)
95 return *cfg;
96 }
97 return NULL;
98}
99
7e8c4ee9
CT
100void
101Adaptation::Config::removeRule(const String& id)
102{
103 typedef AccessRules::const_iterator ARI;
104 const AccessRules& rules = AllRules();
105 for (ARI it = rules.begin(); it != rules.end(); ++it) {
106 AccessRule* rule = *it;
107 if (rule->groupId == id) {
c8ea3cc0 108 debugs(93, 5, "removing access rules for:" << id);
6e1410f9
FC
109 AccessRules::iterator newend;
110 newend = std::remove(AllRules().begin(), AllRules().end(), rule);
111 AllRules().resize(newend-AllRules().begin());
7e8c4ee9
CT
112 delete (rule);
113 break;
114 }
115 }
116}
117
118void
119Adaptation::Config::clear()
120{
121 debugs(93, 3, HERE << "rules: " << AllRules().size() << ", groups: " <<
122 AllGroups().size() << ", services: " << serviceConfigs.size());
123 typedef ServiceConfigs::const_iterator SCI;
124 const ServiceConfigs& configs = serviceConfigs;
125 for (SCI cfg = configs.begin(); cfg != configs.end(); ++cfg)
126 removeService((*cfg)->key);
c33a88ca 127 serviceConfigs.clear();
7e8c4ee9
CT
128 debugs(93, 3, HERE << "rules: " << AllRules().size() << ", groups: " <<
129 AllGroups().size() << ", services: " << serviceConfigs.size());
130}
131
64bdef96
AR
132void
133Adaptation::Config::parseService()
134{
e1e90d26 135 ServiceConfigPointer cfg = newServiceConfig();
a22e6cd3
AR
136 if (!cfg->parse()) {
137 fatalf("%s:%d: malformed adaptation service configuration",
e1381638 138 cfg_filename, config_lineno);
a22e6cd3 139 }
64bdef96
AR
140 serviceConfigs.push_back(cfg);
141}
142
143void
144Adaptation::Config::freeService()
145{
76fc7e57
AJ
146 FreeAccess();
147 FreeServiceGroups();
148
149 DetachServices();
150
c33a88ca 151 serviceConfigs.clear();
64bdef96
AR
152}
153
154void
155Adaptation::Config::dumpService(StoreEntry *entry, const char *name) const
156{
157 typedef Services::iterator SCI;
158 for (SCI i = AllServices().begin(); i != AllServices().end(); ++i) {
159 const ServiceConfig &cfg = (*i)->cfg();
88df846b
CT
160 bool isEcap = cfg.protocol.caseCmp("ecap") == 0;
161 bool isIcap = !isEcap;
162 const char *optConnectionEncryption = "";
163 // Print connections_encrypted option if no default value is used
164 if (cfg.secure.encryptTransport && !cfg.connectionEncryption)
165 optConnectionEncryption = " connection-encryption=off";
166 else if (isEcap && !cfg.connectionEncryption)
167 optConnectionEncryption = " connection-encryption=off";
168 else if (isIcap && !cfg.secure.encryptTransport && cfg.connectionEncryption)
169 optConnectionEncryption = " connection-encryption=on";
170
171 storeAppendPrintf(entry, "%s " SQUIDSTRINGPH " %s_%s %d " SQUIDSTRINGPH "%s\n",
af6a12ee
AJ
172 name,
173 SQUIDSTRINGPRINT(cfg.key),
174 cfg.methodStr(), cfg.vectPointStr(), cfg.bypass,
88df846b 175 SQUIDSTRINGPRINT(cfg.uri),
ff89bfa0 176
88df846b 177 optConnectionEncryption);
64bdef96
AR
178 }
179}
180
7e8c4ee9 181bool
64bdef96
AR
182Adaptation::Config::finalize()
183{
7e8c4ee9
CT
184 if (!onoff) {
185 clear();
186 return false;
187 }
188
64bdef96 189 // create service reps from service configs
e1e90d26
AR
190 int created = 0;
191
192 typedef ServiceConfigs::const_iterator VISCI;
193 const ServiceConfigs &configs = serviceConfigs;
62c7f90e 194 for (VISCI i = configs.begin(); i != configs.end(); ++i) {
e1e90d26
AR
195 const ServiceConfigPointer cfg = *i;
196 if (FindService(cfg->key) != NULL) {
fa84c01d 197 debugs(93, DBG_CRITICAL, "ERROR: Duplicate adaptation service name: " <<
e1e90d26 198 cfg->key);
26ac0430
AJ
199 continue; // TODO: make fatal
200 }
e1e90d26
AR
201 ServicePointer s = createService(cfg);
202 if (s != NULL) {
62c7f90e 203 AllServices().push_back(s);
742a021b 204 ++created;
e1e90d26 205 }
64bdef96
AR
206 }
207
e1e90d26
AR
208 debugs(93,3, HERE << "Created " << created << " adaptation services");
209
210 // services remember their configs; we do not have to
c33a88ca 211 serviceConfigs.clear();
7e8c4ee9 212 return true;
64bdef96
AR
213}
214
62c7f90e
AR
215// poor man for_each
216template <class Collection>
217static void
218FinalizeEach(Collection &collection, const char *label)
64bdef96 219{
62c7f90e
AR
220 typedef typename Collection::iterator CI;
221 for (CI i = collection.begin(); i != collection.end(); ++i)
222 (*i)->finalize();
64bdef96 223
192378eb 224 debugs(93,2, HERE << "Initialized " << collection.size() << ' ' << label);
64bdef96
AR
225}
226
227void
8f361c50 228Adaptation::Config::Finalize(bool enabled)
64bdef96 229{
8f361c50 230 Enabled = enabled;
e0236918 231 debugs(93, DBG_IMPORTANT, "Adaptation support is " << (Enabled ? "on" : "off."));
8f361c50 232
62c7f90e
AR
233 FinalizeEach(AllServices(), "message adaptation services");
234 FinalizeEach(AllGroups(), "message adaptation service groups");
235 FinalizeEach(AllRules(), "message adaptation access rules");
236}
64bdef96
AR
237
238void
62c7f90e 239Adaptation::Config::ParseServiceSet()
64bdef96 240{
a22e6cd3
AR
241 Adaptation::Config::ParseServiceGroup(new ServiceSet);
242}
243
244void
245Adaptation::Config::ParseServiceChain()
246{
247 Adaptation::Config::ParseServiceGroup(new ServiceChain);
248}
249
250void
251Adaptation::Config::ParseServiceGroup(ServiceGroupPointer g)
252{
253 assert(g != NULL);
62c7f90e
AR
254 g->parse();
255 AllGroups().push_back(g);
64bdef96
AR
256}
257
258void
a22e6cd3 259Adaptation::Config::FreeServiceGroups()
64bdef96 260{
62c7f90e 261 while (!AllGroups().empty()) {
a22e6cd3 262 // groups are refcounted so we do not explicitly delete them
b6b637eb
AR
263 AllGroups().pop_back();
264 }
64bdef96
AR
265}
266
267void
a22e6cd3 268Adaptation::Config::DumpServiceGroups(StoreEntry *entry, const char *name)
64bdef96 269{
62c7f90e
AR
270 typedef Groups::iterator GI;
271 for (GI i = AllGroups().begin(); i != AllGroups().end(); ++i)
2c1fd837 272 storeAppendPrintf(entry, "%s " SQUIDSTRINGPH "\n", name, SQUIDSTRINGPRINT((*i)->id));
62c7f90e 273}
64bdef96 274
62c7f90e
AR
275void
276Adaptation::Config::ParseAccess(ConfigParser &parser)
277{
2eceb328 278 String groupId = ConfigParser::NextToken();
287bbe9a 279 AccessRule *r;
899fad67 280 if (!(r=FindRuleByGroupId(groupId))) {
af6a12ee
AJ
281 r = new AccessRule(groupId);
282 AllRules().push_back(r);
899fad67 283 }
62c7f90e 284 r->parse(parser);
62c7f90e 285}
64bdef96
AR
286
287void
62c7f90e 288Adaptation::Config::FreeAccess()
64bdef96 289{
62c7f90e
AR
290 while (!AllRules().empty()) {
291 delete AllRules().back();
292 AllRules().pop_back();
b6b637eb 293 }
64bdef96
AR
294}
295
296void
62c7f90e 297Adaptation::Config::DumpAccess(StoreEntry *entry, const char *name)
64bdef96
AR
298{
299 LOCAL_ARRAY(char, nom, 64);
300
62c7f90e
AR
301 typedef AccessRules::iterator CI;
302 for (CI i = AllRules().begin(); i != AllRules().end(); ++i) {
2c1fd837 303 snprintf(nom, 64, "%s " SQUIDSTRINGPH, name, SQUIDSTRINGPRINT((*i)->groupId));
62c7f90e 304 dump_acl_access(entry, nom, (*i)->acl);
b6b637eb 305 }
64bdef96
AR
306}
307
c9568681 308Adaptation::Config::Config() :
f53969cc
SM
309 onoff(0), service_failure_limit(0), oldest_service_failure(0),
310 service_revival_delay(0)
c9568681 311{}
64bdef96 312
26ac0430 313// XXX: this is called for ICAP and eCAP configs, but deals mostly
62c7f90e 314// with global arrays shared by those individual configs
64bdef96
AR
315Adaptation::Config::~Config()
316{
62c7f90e 317 freeService();
64bdef96 318}
f53969cc 319