------------------------------------------------------------ revno: 13308 revision-id: chtsanti@users.sourceforge.net-20140312164627-cmi3u7rcpwwqe958 parent: squid3@treenet.co.nz-20140309030651-8l8q91wl706djlt7 committer: Christos Tsantilas branch nick: trunk timestamp: Wed 2014-03-12 18:46:27 +0200 message: Add url_rewrite_extras and store_id_extras for redirector and store_id helpers 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 [ 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. ------------------------------------------------------------ # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: chtsanti@users.sourceforge.net-20140312164627-\ # cmi3u7rcpwwqe958 # target_branch: http://bzr.squid-cache.org/bzr/squid3/trunk/ # testament_sha1: 8f3c0fca81956f8e9c3f9b205905ac01c4a8bb44 # timestamp: 2014-03-12 16:59:21 +0000 # source_branch: http://bzr.squid-cache.org/bzr/squid3/trunk/ # base_revision_id: squid3@treenet.co.nz-20140309030651-\ # 8l8q91wl706djlt7 # # Begin patch === modified file 'src/SquidConfig.h' --- src/SquidConfig.h 2014-01-12 17:51:12 +0000 +++ src/SquidConfig.h 2014-03-12 16:46:27 +0000 @@ -540,6 +540,10 @@ 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. === modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2014-02-21 16:14:05 +0000 +++ src/cache_cf.cc 2014-03-12 16:46:27 +0000 @@ -3033,6 +3033,21 @@ #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) { storeAppendPrintf(entry, "%s %d seconds\n", name, (int) var); === modified file 'src/cf.data.depend' --- src/cf.data.depend 2013-08-29 09:21:53 +0000 +++ src/cf.data.depend 2014-03-12 16:46:27 +0000 @@ -55,6 +55,7 @@ pipelinePrefetch PortCfg QosConfig +TokenOrQuotedString refreshpattern removalpolicy size_t === modified file 'src/cf.data.pre' --- src/cf.data.pre 2014-01-30 21:24:44 +0000 +++ src/cf.data.pre 2014-03-12 16:46:27 +0000 @@ -4607,7 +4607,7 @@ For each requested URL, the rewriter will receive on line with the format - [channel-ID ] URL client_ip "/" fqdn user method [ kv-pairs] + [channel-ID ] URL [ extras] After processing the request the helper must reply using the following format: @@ -4755,6 +4755,18 @@ 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 @@ For each requested URL, the helper will receive one line with the format - [channel-ID ] URL client_ip "/" fqdn user method [ kv-pairs] + [channel-ID ] URL [ extras] After processing the request the helper must reply using the following format: @@ -4790,8 +4802,8 @@ 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 @@ 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 === modified file 'src/cf_gen.cc' --- src/cf_gen.cc 2013-07-21 19:24:35 +0000 +++ src/cf_gen.cc 2014-03-12 16:46:27 +0000 @@ -158,6 +158,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } } + +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(); +} === modified file 'src/client_side_request.cc' --- src/client_side_request.cc 2014-03-08 17:28:23 +0000 +++ src/client_side_request.cc 2014-03-12 16:46:27 +0000 @@ -897,7 +897,7 @@ 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); === modified file 'src/redirect.cc' --- src/redirect.cc 2013-11-23 00:58:42 +0000 +++ src/redirect.cc 2014-03-12 16:46:27 +0000 @@ -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 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 @@ } 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 @@ 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 @@ return; } - constructHelperQuery("redirector", redirectors, redirectHandleReply, http, handler, data); + constructHelperQuery("redirector", redirectors, redirectHandleReply, http, handler, data, redirectorExtrasFmt); } /** @@ -379,7 +381,7 @@ return; } - constructHelperQuery("storeId helper", storeIds, storeIdHandleReply, http, handler, data); + constructHelperQuery("storeId helper", storeIds, storeIdHandleReply, http, handler, data, storeIdExtrasFmt); } void @@ -420,6 +422,16 @@ 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 @@ delete storeIds; storeIds = NULL; + delete redirectorExtrasFmt; + redirectorExtrasFmt = NULL; + + delete storeIdExtrasFmt; + storeIdExtrasFmt = NULL; }