]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 3349: Bad support for adaptation service URIs with '='
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 6 Oct 2011 18:12:51 +0000 (21:12 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 6 Oct 2011 18:12:51 +0000 (21:12 +0300)
Currently using URIs  which  include "=" is not supported by
ecap_service/icap_service configuration parameters. Also the squid.conf
documentation about ecap_service is outdated.

This patch
- Fixes the [e|i]cap_service line parser to allow URIs with "="
- Changes the [e|i]cap_service configuration parameter to use the following syntax:
   ecap_service id vectoring_point uri [name=value ...]
- Check for duplicated options
- Fixes the related documentation
- Also the older [e|i]cap_service syntax forms are supported:
   ecap_service id vectoring_point [1|0] uri
   ecap_service id vectoring_point [name=value ...] uri
- The "uri" options is not documented but supported.

This is a Measurement Factory project.

src/adaptation/ServiceConfig.cc
src/cf.data.pre

index 6d0b8d49abc48a15bf9f14ffd72820a41a160ce8..1d4a970e9fd32cec12b028901635a420ae46792b 100644 (file)
@@ -6,6 +6,7 @@
 #include "ConfigParser.h"
 #include "adaptation/ServiceConfig.h"
 #include "ip/tools.h"
+#include <set>
 
 Adaptation::ServiceConfig::ServiceConfig():
         port(-1), method(methodNone), point(pointNone),
@@ -69,29 +70,41 @@ Adaptation::ServiceConfig::parse()
     bypass = routing = false;
 
     // handle optional service name=value parameters
-    const char *lastOption = NULL;
     bool grokkedUri = false;
     bool onOverloadSet = false;
+    std::set<std::string> options;
+    
     while (char *option = strtok(NULL, w_space)) {
+        const char *name = option;
+        const char *value = "";
         if (strcmp(option, "0") == 0) { // backward compatibility
-            bypass = false;
-            continue;
-        }
-        if (strcmp(option, "1") == 0) { // backward compatibility
-            bypass = true;
-            continue;
+            name = "bypass";
+            value = "off";
+            debugs(3, opt_parse_cfg_only?0:1, "UPGRADE: Please use 'bypass=off' option to disable service bypass");
+        }  else if (strcmp(option, "1") == 0) { // backward compatibility
+            name = "bypass";
+            value = "on";
+            debugs(3, opt_parse_cfg_only?0:1, "UPGRADE: Please use 'bypass=on' option to enable service bypass");
+        } else {
+            char *eq = strstr(option, "=");
+            const char *sffx = strstr(option, "://");
+            if (!eq || (sffx && sffx < eq)) { //no "=" or has the form "icap://host?arg=val"
+                name = "uri";
+                value = option;
+            }  else { // a normal name=value option
+                *eq = '\0'; // terminate option name
+                value = eq + 1; // skip '='
+            }
         }
 
-        const char *name = option;
-        char *value = strstr(option, "=");
-        if (!value) {
-            lastOption = option;
-            break;
+        // Check if option is set twice
+        if (options.find(name) != options.end()) {
+            debugs(3, DBG_CRITICAL, cfg_filename << ':' << config_lineno << ": " << 
+                   "Duplicate option \"" << name << "\" in adaptation service definition");
+            return false;
         }
-        *value = '\0'; // terminate option name
-        ++value; // skip '='
+        options.insert(name);
 
-        // TODO: warn if option is set twice?
         bool grokked = false;
         if (strcmp(name, "bypass") == 0) {
             grokked = grokBool(bypass, name, value);
@@ -119,14 +132,10 @@ Adaptation::ServiceConfig::parse()
     if (!onOverloadSet)
         onOverload = bypass ? srvBypass : srvWait;
 
-    // what is left must be the service URI
-    if (!grokkedUri && !grokUri(lastOption))
-        return false;
-
-    // there should be nothing else left
-    if (const char *tail = strtok(NULL, w_space)) {
-        debugs(3, 0, cfg_filename << ':' << config_lineno << ": " <<
-               "garbage after adaptation service URI: " << tail);
+    // is the service URI set?
+    if (!grokkedUri) {
+        debugs(3, DBG_CRITICAL, cfg_filename << ':' << config_lineno << ": " << 
+               "No \"uri\" option in adaptation service definition");
         return false;
     }
 
index 8ea4226de156c9bf8431af9b2fd2095bc4887058..11d333e4ffd9482e1da63902d15385b8855173f3 100644 (file)
@@ -6608,17 +6608,19 @@ DEFAULT: none
 DOC_START
        Defines a single ICAP service using the following format:
 
-       icap_service service_name vectoring_point [options] service_url
+       icap_service id vectoring_point uri [option ...]
 
-       service_name: ID
-               an opaque identifier which must be unique in squid.conf
+       id: ID
+               an opaque identifier or name which is used to direct traffic to
+               this specific service. Must be unique among all adaptation
+               services in squid.conf.
 
        vectoring_point: reqmod_precache|reqmod_postcache|respmod_precache|respmod_postcache
                This specifies at which point of transaction processing the
                ICAP service should be activated. *_postcache vectoring points
                are not yet supported.
 
-       service_url: icap://servername:port/servicepath
+       uri: icap://servername:port/servicepath
                ICAP server and service location.
 
        ICAP does not allow a single service to handle both REQMOD and RESPMOD
@@ -6687,8 +6689,8 @@ DOC_START
        deprecated but supported for backward compatibility.
 
 Example:
-icap_service svcBlocker reqmod_precache bypass=0 icap://icap1.mydomain.net:1344/reqmod
-icap_service svcLogger reqmod_precache routing=on icap://icap2.mydomain.net:1344/respmod
+icap_service svcBlocker reqmod_precache icap://icap1.mydomain.net:1344/reqmod bypass=0
+icap_service svcLogger reqmod_precache icap://icap2.mydomain.net:1344/respmod routing=on
 DOC_END
 
 NAME: icap_class
@@ -6740,25 +6742,56 @@ DEFAULT: none
 DOC_START
        Defines a single eCAP service
 
-       ecap_service servicename vectoring_point bypass service_url
+       ecap_service id vectoring_point uri [option ...]
 
-       vectoring_point = reqmod_precache|reqmod_postcache|respmod_precache|respmod_postcache
+        id: ID
+               an opaque identifier or name which is used to direct traffic to
+               this specific service. Must be unique among all adaptation
+               services in squid.conf.
+
+       vectoring_point: reqmod_precache|reqmod_postcache|respmod_precache|respmod_postcache
                This specifies at which point of transaction processing the
                eCAP service should be activated. *_postcache vectoring points
                are not yet supported.
-       bypass = 1|0
-               If set to 1, the eCAP service is treated as optional. If the
-               service cannot be reached or malfunctions, Squid will try to
-               ignore any errors and process the message as if the service
+
+       uri: ecap://vendor/service_name?custom&cgi=style&parameters=optional
+               Squid uses the eCAP service URI to match this configuration
+               line with one of the dynamically loaded services. Each loaded
+               eCAP service must have a unique URI. Obtain the right URI from
+               the service provider.
+
+
+       Service options are separated by white space. eCAP services support
+       the following name=value options:
+
+       bypass=on|off|1|0
+               If set to 'on' or '1', the eCAP service is treated as optional.
+               If the service cannot be reached or malfunctions, Squid will try
+               to ignore any errors and process the message as if the service
                was not enabled. No all eCAP errors can be bypassed.
-               If set to 0, the eCAP service is treated as essential and all
-               eCAP errors will result in an error page returned to the
+               If set to 'off' or '0', the eCAP service is treated as essential
+               and all eCAP errors will result in an error page returned to the
                HTTP client.
-       service_url = ecap://vendor/service_name?custom&cgi=style&parameters=optional
+
+                Bypass is off by default: services are treated as essential.
+
+       routing=on|off|1|0
+               If set to 'on' or '1', the eCAP service is allowed to
+               dynamically change the current message adaptation plan by
+               returning a chain of services to be used next.
+
+               Dynamic adaptation plan may cross or cover multiple supported
+               vectoring points in their natural processing order.
+
+               Routing is not allowed by default.
+
+       Older ecap_service format without optional named parameters is
+       deprecated but supported for backward compatibility.
+
 
 Example:
-ecap_service service_1 reqmod_precache 0 ecap://filters-R-us/leakDetector?on_error=block
-ecap_service service_2 respmod_precache 1 icap://filters-R-us/virusFilter?config=/etc/vf.cfg
+ecap_service s1 reqmod_precache ecap://filters.R.us/leakDetector?on_error=block bypass=off
+ecap_service s2 respmod_precache ecap://filters.R.us/virusFilter config=/etc/vf.cfg bypass=on
 DOC_END
 
 NAME: loadable_modules