]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Add url_rewrite_extras and store_id_extras for redirector and store_id helpers
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Wed, 12 Mar 2014 16:46:27 +0000 (18:46 +0200)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Wed, 12 Mar 2014 16:46:27 +0000 (18:46 +0200)
The url_rewrite_extras/store_id_extras is a "quoted string" with logformat
%macro support. It is used to modify the request line for redirector and
storeId helpers.

The url rewrite and store_id helpers request format now is:
       url [<SP> extras]
and the default value for extras is:
  "%>a/%>A %un %>rm myip=%la myport=%lp"

Example usage:
   url_rewrite_extras "Note1=%{Note1}note Note2=%{Note2}note"

This is a Measurement Factory project.

src/SquidConfig.h
src/cache_cf.cc
src/cf.data.depend
src/cf.data.pre
src/cf_gen.cc
src/client_side_request.cc
src/redirect.cc

index 013ae217419cfdf99629c60c6264d8a74e21f59a..aa92d3825434ab6ede0cecff9ce8b870428eb1d0 100644 (file)
@@ -540,6 +540,10 @@ public:
 
     int client_ip_max_connections;
 
+    char *redirector_extras;
+
+    char *storeId_extras;
+
     struct {
         int v4_first;       ///< Place IPv4 first in the order of DNS results.
         ssize_t packet_max; ///< maximum size EDNS advertised for DNS replies.
index 0b537d34454953ba9d6937e7c2acc695271a0062..caf65c1ad46485780a5769a257b1ca32ece53515 100644 (file)
@@ -3032,6 +3032,21 @@ parse_eol(char *volatile *var)
 #define dump_eol dump_string
 #define free_eol free_string
 
+static void
+parse_TokenOrQuotedString(char **var)
+{
+    char *token = ConfigParser::NextQuotedToken();
+    safe_free(*var);
+
+    if (token == NULL)
+        self_destruct();
+
+    *var = xstrdup(token);
+}
+
+#define dump_TokenOrQuotedString dump_string
+#define free_TokenOrQuotedString free_string
+
 static void
 dump_time_t(StoreEntry * entry, const char *name, time_t var)
 {
index 1013873910453a3298bd1e9ede55273fd1ebe467..cfd5400c871a2228fcfff851d7341a4f5facddab 100644 (file)
@@ -55,6 +55,7 @@ peer_access           cache_peer acl
 pipelinePrefetch
 PortCfg
 QosConfig
+TokenOrQuotedString
 refreshpattern
 removalpolicy
 size_t
index 829c22d2e28448dc8a2db1e505a315cb3e7076cf..2a8ef198a88c211bd0635c2a0ec2e31b74f9810c 100644 (file)
@@ -4607,7 +4607,7 @@ DOC_START
 
        For each requested URL, the rewriter will receive on line with the format
 
-         [channel-ID <SP>] URL <SP> client_ip "/" fqdn <SP> user <SP> method [<SP> kv-pairs]<NL>
+         [channel-ID <SP>] URL [<SP> extras]<NL>
 
 
        After processing the request the helper must reply using the following format:
@@ -4755,6 +4755,18 @@ DOC_START
        be allowed to request.
 DOC_END
 
+NAME: url_rewrite_extras format
+TYPE: TokenOrQuotedString
+LOC: Config.redirector_extras
+DEFAULT: "%>a/%>A %un %>rm myip=%la myport=%lp"
+DOC_START
+       Specifies a string to be append to request line format for the
+       rewriter helper. "Quoted" format values may contain spaces and
+       logformat %macros. In theory, any logformat %macro can be used.
+       In practice, a %macro expands as a dash (-) if the helper request is
+       sent before the required macro information is available to Squid.
+DOC_END
+
 COMMENT_START
  OPTIONS FOR STORE ID
  -----------------------------------------------------------------------------
@@ -4770,7 +4782,7 @@ DOC_START
 
        For each requested URL, the helper will receive one line with the format
 
-         [channel-ID <SP>] URL <SP> client_ip "/" fqdn <SP> user <SP> method [<SP> kv-pairs]<NL>
+         [channel-ID <SP>] URL [<SP> extras]<NL>
 
 
        After processing the request the helper must reply using the following format:
@@ -4790,8 +4802,8 @@ DOC_START
                a result being identified.
 
 
-       Helper programs should be prepared to receive and possibly ignore additional
-       kv-pairs with keys they do not support.
+       Helper programs should be prepared to receive and possibly ignore
+       additional whitespace-separated tokens on each input line.
 
        When using the concurrency= option the protocol is changed by
        introducing a query channel tag in front of the request/response.
@@ -4808,6 +4820,18 @@ DOC_START
        By default, a StoreID helper is not used.
 DOC_END
 
+NAME: store_id_extras format
+TYPE: TokenOrQuotedString
+LOC: Config.storeId_extras
+DEFAULT: "%>a/%>A %un %>rm myip=%la myport=%lp"
+DOC_START
+        Specifies a string to be append to request line format for the
+        StoreId helper. "Quoted" format values may contain spaces and
+        logformat %macros. In theory, any logformat %macro can be used.
+        In practice, a %macro expands as a dash (-) if the helper request is
+        sent before the required macro information is available to Squid.
+DOC_END
+
 NAME: store_id_children storeurl_rewrite_children
 TYPE: HelperChildConfig
 DEFAULT: 20 startup=0 idle=1 concurrency=0
index 246b3d940536f6bc7503bf774eba9014c1629ae7..cdb3c38b4f7047ff4a25d6c7bc999bd1ee01a86c 100644 (file)
@@ -158,6 +158,7 @@ static void gen_default_if_none(const EntryList &, std::ostream&);
 static void gen_default_postscriptum(const EntryList &, std::ostream&);
 static bool isDefined(const std::string &name);
 static const char *available_if(const std::string &name);
+static const char *gen_quote_escape(const std::string &var);
 
 static void
 checkDepend(const std::string &directive, const char *name, const TypeList &types, const EntryList &entries)
@@ -540,7 +541,7 @@ gen_default(const EntryList &head, std::ostream &fout)
                 fout << "#if " << entry->ifdef << std::endl;
 
             for (LineList::const_iterator l = entry->defaults.preset.begin(); l != entry->defaults.preset.end(); ++l) {
-                fout << "    default_line(\"" << entry->name << " " << *l << "\");" << std::endl;
+                fout << "    default_line(\"" << entry->name << " " << gen_quote_escape(*l) << "\");" << std::endl;
             }
 
             if (entry->ifdef.size())
@@ -581,7 +582,7 @@ gen_default_if_none(const EntryList &head, std::ostream &fout)
 
         fout << "    if (check_null_" << entry->type << "(" << entry->loc << ")) {" << std::endl;
         for (LineList::const_iterator l = entry->defaults.if_none.begin(); l != entry->defaults.if_none.end(); ++l)
-            fout << "        default_line(\"" << entry->name << " " << *l <<"\");" << std::endl;
+            fout << "        default_line(\"" << entry->name << " " << gen_quote_escape(*l) <<"\");" << std::endl;
         fout << "    }" << std::endl;
 
         if (entry->ifdef.size())
@@ -822,13 +823,13 @@ gen_conf(const EntryList &head, std::ostream &fout, bool verbose_output)
             if (entry->defaults.preset.size() && entry->defaults.preset.front().compare("none") != 0) {
                 // Display DEFAULT: line(s)
                 for (LineList::const_iterator l = entry->defaults.preset.begin(); l != entry->defaults.preset.end(); ++l) {
-                    snprintf(buf, sizeof(buf), "%s %s", entry->name.c_str(), l->c_str());
+                    snprintf(buf, sizeof(buf), "%s %s", entry->name.c_str(), gen_quote_escape(*l));
                     def.push_back(buf);
                 }
             } else if (entry->defaults.if_none.size()) {
                 // Display DEFAULT_IF_NONE: line(s)
                 for (LineList::const_iterator l = entry->defaults.if_none.begin(); l != entry->defaults.if_none.end(); ++l) {
-                    snprintf(buf, sizeof(buf), "%s %s", entry->name.c_str(), l->c_str());
+                    snprintf(buf, sizeof(buf), "%s %s", entry->name.c_str(), gen_quote_escape(*l));
                     def.push_back(buf);
                 }
             }
@@ -864,3 +865,22 @@ gen_conf(const EntryList &head, std::ostream &fout, bool verbose_output)
         }
     }
 }
+
+static const char *
+gen_quote_escape(const std::string &var)
+{
+    static std::string esc;
+    esc.clear();
+
+    for (int i = 0; i < var.length(); ++i) {
+        switch (var[i]) {
+            case '"':
+            case '\\':
+                esc += '\\';
+            default:
+                esc += var[i];
+        }
+    }
+
+    return esc.c_str();
+}
index 06c8685047b0779471a153162b7b36af50a203af..b2f2beb8f2d82887d6bf9d533344b2ea4e7fa3ce 100644 (file)
@@ -897,7 +897,7 @@ void
 ClientRequestContext::clientRedirectStart()
 {
     debugs(33, 5, HERE << "'" << http->uri << "'");
-
+    (void)SyncNotes(*http->al, *http->request);
     if (Config.accessList.redirector) {
         acl_checklist = clientAclChecklistCreate(Config.accessList.redirector, http);
         acl_checklist->nonBlockingCheck(clientRedirectAccessCheckDone, this);
index 4131d1c3ad234f2f5c580ddd14697cb45f9fd62e..1ebd680d44ba2da68ec0948b7127b520b086c63c 100644 (file)
@@ -38,6 +38,7 @@
 #include "comm/Connection.h"
 #include "fde.h"
 #include "fqdncache.h"
+#include "format/Format.h"
 #include "globals.h"
 #include "HttpRequest.h"
 #include "mgr/Registration.h"
@@ -82,6 +83,8 @@ static OBJH redirectStats;
 static OBJH storeIdStats;
 static int redirectorBypassed = 0;
 static int storeIdBypassed = 0;
+static Format::Format *redirectorExtrasFmt = NULL;
+static Format::Format *storeIdExtrasFmt = NULL;
 
 CBDATA_CLASS_INIT(RedirectStateData);
 
@@ -233,15 +236,13 @@ storeIdStats(StoreEntry * sentry)
 }
 
 static void
-constructHelperQuery(const char *name, helper *hlp, HLPCB *replyHandler, ClientHttpRequest * http, HLPCB *handler, void *data)
+constructHelperQuery(const char *name, helper *hlp, HLPCB *replyHandler, ClientHttpRequest * http, HLPCB *handler, void *data, Format::Format *requestExtrasFmt)
 {
     ConnStateData * conn = http->getConn();
     const char *fqdn;
     char buf[MAX_REDIRECTOR_REQUEST_STRLEN];
     int sz;
     Http::StatusCode status;
-    char claddr[MAX_IPSTRLEN];
-    char myaddr[MAX_IPSTRLEN];
 
     /** TODO: create a standalone method to initialize
      * the RedirectStateData for all the helpers.
@@ -289,14 +290,15 @@ constructHelperQuery(const char *name, helper *hlp, HLPCB *replyHandler, ClientH
     if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL)
         fqdn = dash_str;
 
-    sz = snprintf(buf, MAX_REDIRECTOR_REQUEST_STRLEN, "%s %s/%s %s %s myip=%s myport=%d\n",
+    static MemBuf requestExtras;
+    requestExtras.reset();
+    if (requestExtrasFmt)
+        requestExtrasFmt->assemble(requestExtras, http->al, 0);
+
+    sz = snprintf(buf, MAX_REDIRECTOR_REQUEST_STRLEN, "%s%s%s\n",
                   r->orig_url.c_str(),
-                  r->client_addr.toStr(claddr,MAX_IPSTRLEN),
-                  fqdn,
-                  r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
-                  r->method_s,
-                  http->request->my_addr.toStr(myaddr,MAX_IPSTRLEN),
-                  http->request->my_addr.port());
+                  requestExtras.hasContent() ? " " : "",
+                  requestExtras.hasContent() ? requestExtras.content() : "");
 
     if ((sz<=0) || (sz>=MAX_REDIRECTOR_REQUEST_STRLEN)) {
         if (sz<=0) {
@@ -353,7 +355,7 @@ redirectStart(ClientHttpRequest * http, HLPCB * handler, void *data)
         return;
     }
 
-    constructHelperQuery("redirector", redirectors, redirectHandleReply, http, handler, data);
+    constructHelperQuery("redirector", redirectors, redirectHandleReply, http, handler, data, redirectorExtrasFmt);
 }
 
 /**
@@ -379,7 +381,7 @@ storeIdStart(ClientHttpRequest * http, HLPCB * handler, void *data)
         return;
     }
 
-    constructHelperQuery("storeId helper", storeIds, storeIdHandleReply, http, handler, data);
+    constructHelperQuery("storeId helper", storeIds, storeIdHandleReply, http, handler, data, storeIdExtrasFmt);
 }
 
 void
@@ -420,6 +422,16 @@ redirectInit(void)
         helperOpenServers(storeIds);
     }
 
+    if (Config.redirector_extras) {
+        redirectorExtrasFmt = new ::Format::Format("redirecor_extras");
+        (void)redirectorExtrasFmt->parse(Config.redirector_extras);
+    }
+
+    if (Config.storeId_extras) {
+        storeIdExtrasFmt = new ::Format::Format("storeId_extras");
+        (void)storeIdExtrasFmt->parse(Config.storeId_extras);
+    }
+
     init = true;
 }
 
@@ -448,4 +460,9 @@ redirectShutdown(void)
     delete storeIds;
     storeIds = NULL;
 
+    delete redirectorExtrasFmt;
+    redirectorExtrasFmt = NULL;
+
+    delete storeIdExtrasFmt;
+    storeIdExtrasFmt = NULL;
 }