]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/ServiceConfig.cc
2 * DEBUG: section 93 Adaptation
6 #include "adaptation/ServiceConfig.h"
7 #include "ConfigParser.h"
13 Adaptation::ServiceConfig::ServiceConfig():
14 port(-1), method(methodNone
), point(pointNone
),
15 bypass(false), maxConn(-1), onOverload(srvWait
),
16 routing(false), ipv6(false)
20 Adaptation::ServiceConfig::methodStr() const
22 return Adaptation::methodStr(method
);
26 Adaptation::ServiceConfig::vectPointStr() const
28 return Adaptation::vectPointStr(point
);
32 Adaptation::ServiceConfig::parseMethod(const char *str
) const
34 if (!strncasecmp(str
, "REQMOD", 6))
35 return Adaptation::methodReqmod
;
37 if (!strncasecmp(str
, "RESPMOD", 7))
38 return Adaptation::methodRespmod
;
40 return Adaptation::methodNone
;
44 Adaptation::ServiceConfig::parseVectPoint(const char *service_configConfig
) const
46 const char *t
= service_configConfig
;
47 const char *q
= strchr(t
, '_');
52 if (!strcasecmp(t
, "precache"))
53 return Adaptation::pointPreCache
;
55 if (!strcasecmp(t
, "postcache"))
56 return Adaptation::pointPostCache
;
58 return Adaptation::pointNone
;
62 Adaptation::ServiceConfig::parse()
66 ConfigParser::ParseString(&key
);
67 ConfigParser::ParseString(&method_point
);
68 method
= parseMethod(method_point
.termedBuf());
69 point
= parseVectPoint(method_point
.termedBuf());
71 // reset optional parameters in case we are reconfiguring
72 bypass
= routing
= false;
74 // handle optional service name=value parameters
75 bool grokkedUri
= false;
76 bool onOverloadSet
= false;
77 std::set
<std::string
> options
;
79 while (char *option
= strtok(NULL
, w_space
)) {
80 const char *name
= option
;
81 const char *value
= "";
82 if (strcmp(option
, "0") == 0) { // backward compatibility
85 debugs(3, opt_parse_cfg_only
?0:1, "UPGRADE: Please use 'bypass=off' option to disable service bypass");
86 } else if (strcmp(option
, "1") == 0) { // backward compatibility
89 debugs(3, opt_parse_cfg_only
?0:1, "UPGRADE: Please use 'bypass=on' option to enable service bypass");
91 char *eq
= strstr(option
, "=");
92 const char *sffx
= strstr(option
, "://");
93 if (!eq
|| (sffx
&& sffx
< eq
)) { //no "=" or has the form "icap://host?arg=val"
96 } else { // a normal name=value option
97 *eq
= '\0'; // terminate option name
98 value
= eq
+ 1; // skip '='
102 // Check if option is set twice
103 if (options
.find(name
) != options
.end()) {
104 debugs(3, DBG_CRITICAL
, cfg_filename
<< ':' << config_lineno
<< ": " <<
105 "Duplicate option \"" << name
<< "\" in adaptation service definition");
108 options
.insert(name
);
110 bool grokked
= false;
111 if (strcmp(name
, "bypass") == 0) {
112 grokked
= grokBool(bypass
, name
, value
);
113 } else if (strcmp(name
, "routing") == 0)
114 grokked
= grokBool(routing
, name
, value
);
115 else if (strcmp(name
, "uri") == 0)
116 grokked
= grokkedUri
= grokUri(value
);
117 else if (strcmp(name
, "ipv6") == 0) {
118 grokked
= grokBool(ipv6
, name
, value
);
119 if (grokked
&& ipv6
&& !Ip::EnableIpv6
)
120 debugs(3, DBG_IMPORTANT
, "WARNING: IPv6 is disabled. ICAP service option ignored.");
121 } else if (strcmp(name
, "max-conn") == 0)
122 grokked
= grokLong(maxConn
, name
, value
);
123 else if (strcmp(name
, "on-overload") == 0) {
124 grokked
= grokOnOverload(onOverload
, value
);
125 onOverloadSet
= true;
127 grokked
= grokExtension(name
, value
);
133 // set default on-overload value if needed
135 onOverload
= bypass
? srvBypass
: srvWait
;
137 // is the service URI set?
139 debugs(3, DBG_CRITICAL
, cfg_filename
<< ':' << config_lineno
<< ": " <<
140 "No \"uri\" option in adaptation service definition");
144 debugs(3,5, cfg_filename
<< ':' << config_lineno
<< ": " <<
145 "adaptation_service " << key
<< ' ' <<
146 methodStr() << "_" << vectPointStr() << ' ' <<
147 bypass
<< routing
<< ' ' <<
154 Adaptation::ServiceConfig::grokUri(const char *value
)
156 // TODO: find core code that parses URLs and extracts various parts
157 // AYJ: most of this is duplicate of urlParse() in src/url.cc
159 if (!value
|| !*value
) {
160 debugs(3, DBG_CRITICAL
, HERE
<< cfg_filename
<< ':' << config_lineno
<< ": " <<
161 "empty adaptation service URI");
167 // extract scheme and use it as the service_configConfig protocol
168 const char *schemeSuffix
= "://";
169 const String::size_type schemeEnd
= uri
.find(schemeSuffix
);
170 if (schemeEnd
!= String::npos
)
171 protocol
=uri
.substr(0,schemeEnd
);
173 debugs(3, 5, HERE
<< cfg_filename
<< ':' << config_lineno
<< ": " <<
174 "service protocol is " << protocol
);
176 if (protocol
.size() == 0)
180 const char *s
= uri
.termedBuf() + protocol
.size() + strlen(schemeSuffix
);
184 bool have_port
= false;
189 if ((t
= strchr(s
, ']')) == NULL
)
194 if ((e
= strchr(t
, ':')) != NULL
) {
196 } else if ((e
= strchr(t
, '/')) != NULL
) {
202 if ((e
= strchr(s
, ':')) != NULL
) {
204 } else if ((e
= strchr(s
, '/')) != NULL
) {
212 host
.limitInit(s
, len
);
219 if ((e
= strchr(s
, '/')) != NULL
) {
221 const unsigned long p
= strtoul(s
, &t
, 0);
223 if (p
> 65535) // port value is too high
226 port
= static_cast<int>(p
);
228 if (t
!= e
) // extras after the port
238 // if no port, the caller may use service_configConfigs or supply the default if neeeded
245 debugs(3, DBG_CRITICAL
, HERE
<< cfg_filename
<< ':' << config_lineno
<< ": " <<
246 "long resource name (>1024), probably wrong");
249 resource
.limitInit(s
, len
+ 1);
255 Adaptation::ServiceConfig::grokBool(bool &var
, const char *name
, const char *value
)
257 if (!strcmp(value
, "0") || !strcmp(value
, "off"))
259 else if (!strcmp(value
, "1") || !strcmp(value
, "on"))
262 debugs(3, DBG_CRITICAL
, HERE
<< cfg_filename
<< ':' << config_lineno
<< ": " <<
263 "wrong value for boolean " << name
<< "; " <<
264 "'0', '1', 'on', or 'off' expected but got: " << value
);
272 Adaptation::ServiceConfig::grokLong(long &var
, const char *name
, const char *value
)
275 const long p
= strtol(value
, &bad
, 0);
276 if (p
< 0 || bad
== value
) {
277 debugs(3, DBG_CRITICAL
, "ERROR: " << cfg_filename
<< ':' <<
278 config_lineno
<< ": " << "wrong value for " << name
<< "; " <<
279 "a non-negative integer expected but got: " << value
);
287 Adaptation::ServiceConfig::grokOnOverload(SrvBehaviour
&var
, const char *value
)
289 if (strcmp(value
, "block") == 0)
291 else if (strcmp(value
, "bypass") == 0)
293 else if (strcmp(value
, "wait") == 0)
295 else if (strcmp(value
, "force") == 0)
298 debugs(3, DBG_CRITICAL
, "ERROR: " << cfg_filename
<< ':' <<
299 config_lineno
<< ": " << "wrong value for on-overload; " <<
300 "'block', 'bypass', 'wait' or 'force' expected but got: " << value
);
307 Adaptation::ServiceConfig::grokExtension(const char *name
, const char *value
)
309 // we do not accept extensions by default
310 debugs(3, DBG_CRITICAL
, cfg_filename
<< ':' << config_lineno
<< ": " <<
311 "ERROR: unknown adaptation service option: " <<
312 name
<< '=' << value
);