]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
SourceLayout: format namespace for custom tag-based formats
authorAmos Jeffries <squid3@treenet.co.nz>
Thu, 4 Aug 2011 03:21:06 +0000 (21:21 -0600)
committerAmos Jeffries <squid3@treenet.co.nz>
Thu, 4 Aug 2011 03:21:06 +0000 (21:21 -0600)
Part 1 of enabling non-logging components to support custom formats in strings

Shuffle the log custom format code into its own library separate from the
logging functionality.

One minor logic change removing redundant LogFileEnabled flag.

TODO:
 - use MemBuf instead or as well as StoreEntry as the output buffer
 - separate from AccessLogEntry confusion
 - upgrade deny_info URL generation format
 - upgrade external_acl_type format
 - add custom helper formats

32 files changed:
configure.ac
doc/debug-sections.txt
src/AccessLogEntry.h
src/HttpRequest.cc
src/HttpRequest.h
src/Makefile.am
src/adaptation/History.cc
src/cache_cf.cc
src/client_db.cc
src/client_side_reply.cc
src/client_side_request.cc
src/format/Format.cc [new file with mode: 0644]
src/format/Format.h [new file with mode: 0644]
src/format/Makefile.am [new file with mode: 0644]
src/format/Quoting.cc [moved from src/log/Gadgets.cc with 97% similarity]
src/format/Quoting.h [moved from src/log/Gadgets.h with 50% similarity]
src/format/Tokens.cc [new file with mode: 0644]
src/format/Tokens.h [moved from src/log/Tokens.h with 55% similarity]
src/helper.cc
src/log/Config.cc
src/log/Config.h
src/log/FormatHttpdCombined.cc
src/log/FormatHttpdCommon.cc
src/log/FormatSquidCustom.cc
src/log/FormatSquidIcap.cc
src/log/FormatSquidNative.cc
src/log/Makefile.am
src/log/Tokens.cc [deleted file]
src/log/access_log.cc
src/stat.cc
src/store_log.cc
src/structs.h

index 5babed57000129eaa368c682852224ee5e8937e9..39b0054eee84b75d6a3d2302d5bd0079cffeb6bb 100644 (file)
@@ -3420,6 +3420,7 @@ AC_CONFIG_FILES([\
        src/comm/Makefile \
        src/esi/Makefile \
        src/eui/Makefile \
+       src/format/Makefile \
        src/icmp/Makefile \
        src/ident/Makefile \
        src/ip/Makefile \
index 0fc9d5f877bf988ca935b57cf5b58681871d5c8f..1166c0d594231fb4cf8da4bd9b5e252b139d0cb8 100644 (file)
@@ -85,7 +85,6 @@ section 46    Access Log - Squid ICAP Logging
 section 46    Access Log - Squid format
 section 46    Access Log - Squid referer format
 section 46    Access Log - Squid useragent format
-section 46    Access Log Format Tokens
 section 47    Store COSS Directory Routines
 section 47    Store Directory Routines
 section 48    Persistent Connections
index 84995c0391ffb171af4b793d45d4b60641a5070b..d15604f2af36d4e77c28fb1c06db96478856db9a 100644 (file)
@@ -239,7 +239,6 @@ public:
 
 class ACLChecklist;
 class StoreEntry;
-class logformat_token;
 
 /* Should be in 'AccessLog.h' as the driver */
 extern void accessLogLogTo(customlog* log, AccessLogEntry* al, ACLChecklist* checklist = NULL);
@@ -249,8 +248,5 @@ extern void accessLogClose(void);
 extern void accessLogInit(void);
 extern void accessLogFreeMemory(AccessLogEntry * aLogEntry);
 extern const char *accessLogTime(time_t);
-extern int accessLogParseLogFormat(logformat_token ** fmt, char *def);
-extern void accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definitions);
-extern void accessLogFreeLogFormat(logformat_token ** fmt);
 
 #endif /* SQUID_HTTPACCESSLOGENTRY_H */
index 6fb9f410c633e4a74804d161ee27f246af458f00..3448d47b9818e578cffeb5dfbed3657c379c003b 100644 (file)
@@ -41,6 +41,7 @@
 #include "auth/UserRequest.h"
 #endif
 #include "HttpHeaderRange.h"
+#include "log/Config.h"
 #include "MemBuf.h"
 #include "Store.h"
 #if ICAP_CLIENT
@@ -438,8 +439,7 @@ Adaptation::Icap::History::Pointer
 HttpRequest::icapHistory() const
 {
     if (!icapHistory_) {
-        if ((LogfileStatus == LOG_ENABLE && alLogformatHasIcapToken) ||
-                IcapLogfileStatus == LOG_ENABLE) {
+        if (Log::TheConfig.hasIcapToken || IcapLogfileStatus == LOG_ENABLE) {
             icapHistory_ = new Adaptation::Icap::History();
             debugs(93,4, HERE << "made " << icapHistory_ << " for " << this);
         }
@@ -464,9 +464,7 @@ HttpRequest::adaptHistory(bool createIfNone) const
 Adaptation::History::Pointer
 HttpRequest::adaptLogHistory() const
 {
-    const bool loggingNeedsHistory = (LogfileStatus == LOG_ENABLE) &&
-                                     alLogformatHasAdaptToken; // TODO: make global to remove this method?
-    return HttpRequest::adaptHistory(loggingNeedsHistory);
+    return HttpRequest::adaptHistory(Log::TheConfig.hasAdaptToken);
 }
 
 void
index 8d8e1afda660bee340e76204c94f4090787b3e27..3de0af7cbb8d17864b866ead5bfa49fbcb3a7524 100644 (file)
 //DEAD?: extern int httpRequestHdrAllowedByName(http_hdr_type id);
 extern void httpRequestPack(void *obj, Packer *p);
 
-// TODO: Move these three to access_log.h or AccessLogEntry.h
-#if USE_ADAPTATION
-extern bool alLogformatHasAdaptToken;
-#endif
-#if ICAP_CLIENT
-extern bool alLogformatHasIcapToken;
-#endif
-extern int LogfileStatus;
-
 class HttpHdrRange;
 class DnsLookupDetails;
 
index 6c152419ed4e42a1fdcfa81ebcdf65294f5bf238..19110eba005b171b5fe08103cd8103bdf200ef87 100644 (file)
@@ -30,8 +30,8 @@ LOADABLE_MODULES_SOURCES = \
        LoadableModules.h \
        LoadableModules.cc
 
-SUBDIRS        = base anyp comm eui acl fs repl
-DIST_SUBDIRS = base anyp comm eui acl fs repl
+SUBDIRS        = base anyp comm eui acl format fs repl
+DIST_SUBDIRS = base anyp comm eui acl format fs repl
 
 if ENABLE_AUTH
 SUBDIRS += auth
@@ -559,6 +559,7 @@ squid_LDADD = \
        eui/libeui.la \
        icmp/libicmp.la icmp/libicmp-core.la \
        log/liblog.la \
+       format/libformat.la \
        $(XTRA_OBJS) \
        $(DISK_LINKOBJS) \
        $(REPL_OBJS) \
@@ -597,6 +598,7 @@ squid_DEPENDENCIES = \
        libsquid.la \
        ip/libip.la \
        fs/libfs.la \
+       format/libformat.la \
        ipc/libipc.la \
        mgr/libmgr.la
 
@@ -1358,6 +1360,7 @@ tests_testCacheManager_LDADD = \
        comm/libcomm.la \
        icmp/libicmp.la icmp/libicmp-core.la \
        log/liblog.la \
+       format/libformat.la \
        $(REPL_OBJS) \
        $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
@@ -1674,6 +1677,7 @@ tests_testEvent_LDADD = \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
+       format/libformat.la \
        $(REPL_OBJS) \
        $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
@@ -1850,6 +1854,7 @@ tests_testEventLoop_LDADD = \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
+       format/libformat.la \
        $(REPL_OBJS) \
        $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
@@ -2021,6 +2026,7 @@ tests_test_http_range_LDADD = \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
+       format/libformat.la \
        $(REPL_OBJS) \
        $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
@@ -2227,6 +2233,7 @@ tests_testHttpRequest_LDADD = \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
+       format/libformat.la \
        $(REPL_OBJS) \
        $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
@@ -2965,6 +2972,7 @@ tests_testURL_LDADD = \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
+       format/libformat.la \
        $(REGEXLIB) \
        $(REPL_OBJS) \
        $(ADAPTATION_LIBS) \
index dd97cda39825d70993332d6a65201ae100fd9a0f..97ea84bf5b1367c393f05c5075b8b0b7bbcb12d1 100644 (file)
@@ -3,7 +3,6 @@
 #include "adaptation/History.h"
 #include "base/TextException.h"
 #include "globals.h"
-#include "HttpRequest.h" /* for alLogformatHasAdaptToken */
 #include "SquidTime.h"
 
 /// impossible services value to identify unset theNextServices
index 5e680a5e0f71716ea122e5b4fa036b19f8474317..7aa27ef049b0d623b3a45239e4acfab10782e7e1 100644 (file)
@@ -60,6 +60,7 @@
 #if USE_SQUID_ESI
 #include "esi/Parser.h"
 #endif
+#include "format/Format.h"
 #include "HttpRequestMethod.h"
 #include "ident/Config.h"
 #include "ip/Intercept.h"
@@ -4097,10 +4098,8 @@ static void
 parse_access_log(customlog ** logs)
 {
     const char *filename, *logdef_name;
-    customlog *cl;
-    logformat *lf;
 
-    cl = (customlog *)xcalloc(1, sizeof(*cl));
+    customlog *cl = (customlog *)xcalloc(1, sizeof(*cl));
 
     if ((filename = strtok(NULL, w_space)) == NULL) {
         self_destruct();
@@ -4120,7 +4119,7 @@ parse_access_log(customlog ** logs)
     cl->filename = xstrdup(filename);
 
     /* look for the definition pointer corresponding to this name */
-    lf = Log::TheConfig.logformats;
+    Format::Format *lf = Log::TheConfig.logformats;
 
     while (lf != NULL) {
         debugs(3, 9, "Comparing against '" << lf->name << "'");
index 6d64c8410a324f258f1ad4e47bf937b689ddf260..dd90241e4b7bac18f832b321f209e4c19cbddc3c 100644 (file)
@@ -34,9 +34,9 @@
 
 #include "squid.h"
 #include "event.h"
+#include "format/Tokens.h"
 #include "ClientInfo.h"
 #include "ip/Address.h"
-#include "log/Tokens.h"
 #include "mgr/Registration.h"
 #include "SquidMath.h"
 #include "SquidTime.h"
@@ -310,7 +310,7 @@ clientdbDump(StoreEntry * sentry)
             if (LOG_UDP_HIT == l)
                 icp_hits += c->Icp.result_hist[l];
 
-            storeAppendPrintf(sentry, "        %-20.20s %7d %3d%%\n",log_tags[l], c->Icp.result_hist[l], Math::intPercent(c->Icp.result_hist[l], c->Icp.n_requests));
+            storeAppendPrintf(sentry, "        %-20.20s %7d %3d%%\n",Format::log_tags[l], c->Icp.result_hist[l], Math::intPercent(c->Icp.result_hist[l], c->Icp.n_requests));
         }
 
         storeAppendPrintf(sentry, "    HTTP Requests %d\n", c->Http.n_requests);
@@ -326,7 +326,7 @@ clientdbDump(StoreEntry * sentry)
 
             storeAppendPrintf(sentry,
                               "        %-20.20s %7d %3d%%\n",
-                              log_tags[l],
+                              Format::log_tags[l],
                               c->Http.result_hist[l],
                               Math::intPercent(c->Http.result_hist[l], c->Http.n_requests));
         }
index a69864dd9e4e082a7fefa0b7d7bbccc82fc16b0f..157cf7d021bbaf9c79975186158e9c7101514bc7 100644 (file)
 #endif
 #include "fde.h"
 #include "forward.h"
+#include "format/Tokens.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "ip/QosConfig.h"
 #include "ipcache.h"
-#include "log/Tokens.h"
 #include "MemObject.h"
 #include "ProtoPort.h"
 #include "SquidTime.h"
@@ -605,7 +605,7 @@ clientReplyContext::processMiss()
     if (http->storeEntry()) {
         if (EBIT_TEST(http->storeEntry()->flags, ENTRY_SPECIAL)) {
             debugs(88, 0, "clientProcessMiss: miss on a special object (" << url << ").");
-            debugs(88, 0, "\tlog_type = " << log_tags[http->logType]);
+            debugs(88, 0, "\tlog_type = " << Format::log_tags[http->logType]);
             http->storeEntry()->dump(1);
         }
 
index 7d9ba1f57323242f8a2e02ceea1e1fd928a6d44e..49615cfef9f797bf9be61a21359fed8e016ca658 100644 (file)
 #include "comm/Write.h"
 #include "compat/inet_pton.h"
 #include "fde.h"
+#include "format/Tokens.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "ip/QosConfig.h"
-#include "log/Tokens.h"
 #include "MemObject.h"
 #include "ProtoPort.h"
 #include "Store.h"
@@ -1314,7 +1314,7 @@ ClientHttpRequest::httpStart()
 {
     PROF_start(httpStart);
     logType = LOG_TAG_NONE;
-    debugs(85, 4, "ClientHttpRequest::httpStart: " << log_tags[logType] << " for '" << uri << "'");
+    debugs(85, 4, "ClientHttpRequest::httpStart: " << Format::log_tags[logType] << " for '" << uri << "'");
 
     /* no one should have touched this */
     assert(out.offset == 0);
diff --git a/src/format/Format.cc b/src/format/Format.cc
new file mode 100644 (file)
index 0000000..8e61152
--- /dev/null
@@ -0,0 +1,1067 @@
+#include "config.h"
+#include "AccessLogEntry.h"
+#include "comm/Connection.h"
+#include "err_detail_type.h"
+#include "errorpage.h"
+#include "format/Format.h"
+#include "format/Quoting.h"
+#include "format/Tokens.h"
+#include "HttpRequest.h"
+#include "MemBuf.h"
+#include "rfc1738.h"
+#include "SquidTime.h"
+#include "Store.h"
+
+
+Format::Format::Format(const char *n) :
+        format(NULL),
+        next(NULL)
+{
+    name = xstrdup(n);
+}
+
+Format::Format::~Format()
+{
+    // erase the list without consuming stack space
+    while (next) {
+        // unlink the next entry for deletion
+        Format *temp = next;
+        next = temp->next;
+        temp->next = NULL;
+        delete temp;
+    }
+
+    // remove locals
+    xfree(name);
+    delete format;
+}
+
+bool
+Format::Format::parse(char *def)
+{
+    char *cur, *eos;
+    Token *new_lt, *last_lt;
+    enum Quoting quote = LOG_QUOTE_NONE;
+
+    debugs(46, 2, HERE << "got definition '" << def << "'");
+
+    if (format) {
+        debugs(46, DBG_IMPORTANT, "WARNING: existing format for '" << name << " " << def << "'");
+        return false;
+    }
+
+    /* very inefficent parser, but who cares, this needs to be simple */
+    /* First off, let's tokenize, we'll optimize in a second pass.
+     * A token can either be a %-prefixed sequence (usually a dynamic
+     * token but it can be an escaped sequence), or a string. */
+    cur = def;
+    eos = def + strlen(def);
+    format = new_lt = last_lt = new Token;
+    cur += new_lt->parse(cur, &quote);
+
+    while (cur < eos) {
+        new_lt = new Token;
+        last_lt->next = new_lt;
+        last_lt = new_lt;
+        cur += new_lt->parse(cur, &quote);
+    }
+
+    return true;
+}
+
+void
+Format::Format::dump(StoreEntry * entry, const char *name)
+{
+    debugs(46, 4, HERE);
+
+    // loop rather than recursing to conserve stack space.
+    for (Format *format = this; format; format = format->next) {
+        debugs(46, 3, HERE << "Dumping format definition for " << format->name);
+        storeAppendPrintf(entry, "format %s ", format->name);
+
+        for (Token *t = format->format; t; t = t->next) {
+            if (t->type == LFT_STRING)
+                storeAppendPrintf(entry, "%s", t->data.string);
+            else {
+                char argbuf[256];
+                char *arg = NULL;
+                ByteCode_t type = t->type;
+
+                switch (type) {
+                    /* special cases */
+
+                case LFT_STRING:
+                    break;
+#if USE_ADAPTATION
+                case LFT_ADAPTATION_LAST_HEADER_ELEM:
+#endif
+#if ICAP_CLIENT
+                case LFT_ICAP_REQ_HEADER_ELEM:
+                case LFT_ICAP_REP_HEADER_ELEM:
+#endif
+                case LFT_REQUEST_HEADER_ELEM:
+                case LFT_ADAPTED_REQUEST_HEADER_ELEM:
+                case LFT_REPLY_HEADER_ELEM:
+
+                    if (t->data.header.separator != ',')
+                        snprintf(argbuf, sizeof(argbuf), "%s:%c%s", t->data.header.header, t->data.header.separator, t->data.header.element);
+                    else
+                        snprintf(argbuf, sizeof(argbuf), "%s:%s", t->data.header.header, t->data.header.element);
+
+                    arg = argbuf;
+
+                    switch (type) {
+                    case LFT_REQUEST_HEADER_ELEM:
+                        type = LFT_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
+                        break;
+                    case LFT_ADAPTED_REQUEST_HEADER_ELEM:
+                        type = LFT_ADAPTED_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
+                        break;
+                    case LFT_REPLY_HEADER_ELEM:
+                        type = LFT_REPLY_HEADER_ELEM; // XXX: remove _ELEM?
+                        break;
+#if USE_ADAPTATION
+                    case LFT_ADAPTATION_LAST_HEADER_ELEM:
+                        type = LFT_ADAPTATION_LAST_HEADER;
+                        break;
+#endif
+#if ICAP_CLIENT
+                    case LFT_ICAP_REQ_HEADER_ELEM:
+                        type = LFT_ICAP_REQ_HEADER;
+                        break;
+                    case LFT_ICAP_REP_HEADER_ELEM:
+                        type = LFT_ICAP_REP_HEADER;
+                        break;
+#endif
+                    default:
+                        break;
+                    }
+
+                    break;
+
+                case LFT_REQUEST_ALL_HEADERS:
+                case LFT_ADAPTED_REQUEST_ALL_HEADERS:
+                case LFT_REPLY_ALL_HEADERS:
+
+#if USE_ADAPTATION
+                case LFT_ADAPTATION_LAST_ALL_HEADERS:
+#endif
+#if ICAP_CLIENT
+                case LFT_ICAP_REQ_ALL_HEADERS:
+                case LFT_ICAP_REP_ALL_HEADERS:
+#endif
+
+                    switch (type) {
+                    case LFT_REQUEST_ALL_HEADERS:
+                        type = LFT_REQUEST_HEADER;
+                        break;
+                    case LFT_ADAPTED_REQUEST_ALL_HEADERS:
+                        type = LFT_ADAPTED_REQUEST_HEADER;
+                        break;
+                    case LFT_REPLY_ALL_HEADERS:
+                        type = LFT_REPLY_HEADER;
+                        break;
+#if USE_ADAPTATION
+                    case LFT_ADAPTATION_LAST_ALL_HEADERS:
+                        type = LFT_ADAPTATION_LAST_HEADER;
+                        break;
+#endif
+#if ICAP_CLIENT
+                    case LFT_ICAP_REQ_ALL_HEADERS:
+                        type = LFT_ICAP_REQ_HEADER;
+                        break;
+                    case LFT_ICAP_REP_ALL_HEADERS:
+                        type = LFT_ICAP_REP_HEADER;
+                        break;
+#endif
+                    default:
+                        break;
+                    }
+
+                    break;
+
+                default:
+                    if (t->data.string)
+                        arg = t->data.string;
+
+                    break;
+                }
+
+                entry->append("%", 1);
+
+                switch (t->quote) {
+
+                case LOG_QUOTE_QUOTES:
+                    entry->append("\"", 1);
+                    break;
+
+                case LOG_QUOTE_MIMEBLOB:
+                    entry->append("[", 1);
+                    break;
+
+                case LOG_QUOTE_URL:
+                    entry->append("#", 1);
+                    break;
+
+                case LOG_QUOTE_RAW:
+                    entry->append("'", 1);
+                    break;
+
+                case LOG_QUOTE_NONE:
+                    break;
+                }
+
+                if (t->left)
+                    entry->append("-", 1);
+
+                if (t->zero)
+                    entry->append("0", 1);
+
+                if (t->width)
+                    storeAppendPrintf(entry, "%d", (int) t->width);
+
+                if (t->precision)
+                    storeAppendPrintf(entry, ".%d", (int) t->precision);
+
+                if (arg)
+                    storeAppendPrintf(entry, "{%s}", arg);
+
+                for (struct TokenTableEntry *te = TokenTable; te->config != NULL; te++) {
+                    if (te->token_type == type) {
+                        storeAppendPrintf(entry, "%s", te->config);
+                        break;
+                    }
+                }
+
+                if (t->space)
+                    entry->append(" ", 1);
+            }
+        }
+
+        entry->append("\n", 1);
+    }
+
+}
+
+static void
+log_quoted_string(const char *str, char *out)
+{
+    char *p = out;
+
+    while (*str) {
+        int l = strcspn(str, "\"\\\r\n\t");
+        memcpy(p, str, l);
+        str += l;
+        p += l;
+
+        switch (*str) {
+
+        case '\0':
+            break;
+
+        case '\r':
+            *p++ = '\\';
+            *p++ = 'r';
+            str++;
+            break;
+
+        case '\n':
+            *p++ = '\\';
+            *p++ = 'n';
+            str++;
+            break;
+
+        case '\t':
+            *p++ = '\\';
+            *p++ = 't';
+            str++;
+            break;
+
+        default:
+            *p++ = '\\';
+            *p++ = *str;
+            str++;
+            break;
+        }
+    }
+
+    *p++ = '\0';
+}
+
+void
+Format::Format::assemble(MemBuf &mb, AccessLogEntry *al, int logSequenceNumber) const
+{
+    char tmp[1024];
+    String sb;
+
+    for (Token *fmt = format; fmt != NULL; fmt = fmt->next) {  /* for each token */
+        const char *out = NULL;
+        int quote = 0;
+        long int outint = 0;
+        int doint = 0;
+        int dofree = 0;
+        int64_t outoff = 0;
+        int dooff = 0;
+
+        switch (fmt->type) {
+
+        case LFT_NONE:
+            out = "";
+            break;
+
+        case LFT_STRING:
+            out = fmt->data.string;
+            break;
+
+        case LFT_CLIENT_IP_ADDRESS:
+            if (al->cache.caddr.IsNoAddr()) // e.g., ICAP OPTIONS lack client
+                out = "-";
+            else
+                out = al->cache.caddr.NtoA(tmp,1024);
+            break;
+
+        case LFT_CLIENT_FQDN:
+            if (al->cache.caddr.IsAnyAddr()) // e.g., ICAP OPTIONS lack client
+                out = "-";
+            else
+                out = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
+            if (!out) {
+                out = al->cache.caddr.NtoA(tmp,1024);
+            }
+
+            break;
+
+        case LFT_CLIENT_PORT:
+            if (al->request) {
+                outint = al->request->client_addr.GetPort();
+                doint = 1;
+            }
+            break;
+
+#if USE_SQUID_EUI
+        case LFT_CLIENT_EUI:
+            // TODO make the ACL checklist have a direct link to any TCP details.
+            if (al->request && al->request->clientConnectionManager.valid() && al->request->clientConnectionManager->clientConnection != NULL) {
+                if (al->request->clientConnectionManager->clientConnection->remote.IsIPv4())
+                    al->request->clientConnectionManager->clientConnection->remoteEui48.encode(tmp, 1024);
+                else
+                    al->request->clientConnectionManager->clientConnection->remoteEui64.encode(tmp, 1024);
+                out = tmp;
+            }
+            break;
+#endif
+
+            /* case LFT_SERVER_IP_ADDRESS: */
+
+        case LFT_SERVER_IP_OR_PEER_NAME:
+            out = al->hier.host;
+
+            break;
+
+            /* case LFT_SERVER_PORT: */
+
+        case LFT_LOCAL_IP:
+            if (al->request) {
+                out = al->request->my_addr.NtoA(tmp,sizeof(tmp));
+            }
+
+            break;
+
+        case LFT_LOCAL_PORT:
+            if (al->request) {
+                outint = al->request->my_addr.GetPort();
+                doint = 1;
+            }
+
+            break;
+
+            // the fmt->type can not be LFT_PEER_LOCAL_IP_OLD_27
+            // but compiler complains if ommited
+        case LFT_PEER_LOCAL_IP_OLD_27:
+        case LFT_PEER_LOCAL_IP:
+            if (!al->hier.peer_local_addr.IsAnyAddr()) {
+                out = al->hier.peer_local_addr.NtoA(tmp,sizeof(tmp));
+            }
+            break;
+
+        case LFT_PEER_LOCAL_PORT:
+            if ((outint = al->hier.peer_local_addr.GetPort())) {
+                doint = 1;
+            }
+
+            break;
+
+        case LFT_TIME_SECONDS_SINCE_EPOCH:
+            // some platforms store time in 32-bit, some 64-bit...
+            outoff = static_cast<int64_t>(current_time.tv_sec);
+            dooff = 1;
+            break;
+
+        case LFT_TIME_SUBSECOND:
+            outint = current_time.tv_usec / fmt->divisor;
+            doint = 1;
+            break;
+
+
+        case LFT_TIME_LOCALTIME:
+
+        case LFT_TIME_GMT: {
+            const char *spec;
+
+            struct tm *t;
+            spec = fmt->data.timespec;
+
+            if (fmt->type == LFT_TIME_LOCALTIME) {
+                if (!spec)
+                    spec = "%d/%b/%Y:%H:%M:%S %z";
+                t = localtime(&squid_curtime);
+            } else {
+                if (!spec)
+                    spec = "%d/%b/%Y:%H:%M:%S";
+
+                t = gmtime(&squid_curtime);
+            }
+
+            strftime(tmp, sizeof(tmp), spec, t);
+
+            out = tmp;
+        }
+
+        break;
+
+        case LFT_TIME_TO_HANDLE_REQUEST:
+            outint = al->cache.msec;
+            doint = 1;
+            break;
+
+        case LFT_PEER_RESPONSE_TIME:
+            if (al->hier.peer_response_time < 0) {
+                out = "-";
+            } else {
+                outoff = al->hier.peer_response_time;
+                dooff = 1;
+            }
+            break;
+
+        case LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME:
+            if (al->hier.total_response_time < 0) {
+                out = "-";
+            } else {
+                outoff = al->hier.total_response_time;
+                dooff = 1;
+            }
+            break;
+
+        case LFT_DNS_WAIT_TIME:
+            if (al->request && al->request->dnsWait >= 0) {
+                outint = al->request->dnsWait;
+                doint = 1;
+            }
+            break;
+
+        case LFT_REQUEST_HEADER:
+
+            if (al->request)
+                sb = al->request->header.getByName(fmt->data.header.header);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ADAPTED_REQUEST_HEADER:
+
+            if (al->request)
+                sb = al->adapted_request->header.getByName(fmt->data.header.header);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_REPLY_HEADER:
+            if (al->reply)
+                sb = al->reply->header.getByName(fmt->data.header.header);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+#if USE_ADAPTATION
+        case LTF_ADAPTATION_SUM_XACT_TIMES:
+            if (al->request) {
+                Adaptation::History::Pointer ah = al->request->adaptHistory();
+                if (ah != NULL)
+                    ah->sumLogString(fmt->data.string, sb);
+                out = sb.termedBuf();
+            }
+            break;
+
+        case LTF_ADAPTATION_ALL_XACT_TIMES:
+            if (al->request) {
+                Adaptation::History::Pointer ah = al->request->adaptHistory();
+                if (ah != NULL)
+                    ah->allLogString(fmt->data.string, sb);
+                out = sb.termedBuf();
+            }
+            break;
+
+        case LFT_ADAPTATION_LAST_HEADER:
+            if (al->request) {
+                const Adaptation::History::Pointer ah = al->request->adaptHistory();
+                if (ah != NULL) // XXX: add adapt::<all_h but use lastMeta here
+                    sb = ah->allMeta.getByName(fmt->data.header.header);
+            }
+
+            // XXX: here and elsewhere: move such code inside the if guard
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ADAPTATION_LAST_HEADER_ELEM:
+            if (al->request) {
+                const Adaptation::History::Pointer ah = al->request->adaptHistory();
+                if (ah != NULL) // XXX: add adapt::<all_h but use lastMeta here
+                    sb = ah->allMeta.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+            }
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ADAPTATION_LAST_ALL_HEADERS:
+            out = al->adapt.last_meta;
+
+            quote = 1;
+
+            break;
+#endif
+
+#if ICAP_CLIENT
+        case LFT_ICAP_ADDR:
+            if (!out)
+                out = al->icap.hostAddr.NtoA(tmp,1024);
+            break;
+
+        case LFT_ICAP_SERV_NAME:
+            out = al->icap.serviceName.termedBuf();
+            break;
+
+        case LFT_ICAP_REQUEST_URI:
+            out = al->icap.reqUri.termedBuf();
+            break;
+
+        case LFT_ICAP_REQUEST_METHOD:
+            out = Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod);
+            break;
+
+        case LFT_ICAP_BYTES_SENT:
+            outoff = al->icap.bytesSent;
+            dooff = 1;
+            break;
+
+        case LFT_ICAP_BYTES_READ:
+            outoff = al->icap.bytesRead;
+            dooff = 1;
+            break;
+
+        case LFT_ICAP_BODY_BYTES_READ:
+            if (al->icap.bodyBytesRead >= 0) {
+                outoff = al->icap.bodyBytesRead;
+                dooff = 1;
+            }
+            // else if icap.bodyBytesRead < 0, we do not have any http data,
+            // so just print a "-" (204 responses etc)
+            break;
+
+        case LFT_ICAP_REQ_HEADER:
+            if (NULL != al->icap.request) {
+                sb = al->icap.request->header.getByName(fmt->data.header.header);
+                out = sb.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_ICAP_REQ_HEADER_ELEM:
+            if (al->request)
+                sb = al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ICAP_REQ_ALL_HEADERS:
+            if (al->icap.request) {
+                HttpHeaderPos pos = HttpHeaderInitPos;
+                while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
+                    sb.append(e->name);
+                    sb.append(": ");
+                    sb.append(e->value);
+                    sb.append("\r\n");
+                }
+                out = sb.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_ICAP_REP_HEADER:
+            if (NULL != al->icap.reply) {
+                sb = al->icap.reply->header.getByName(fmt->data.header.header);
+                out = sb.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_ICAP_REP_HEADER_ELEM:
+            if (NULL != al->icap.reply)
+                sb = al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ICAP_REP_ALL_HEADERS:
+            if (al->icap.reply) {
+                HttpHeaderPos pos = HttpHeaderInitPos;
+                while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
+                    sb.append(e->name);
+                    sb.append(": ");
+                    sb.append(e->value);
+                    sb.append("\r\n");
+                }
+                out = sb.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_ICAP_TR_RESPONSE_TIME:
+            outint = al->icap.trTime;
+            doint = 1;
+            break;
+
+        case LFT_ICAP_IO_TIME:
+            outint = al->icap.ioTime;
+            doint = 1;
+            break;
+
+        case LFT_ICAP_STATUS_CODE:
+            outint = al->icap.resStatus;
+            doint  = 1;
+            break;
+
+        case LFT_ICAP_OUTCOME:
+            out = al->icap.outcome;
+            break;
+
+        case LFT_ICAP_TOTAL_TIME:
+            outint = al->icap.processingTime;
+            doint = 1;
+            break;
+#endif
+        case LFT_REQUEST_HEADER_ELEM:
+            if (al->request)
+                sb = al->request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ADAPTED_REQUEST_HEADER_ELEM:
+            if (al->adapted_request)
+                sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_REPLY_HEADER_ELEM:
+            if (al->reply)
+                sb = al->reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_REQUEST_ALL_HEADERS:
+            out = al->headers.request;
+
+            quote = 1;
+
+            break;
+
+        case LFT_ADAPTED_REQUEST_ALL_HEADERS:
+            out = al->headers.adapted_request;
+
+            quote = 1;
+
+            break;
+
+        case LFT_REPLY_ALL_HEADERS:
+            out = al->headers.reply;
+
+            quote = 1;
+
+            break;
+
+        case LFT_USER_NAME:
+            out = QuoteUrlEncodeUsername(al->cache.authuser);
+
+            if (!out)
+                out = QuoteUrlEncodeUsername(al->cache.extuser);
+
+#if USE_SSL
+
+            if (!out)
+                out = QuoteUrlEncodeUsername(al->cache.ssluser);
+
+#endif
+
+            if (!out)
+                out = QuoteUrlEncodeUsername(al->cache.rfc931);
+
+            dofree = 1;
+
+            break;
+
+        case LFT_USER_LOGIN:
+            out = QuoteUrlEncodeUsername(al->cache.authuser);
+
+            dofree = 1;
+
+            break;
+
+        case LFT_USER_IDENT:
+            out = QuoteUrlEncodeUsername(al->cache.rfc931);
+
+            dofree = 1;
+
+            break;
+
+        case LFT_USER_EXTERNAL:
+            out = QuoteUrlEncodeUsername(al->cache.extuser);
+
+            dofree = 1;
+
+            break;
+
+            /* case LFT_USER_REALM: */
+            /* case LFT_USER_SCHEME: */
+
+            // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
+            // but compiler complains if ommited
+        case LFT_HTTP_SENT_STATUS_CODE_OLD_30:
+        case LFT_HTTP_SENT_STATUS_CODE:
+            outint = al->http.code;
+
+            doint = 1;
+
+            break;
+
+        case LFT_HTTP_RECEIVED_STATUS_CODE:
+            if (al->hier.peer_reply_status == HTTP_STATUS_NONE) {
+                out = "-";
+            } else {
+                outint = al->hier.peer_reply_status;
+                doint = 1;
+            }
+            break;
+            /* case LFT_HTTP_STATUS:
+             *           out = statusline->text;
+             *     quote = 1;
+             *     break;
+             */
+        case LFT_HTTP_BODY_BYTES_READ:
+            if (al->hier.bodyBytesRead >= 0) {
+                outoff = al->hier.bodyBytesRead;
+                dooff = 1;
+            }
+            // else if hier.bodyBytesRead < 0 we did not have any data exchange with
+            // a peer server so just print a "-" (eg requests served from cache,
+            // or internal error messages).
+            break;
+
+        case LFT_SQUID_STATUS:
+            if (al->http.timedout || al->http.aborted) {
+                snprintf(tmp, sizeof(tmp), "%s%s", log_tags[al->cache.code],
+                         al->http.statusSfx());
+                out = tmp;
+            } else {
+                out = log_tags[al->cache.code];
+            }
+
+            break;
+
+        case LFT_SQUID_ERROR:
+            if (al->request && al->request->errType != ERR_NONE)
+                out = errorPageName(al->request->errType);
+            break;
+
+        case LFT_SQUID_ERROR_DETAIL:
+            if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
+                if (al->request->errDetail > ERR_DETAIL_START  &&
+                        al->request->errDetail < ERR_DETAIL_MAX)
+                    out = errorDetailName(al->request->errDetail);
+                else {
+                    if (al->request->errDetail >= ERR_DETAIL_EXCEPTION_START)
+                        snprintf(tmp, sizeof(tmp), "%s=0x%X",
+                                 errorDetailName(al->request->errDetail), (uint32_t) al->request->errDetail);
+                    else
+                        snprintf(tmp, sizeof(tmp), "%s=%d",
+                                 errorDetailName(al->request->errDetail), al->request->errDetail);
+                    out = tmp;
+                }
+            }
+            break;
+
+        case LFT_SQUID_HIERARCHY:
+            if (al->hier.ping.timedout)
+                mb.append("TIMEOUT_", 8);
+
+            out = hier_code_str[al->hier.code];
+
+            break;
+
+        case LFT_MIME_TYPE:
+            out = al->http.content_type;
+
+            break;
+
+        case LFT_CLIENT_REQ_METHOD:
+            if (al->request) {
+                out = al->request->method.image();
+                quote = 1;
+            }
+            break;
+
+        case LFT_CLIENT_REQ_URI:
+            // original client URI
+            if (al->request) {
+                out = urlCanonical(al->request);
+                quote = 1;
+            }
+            break;
+
+        case LFT_REQUEST_URLPATH_OLD_31:
+        case LFT_CLIENT_REQ_URLPATH:
+            if (al->request) {
+                out = al->request->urlpath.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_CLIENT_REQ_VERSION:
+            if (al->request) {
+                snprintf(tmp, sizeof(tmp), "%d.%d", (int) al->request->http_ver.major, (int) al->request->http_ver.minor);
+                out = tmp;
+            }
+            break;
+
+        case LFT_REQUEST_METHOD:
+            out = al->_private.method_str;
+            break;
+
+        case LFT_REQUEST_URI:
+            out = al->url;
+            break;
+
+        case LFT_REQUEST_VERSION_OLD_2X:
+        case LFT_REQUEST_VERSION:
+            snprintf(tmp, sizeof(tmp), "%d.%d", (int) al->http.version.major, (int) al->http.version.minor);
+            out = tmp;
+            break;
+
+        case LFT_SERVER_REQ_METHOD:
+            if (al->adapted_request) {
+                out = al->adapted_request->method.image();
+                quote = 1;
+            }
+            break;
+
+        case LFT_SERVER_REQ_URI:
+            // adapted request URI sent to server/peer
+            if (al->adapted_request) {
+                out = urlCanonical(al->adapted_request);
+                quote = 1;
+            }
+            break;
+
+        case LFT_SERVER_REQ_URLPATH:
+            if (al->adapted_request) {
+                out = al->adapted_request->urlpath.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_SERVER_REQ_VERSION:
+            if (al->adapted_request) {
+                snprintf(tmp, sizeof(tmp), "%d.%d",
+                         (int) al->adapted_request->http_ver.major,
+                         (int) al->adapted_request->http_ver.minor);
+                out = tmp;
+            }
+            break;
+
+        case LFT_REQUEST_SIZE_TOTAL:
+            outoff = al->cache.requestSize;
+            dooff = 1;
+            break;
+
+            /*case LFT_REQUEST_SIZE_LINE: */
+        case LFT_REQUEST_SIZE_HEADERS:
+            outoff = al->cache.requestHeadersSize;
+            dooff =1;
+            break;
+            /*case LFT_REQUEST_SIZE_BODY: */
+            /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
+
+        case LFT_REPLY_SIZE_TOTAL:
+            outoff = al->cache.replySize;
+            dooff = 1;
+            break;
+
+        case LFT_REPLY_HIGHOFFSET:
+            outoff = al->cache.highOffset;
+
+            dooff = 1;
+
+            break;
+
+        case LFT_REPLY_OBJECTSIZE:
+            outoff = al->cache.objectSize;
+
+            dooff = 1;
+
+            break;
+
+            /*case LFT_REPLY_SIZE_LINE: */
+        case LFT_REPLY_SIZE_HEADERS:
+            outint = al->cache.replyHeadersSize;
+            doint = 1;
+            break;
+            /*case LFT_REPLY_SIZE_BODY: */
+            /*case LFT_REPLY_SIZE_BODY_NO_TE: */
+
+        case LFT_TAG:
+            if (al->request)
+                out = al->request->tag.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_IO_SIZE_TOTAL:
+            outint = al->cache.requestSize + al->cache.replySize;
+            doint = 1;
+            break;
+
+        case LFT_EXT_LOG:
+            if (al->request)
+                out = al->request->extacl_log.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_SEQUENCE_NUMBER:
+            outoff = logSequenceNumber;
+            dooff = 1;
+            break;
+
+        case LFT_PERCENT:
+            out = "%";
+
+            break;
+        }
+
+        if (dooff) {
+            snprintf(tmp, sizeof(tmp), "%0*" PRId64, fmt->zero ? (int) fmt->width : 0, outoff);
+            out = tmp;
+
+        } else if (doint) {
+            snprintf(tmp, sizeof(tmp), "%0*ld", fmt->zero ? (int) fmt->width : 0, outint);
+            out = tmp;
+        }
+
+        if (out && *out) {
+            if (quote || fmt->quote != LOG_QUOTE_NONE) {
+                char *newout = NULL;
+                int newfree = 0;
+
+                switch (fmt->quote) {
+
+                case LOG_QUOTE_NONE:
+                    newout = rfc1738_escape_unescaped(out);
+                    break;
+
+                case LOG_QUOTE_QUOTES: {
+                    size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
+                    if (out_len >= sizeof(tmp)) {
+                        newout = (char *)xmalloc(out_len);
+                        newfree = 1;
+                    } else
+                        newout = tmp;
+                    log_quoted_string(out, newout);
+                }
+                break;
+
+                case LOG_QUOTE_MIMEBLOB:
+                    newout = QuoteMimeBlob(out);
+                    newfree = 1;
+                    break;
+
+                case LOG_QUOTE_URL:
+                    newout = rfc1738_escape(out);
+                    break;
+
+                case LOG_QUOTE_RAW:
+                    break;
+                }
+
+                if (newout) {
+                    if (dofree)
+                        safe_free(out);
+
+                    out = newout;
+
+                    dofree = newfree;
+                }
+            }
+
+            if (fmt->width) {
+                if (fmt->left)
+                    mb.Printf("%-*s", (int) fmt->width, out);
+                else
+                    mb.Printf("%*s", (int) fmt->width, out);
+            } else
+                mb.append(out, strlen(out));
+        } else {
+            mb.append("-", 1);
+        }
+
+        if (fmt->space)
+            mb.append(" ", 1);
+
+        sb.clean();
+
+        if (dofree)
+            safe_free(out);
+    }
+}
diff --git a/src/format/Format.h b/src/format/Format.h
new file mode 100644 (file)
index 0000000..3c17756
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _SQUID_FORMAT_FORMAT_H
+#define _SQUID_FORMAT_FORMAT_H
+
+/*
+ * Squid configuration allows users to define custom formats in
+ * several components.
+ * - logging
+ * - external ACL input
+ * - deny page URL
+ *
+ * These enumerations and classes define the API for parsing of
+ * format directives to define these patterns. Along with output
+ * functionality to produce formatted buffers.
+ */
+
+class AccessLogEntry;
+class MemBuf;
+class StoreEntry;
+
+namespace Format
+{
+
+class Token;
+
+// XXX: inherit from linked list
+class Format
+{
+public:
+    Format(const char *name);
+    ~Format();
+
+    /* very inefficent parser, but who cares, this needs to be simple */
+    /* First off, let's tokenize, we'll optimize in a second pass.
+     * A token can either be a %-prefixed sequence (usually a dynamic
+     * token but it can be an escaped sequence), or a string. */
+    bool parse(char *def);
+
+    /// assemble the state information into a formatted line.
+    void assemble(MemBuf &mb, AccessLogEntry *al, int logSequenceNumber) const;
+
+    /// dump this whole list of formats into the provided StoreEntry
+    void dump(StoreEntry * entry, const char *name);
+
+    char *name;
+    Token *format;
+    Format *next;
+};
+
+} // namespace Format
+
+#endif /* _SQUID_FORMAT_FORMAT_H */
diff --git a/src/format/Makefile.am b/src/format/Makefile.am
new file mode 100644 (file)
index 0000000..cbf05de
--- /dev/null
@@ -0,0 +1,13 @@
+include $(top_srcdir)/src/Common.am
+include $(top_srcdir)/src/TestHeaders.am
+
+noinst_LTLIBRARIES = libformat.la
+
+libformat_la_SOURCES = \
+       Format.cc \
+       Format.h \
+       Quoting.cc \
+       Quoting.h \
+       Tokens.cc \
+       Tokens.h
+
similarity index 97%
rename from src/log/Gadgets.cc
rename to src/format/Quoting.cc
index f188f813e7a24aa7f0edab4f9642b18220bbc1c6..badff8814be669975ef96a1dce58d08bc195893d 100644 (file)
@@ -1,5 +1,5 @@
 #include "config.h"
-#include "log/Gadgets.h"
+#include "format/Quoting.h"
 
 static const char c2x[] =
     "000102030405060708090a0b0c0d0e0f"
@@ -70,7 +70,7 @@ username_quote(const char *header)
 #endif // DEAD
 
 char *
-Log::FormatName(const char *name)
+Format::QuoteUrlEncodeUsername(const char *name)
 {
     if (NULL == name)
         return NULL;
@@ -83,7 +83,7 @@ Log::FormatName(const char *name)
 }
 
 char *
-Log::QuoteMimeBlob(const char *header)
+Format::QuoteMimeBlob(const char *header)
 {
     int c;
     int i;
similarity index 50%
rename from src/log/Gadgets.h
rename to src/format/Quoting.h
index 9e5e1dd0d9295ba72858bb07ecee274064b52b88..2b6e78d837e2649dc4815855689ddb93870d6878 100644 (file)
@@ -1,19 +1,19 @@
-#ifndef _SQUID_LOG_GADGETS_H
-#define _SQUID_LOG_GADGETS_H
+#ifndef _SQUID_FORMAT_QUOTING_H
+#define _SQUID_FORMAT_QUOTING_H
 
-namespace Log
+namespace Format
 {
 
 /// Safely URL-encode a username.
 /// Accepts NULL or empty strings.
-char * FormatName(const char *name);
+extern char * QuoteUrlEncodeUsername(const char *name);
 
 /** URL-style encoding on a MIME headers blob.
  * May accept NULL or empty strings.
  * \return A dynamically allocated string. recipient is responsible for free()'ing
  */
-char *QuoteMimeBlob(const char *header);
+extern char *QuoteMimeBlob(const char *header);
 
-}; // namespace Log
+}; // namespace Format
 
-#endif /* _SQUID_LOG_GADGETS_H */
+#endif /* _SQUID_FORMAT_QUOTING_H */
diff --git a/src/format/Tokens.cc b/src/format/Tokens.cc
new file mode 100644 (file)
index 0000000..9feed0e
--- /dev/null
@@ -0,0 +1,463 @@
+#include "config.h"
+#include "format/Tokens.h"
+#include "Store.h"
+
+const char *Format::log_tags[] = {
+    "NONE",
+    "TCP_HIT",
+    "TCP_MISS",
+    "TCP_REFRESH_UNMODIFIED",
+    "TCP_REFRESH_FAIL", // same tag logged for LOG_TCP_REFRESH_FAIL_OLD and
+    "TCP_REFRESH_FAIL", // LOG_TCP_REFRESH_FAIL_ERR for backward-compatibility
+    "TCP_REFRESH_MODIFIED",
+    "TCP_CLIENT_REFRESH_MISS",
+    "TCP_IMS_HIT",
+    "TCP_SWAPFAIL_MISS",
+    "TCP_NEGATIVE_HIT",
+    "TCP_MEM_HIT",
+    "TCP_DENIED",
+    "TCP_DENIED_REPLY",
+    "TCP_OFFLINE_HIT",
+#if LOG_TCP_REDIRECTS
+    "TCP_REDIRECT",
+#endif
+    "UDP_HIT",
+    "UDP_MISS",
+    "UDP_DENIED",
+    "UDP_INVALID",
+    "UDP_MISS_NOFETCH",
+    "ICP_QUERY",
+    "LOG_TYPE_MAX"
+};
+
+struct Format::TokenTableEntry Format::TokenTable[] = {
+
+    {">a", LFT_CLIENT_IP_ADDRESS},
+    {">p", LFT_CLIENT_PORT},
+    {">A", LFT_CLIENT_FQDN},
+#if USE_SQUID_EUI
+    {">eui", LFT_CLIENT_EUI},
+#endif
+
+    /*{ "<a", LFT_SERVER_IP_ADDRESS }, */
+    /*{ "<p", LFT_SERVER_PORT }, */
+    {"<A", LFT_SERVER_IP_OR_PEER_NAME},
+
+    {"la", LFT_LOCAL_IP},
+    {"lp", LFT_LOCAL_PORT},
+    /*{ "lA", LFT_LOCAL_NAME }, */
+
+    {"<la", LFT_PEER_LOCAL_IP},
+    {"oa", LFT_PEER_LOCAL_IP_OLD_27},
+    {"<lp", LFT_PEER_LOCAL_PORT},
+    /* {"ot", LFT_PEER_OUTGOING_TOS}, */
+
+    {"ts", LFT_TIME_SECONDS_SINCE_EPOCH},
+    {"tu", LFT_TIME_SUBSECOND},
+    {"tl", LFT_TIME_LOCALTIME},
+    {"tg", LFT_TIME_GMT},
+    {"tr", LFT_TIME_TO_HANDLE_REQUEST},
+
+    {"<pt", LFT_PEER_RESPONSE_TIME},
+    {"<tt", LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME},
+    {"dt", LFT_DNS_WAIT_TIME},
+
+    {">ha", LFT_ADAPTED_REQUEST_HEADER},
+    {">ha", LFT_ADAPTED_REQUEST_ALL_HEADERS},
+    {">h", LFT_REQUEST_HEADER},
+    {">h", LFT_REQUEST_ALL_HEADERS},
+    {"<h", LFT_REPLY_HEADER},
+    {"<h", LFT_REPLY_ALL_HEADERS},
+
+    {"un", LFT_USER_NAME},
+    {"ul", LFT_USER_LOGIN},
+    /*{ "ur", LFT_USER_REALM }, */
+    /*{ "us", LFT_USER_SCHEME }, */
+    {"ui", LFT_USER_IDENT},
+    {"ue", LFT_USER_EXTERNAL},
+
+    {"Hs", LFT_HTTP_SENT_STATUS_CODE_OLD_30},
+    {">Hs", LFT_HTTP_SENT_STATUS_CODE},
+    {"<Hs", LFT_HTTP_RECEIVED_STATUS_CODE},
+    /*{ "Ht", LFT_HTTP_STATUS }, */
+    {"<bs", LFT_HTTP_BODY_BYTES_READ},
+
+    {"Ss", LFT_SQUID_STATUS},
+    { "err_code", LFT_SQUID_ERROR },
+    { "err_detail", LFT_SQUID_ERROR_DETAIL },
+    {"Sh", LFT_SQUID_HIERARCHY},
+
+    {"mt", LFT_MIME_TYPE},
+
+    {">rm", LFT_CLIENT_REQ_METHOD},
+    {">ru", LFT_CLIENT_REQ_URI},
+    {">rp", LFT_CLIENT_REQ_URLPATH},
+    /*{">rq", LFT_CLIENT_REQ_QUERY},*/
+    {">rv", LFT_CLIENT_REQ_VERSION},
+
+    {"rm", LFT_REQUEST_METHOD},
+    {"ru", LFT_REQUEST_URI},   /* doesn't include the query-string */
+    {"rp", LFT_REQUEST_URLPATH_OLD_31},
+    /* { "rq", LFT_REQUEST_QUERY }, * /     / * the query-string, INCLUDING the leading ? */
+    {">v", LFT_REQUEST_VERSION_OLD_2X},
+    {"rv", LFT_REQUEST_VERSION},
+
+    {"<rm", LFT_SERVER_REQ_METHOD},
+    {"<ru", LFT_SERVER_REQ_URI},
+    {"<rp", LFT_SERVER_REQ_URLPATH},
+    /*{"<rq", LFT_SERVER_REQ_QUERY},*/
+    {"<rv", LFT_SERVER_REQ_VERSION},
+
+    { ">st", LFT_REQUEST_SIZE_TOTAL },
+    /*{ ">sl", LFT_REQUEST_SIZE_LINE }, * / / * the request line "GET ... " */
+    { ">sh", LFT_REQUEST_SIZE_HEADERS },
+    /*{ ">sb", LFT_REQUEST_SIZE_BODY }, */
+    /*{ ">sB", LFT_REQUEST_SIZE_BODY_NO_TE }, */
+
+    {"<st", LFT_REPLY_SIZE_TOTAL},
+    {"<sH", LFT_REPLY_HIGHOFFSET},
+    {"<sS", LFT_REPLY_OBJECTSIZE},
+    /*{ "<sl", LFT_REPLY_SIZE_LINE }, * /   / * the reply line (protocol, code, text) */
+    { "<sh", LFT_REPLY_SIZE_HEADERS },
+    /*{ "<sb", LFT_REPLY_SIZE_BODY }, */
+    /*{ "<sB", LFT_REPLY_SIZE_BODY_NO_TE }, */
+
+    {"et", LFT_TAG},
+    {"st", LFT_IO_SIZE_TOTAL},
+    {"ea", LFT_EXT_LOG},
+    {"sn", LFT_SEQUENCE_NUMBER},
+
+    {"%", LFT_PERCENT},
+
+#if USE_ADAPTATION
+    {"adapt::all_trs", LTF_ADAPTATION_ALL_XACT_TIMES},
+    {"adapt::sum_trs", LTF_ADAPTATION_SUM_XACT_TIMES},
+    {"adapt::<last_h", LFT_ADAPTATION_LAST_HEADER},
+#endif
+
+#if ICAP_CLIENT
+    {"icap::tt", LFT_ICAP_TOTAL_TIME},
+    {"icap::<last_h", LFT_ADAPTATION_LAST_HEADER}, // deprecated
+
+    {"icap::<A",  LFT_ICAP_ADDR},
+    {"icap::<service_name",  LFT_ICAP_SERV_NAME},
+    {"icap::ru",  LFT_ICAP_REQUEST_URI},
+    {"icap::rm",  LFT_ICAP_REQUEST_METHOD},
+    {"icap::>st",  LFT_ICAP_BYTES_SENT},
+    {"icap::<st",  LFT_ICAP_BYTES_READ},
+    {"icap::<bs", LFT_ICAP_BODY_BYTES_READ},
+
+    {"icap::>h",  LFT_ICAP_REQ_HEADER},
+    {"icap::<h",  LFT_ICAP_REP_HEADER},
+
+    {"icap::tr",  LFT_ICAP_TR_RESPONSE_TIME},
+    {"icap::tio",  LFT_ICAP_IO_TIME},
+    {"icap::to",  LFT_ICAP_OUTCOME},
+    {"icap::Hs",  LFT_ICAP_STATUS_CODE},
+#endif
+
+    {NULL, LFT_NONE}           /* this must be last */
+};
+
+/* parses a single token. Returns the token length in characters,
+ * and fills in the lt item with the token information.
+ * def is for sure null-terminated
+ */
+int
+Format::Token::parse(char *def, Quoting *quoting)
+{
+    char *cur = def;
+
+    struct TokenTableEntry *lte;
+    int l;
+
+    l = strcspn(cur, "%");
+
+    if (l > 0) {
+        char *cp;
+        /* it's a string for sure, until \0 or the next % */
+        cp = (char *)xmalloc(l + 1);
+        xstrncpy(cp, cur, l + 1);
+        type = LFT_STRING;
+        data.string = cp;
+
+        while (l > 0) {
+            switch (*cur) {
+
+            case '"':
+
+                if (*quoting == LOG_QUOTE_NONE)
+                    *quoting = LOG_QUOTE_QUOTES;
+                else if (*quoting == LOG_QUOTE_QUOTES)
+                    *quoting = LOG_QUOTE_NONE;
+
+                break;
+
+            case '[':
+                if (*quoting == LOG_QUOTE_NONE)
+                    *quoting = LOG_QUOTE_MIMEBLOB;
+
+                break;
+
+            case ']':
+                if (*quoting == LOG_QUOTE_MIMEBLOB)
+                    *quoting = LOG_QUOTE_NONE;
+
+                break;
+            }
+
+            cur++;
+            l--;
+        }
+
+        goto done;
+    }
+
+    if (!*cur)
+        goto done;
+
+    cur++;
+
+    // select quoting style for his particular token
+    switch (*cur) {
+
+    case '"':
+        quote = LOG_QUOTE_QUOTES;
+        cur++;
+        break;
+
+    case '\'':
+        quote = LOG_QUOTE_RAW;
+        cur++;
+        break;
+
+    case '[':
+        quote = LOG_QUOTE_MIMEBLOB;
+        cur++;
+        break;
+
+    case '#':
+        quote = LOG_QUOTE_URL;
+        cur++;
+        break;
+
+    default:
+        quote = *quoting;
+        break;
+    }
+
+    if (*cur == '-') {
+        left = 1;
+        cur++;
+    }
+
+    if (*cur == '0') {
+        zero = 1;
+        cur++;
+    }
+
+    if (xisdigit(*cur))
+        width = strtol(cur, &cur, 10);
+
+    if (*cur == '.')
+        precision = strtol(cur + 1, &cur, 10);
+
+    if (*cur == '{') {
+        char *cp;
+        cur++;
+        l = strcspn(cur, "}");
+        cp = (char *)xmalloc(l + 1);
+        xstrncpy(cp, cur, l + 1);
+        data.string = cp;
+        cur += l;
+
+        if (*cur == '}')
+            cur++;
+    }
+
+    // For upward compatibility, assume "http::" prefix as default prefix
+    // for all log access formating codes, except those starting
+    // from "icap::", "adapt::" and "%"
+    if (strncmp(cur,"http::", 6) == 0 &&
+            strncmp(cur+6, "icap::", 6) != 0  &&
+            strncmp(cur+6, "adapt::", 12) != 0 && *(cur+6) != '%' ) {
+        cur += 6;
+    }
+
+    type = LFT_NONE;
+
+    for (lte = TokenTable; lte->config != NULL; lte++) {
+        if (strncmp(lte->config, cur, strlen(lte->config)) == 0) {
+            type = lte->token_type;
+            cur += strlen(lte->config);
+            break;
+        }
+    }
+
+    if (type == LFT_NONE) {
+        fatalf("Can't parse configuration token: '%s'\n",
+               def);
+    }
+
+    if (*cur == ' ') {
+        space = 1;
+        cur++;
+    }
+
+done:
+
+    switch (type) {
+
+#if USE_ADAPTATION
+    case LFT_ADAPTATION_LAST_HEADER:
+#endif
+
+#if ICAP_CLIENT
+    case LFT_ICAP_REQ_HEADER:
+
+    case LFT_ICAP_REP_HEADER:
+#endif
+
+    case LFT_ADAPTED_REQUEST_HEADER:
+
+    case LFT_REQUEST_HEADER:
+
+    case LFT_REPLY_HEADER:
+
+        if (data.string) {
+            char *header = data.string;
+            char *cp = strchr(header, ':');
+
+            if (cp) {
+                *cp++ = '\0';
+
+                if (*cp == ',' || *cp == ';' || *cp == ':')
+                    data.header.separator = *cp++;
+                else
+                    data.header.separator = ',';
+
+                data.header.element = cp;
+
+                switch (type) {
+                case LFT_REQUEST_HEADER:
+                    type = LFT_REQUEST_HEADER_ELEM;
+                    break;
+
+                case LFT_ADAPTED_REQUEST_HEADER:
+                    type = LFT_ADAPTED_REQUEST_HEADER_ELEM;
+                    break;
+
+                case LFT_REPLY_HEADER:
+                    type = LFT_REPLY_HEADER_ELEM;
+                    break;
+#if USE_ADAPTATION
+                case LFT_ADAPTATION_LAST_HEADER:
+                    type = LFT_ADAPTATION_LAST_HEADER_ELEM;
+                    break;
+#endif
+#if ICAP_CLIENT
+                case LFT_ICAP_REQ_HEADER:
+                    type = LFT_ICAP_REQ_HEADER_ELEM;
+                    break;
+                case LFT_ICAP_REP_HEADER:
+                    type = LFT_ICAP_REP_HEADER_ELEM;
+                    break;
+#endif
+                default:
+                    break;
+                }
+            }
+
+            data.header.header = header;
+        } else {
+            switch (type) {
+            case LFT_REQUEST_HEADER:
+                type = LFT_REQUEST_ALL_HEADERS;
+                break;
+
+            case LFT_ADAPTED_REQUEST_HEADER:
+                type = LFT_ADAPTED_REQUEST_ALL_HEADERS;
+                break;
+
+            case LFT_REPLY_HEADER:
+                type = LFT_REPLY_ALL_HEADERS;
+                break;
+#if USE_ADAPTATION
+            case LFT_ADAPTATION_LAST_HEADER:
+                type = LFT_ADAPTATION_LAST_ALL_HEADERS;
+                break;
+#endif
+#if ICAP_CLIENT
+            case LFT_ICAP_REQ_HEADER:
+                type = LFT_ICAP_REQ_ALL_HEADERS;
+                break;
+            case LFT_ICAP_REP_HEADER:
+                type = LFT_ICAP_REP_ALL_HEADERS;
+                break;
+#endif
+            default:
+                break;
+            }
+            Config.onoff.log_mime_hdrs = 1;
+        }
+
+        break;
+
+    case LFT_CLIENT_FQDN:
+        Config.onoff.log_fqdn = 1;
+        break;
+
+    case LFT_TIME_SUBSECOND:
+        divisor = 1000;
+
+        if (precision) {
+            int i;
+            divisor = 1000000;
+
+            for (i = precision; i > 1; i--)
+                divisor /= 10;
+
+            if (!divisor)
+                divisor = 0;
+        }
+
+        break;
+
+    case LFT_HTTP_SENT_STATUS_CODE_OLD_30:
+        debugs(46, 0, "WARNING: The \"Hs\" formatting code is deprecated. Use the \">Hs\" instead.");
+        type = LFT_HTTP_SENT_STATUS_CODE;
+        break;
+
+    case LFT_PEER_LOCAL_IP_OLD_27:
+        debugs(46, 0, "WARNING: The \"oa\" formatting code is deprecated. Use the \"<la\" instead.");
+        type = LFT_PEER_LOCAL_IP;
+        break;
+
+    case LFT_REQUEST_URLPATH_OLD_31:
+        debugs(46, 0, "WARNING: The \"rp\" formatting code is deprecated. Use the \">rp\" instead.");
+        type = LFT_CLIENT_REQ_URLPATH;
+        break;
+
+    case LFT_REQUEST_VERSION_OLD_2X:
+        debugs(46, 0, "WARNING: The \">v\" formatting code is deprecated. Use the \">rv\" instead.");
+        type = LFT_REQUEST_VERSION;
+        break;
+
+    default:
+        break;
+    }
+
+    return (cur - def);
+}
+
+Format::Token::~Token()
+{
+    safe_free(data.string);
+    while (next) {
+        Token *tokens = next;
+        next = next->next;
+        tokens->next = NULL;
+        delete tokens;
+    }
+}
+
similarity index 55%
rename from src/log/Tokens.h
rename to src/format/Tokens.h
index 1571550a901e3d672a9d70fda7bfadc399199f50..b37ec9187a519584dbcdd696012783598e03f75f 100644 (file)
@@ -1,45 +1,25 @@
+#ifndef _SQUID_FMT_TOKENS_H
+#define _SQUID_FMT_TOKENS_H
+
 /*
- * $Id$
- *
- * DEBUG: section 46    Access Log
- * AUTHOR: Duane Wessels
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ * Squid configuration allows users to define custom formats in
+ * several components.
+ * - logging
+ * - external ACL input
+ * - deny page URL
  *
+ * These enumerations and classes define the API for parsing of
+ * format directives to define these patterns. Along with output
+ * functionality to produce formatted buffers.
  */
-#ifndef _SQUID_LOG_TOKENS_H
-#define _SQUID_LOG_TOKENS_H
 
-class StoreEntry;
+namespace Format
+{
 
 #define LOG_BUF_SZ (MAX_URL<<2)
 
 /*
- * Bytecodes for the configureable logformat stuff
+ * Bytecodes for the configureable format stuff
  */
 typedef enum {
     LFT_NONE,                  /* dummy */
@@ -182,9 +162,10 @@ typedef enum {
 #endif
 
     LFT_PERCENT                        /* special string cases for escaped chars */
-} logformat_bcode_t;
+} ByteCode_t;
 
-enum log_quote {
+/// Quoting style for a format output.
+enum Quoting {
     LOG_QUOTE_NONE = 0,
     LOG_QUOTE_QUOTES,
     LOG_QUOTE_MIMEBLOB,
@@ -192,11 +173,20 @@ enum log_quote {
     LOG_QUOTE_RAW
 };
 
-/* FIXME: public class so we can pre-define its type. */
-class logformat_token
+// XXX: inherit from linked list
+class Token
 {
 public:
-    logformat_bcode_t type;
+    Token() {};
+    ~Token();
+
+    /** parses a single token. Returns the token length in characters,
+     * and fills in this item with the token information.
+     * def is for sure null-terminated.
+     */
+    int parse(char *def, enum Quoting *quote);
+
+    ByteCode_t type;
     union {
         char *string;
 
@@ -209,56 +199,23 @@ public:
     } data;
     unsigned char width;
     unsigned char precision;
-    enum log_quote quote;
+    enum Quoting quote;
     unsigned int left:1;
     unsigned int space:1;
     unsigned int zero:1;
     int divisor;
-    logformat_token *next;     /* todo: move from linked list to array */
+    Token *next;       /* todo: move from linked list to array */
 };
 
-struct logformat_token_table_entry {
+struct TokenTableEntry {
     const char *config;
-    logformat_bcode_t token_type;
+    ByteCode_t token_type;
     int options;
 };
 
-class logformat
-{
-public:
-    logformat(const char *name);
-    ~logformat();
-
-    char *name;
-    logformat_token *format;
-    logformat *next;
-};
-
 extern const char *log_tags[];
-extern struct logformat_token_table_entry logformat_token_table[];
-
-#if USE_ADAPTATION
-extern bool alLogformatHasAdaptToken;
-#endif
-
-#if ICAP_CLIENT
-extern bool alLogformatHasIcapToken;
-#endif
-
-/* parses a single token. Returns the token length in characters,
- * and fills in the lt item with the token information.
- * def is for sure null-terminated
- */
-int accessLogGetNewLogFormatToken(logformat_token * lt, char *def, enum log_quote *quote);
-
-/* very inefficent parser, but who cares, this needs to be simple */
-/* First off, let's tokenize, we'll optimize in a second pass.
- * A token can either be a %-prefixed sequence (usually a dynamic
- * token but it can be an escaped sequence), or a string. */
-int accessLogParseLogFormat(logformat_token ** fmt, char *def);
-
-void accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definitions);
+extern struct TokenTableEntry TokenTable[];
 
-void accessLogFreeLogFormat(logformat_token ** tokens);
+} // namespace Format
 
-#endif /* _SQUID_LOG_TOKENS_H */
+#endif /* _SQUID_FMT_TOKENS_H */
index 9d385f63844e8e22de716d1f390038176da7de9f..ae56fe7cb268db89433d813429a0d810ccfcc075 100644 (file)
@@ -37,7 +37,7 @@
 #include "comm/Connection.h"
 #include "comm/Write.h"
 #include "helper.h"
-#include "log/Gadgets.h"
+#include "format/Quoting.h"
 #include "MemBuf.h"
 #include "SquidMath.h"
 #include "SquidTime.h"
@@ -507,7 +507,7 @@ helperStats(StoreEntry * sentry, helper * hlp, const char *label)
                           srv->flags.shutdown ? 'S' : ' ',
                           tt < 0.0 ? 0.0 : tt,
                           (int) srv->roffset,
-                          srv->requests[0] ? Log::QuoteMimeBlob(srv->requests[0]->buf) : "(none)");
+                          srv->requests[0] ? Format::QuoteMimeBlob(srv->requests[0]->buf) : "(none)");
     }
 
     storeAppendPrintf(sentry, "\nFlags key:\n\n");
@@ -561,7 +561,7 @@ helperStatefulStats(StoreEntry * sentry, statefulhelper * hlp, const char *label
                           srv->request ? (srv->request->placeholder ? 'P' : ' ') : ' ',
                                   tt < 0.0 ? 0.0 : tt,
                                   (int) srv->roffset,
-                                  srv->request ? Log::QuoteMimeBlob(srv->request->buf) : "(none)");
+                                  srv->request ? Format::QuoteMimeBlob(srv->request->buf) : "(none)");
     }
 
     storeAppendPrintf(sentry, "\nFlags key:\n\n");
index fd9a148eaf4485ad946c16cf48c6ed8b23c0910f..02ba17f2d6f99a23f1e43b824640cecdccfab49a 100644 (file)
@@ -1,6 +1,5 @@
 #include "config.h"
 #include "log/Config.h"
-#include "log/Tokens.h"
 #include "protos.h"
 
 Log::LogConfig Log::TheConfig;
@@ -18,11 +17,11 @@ Log::LogConfig::parseFormats()
         return;
     }
 
-    debugs(3, 2, "Logformat for '" << name << "' is '" << def << "'");
+    debugs(3, 2, "Log Format for '" << name << "' is '" << def << "'");
 
-    logformat *nlf = new logformat(name);
+    ::Format::Format *nlf = new ::Format::Format(name);
 
-    if (!accessLogParseLogFormat(&nlf->format, def)) {
+    if (!nlf->parse(def)) {
         self_destruct();
         return;
     }
index f46d4654d0b721b6ddd96edab69a81b50d8a9500..54176decd5b0dc9eafc204f68977ee8091868123 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SQUID_SRC_LOG_CONFIG_H
 #define SQUID_SRC_LOG_CONFIG_H
 
-#include "log/Tokens.h"
+#include "format/Format.h"
 
 class StoreEntry;
 
@@ -13,14 +13,22 @@ class LogConfig
 public:
     void parseFormats();
     void dumpFormats(StoreEntry *e, const char *name) {
-        accessLogDumpLogFormat(e, name, logformats);
+        logformats->dump(e, name);
     }
 
     /// File path to logging daemon executable
     char *logfile_daemon;
 
     /// Linked list of custom log formats
-    logformat *logformats;
+    ::Format::Format *logformats;
+
+#if USE_ADAPTATION
+    bool hasAdaptToken;
+#endif
+
+#if ICAP_CLIENT
+    bool hasIcapToken;
+#endif
 };
 
 extern LogConfig TheConfig;
index db4638957b94fdfcbdc34e3deeaf62ba6d15e588..32839561263a159ab084aabd9f33f0453b8e4011 100644 (file)
 
 #include "config.h"
 #include "AccessLogEntry.h"
+#include "format/Tokens.h"
+#include "format/Quoting.h"
 #include "HttpRequest.h"
 #include "log/File.h"
 #include "log/Formats.h"
-#include "log/Gadgets.h"
-#include "log/Tokens.h"
 #include "SquidTime.h"
 
 void
@@ -46,9 +46,9 @@ Log::Format::HttpdCombined(AccessLogEntry * al, Logfile * logfile)
 {
     char clientip[MAX_IPSTRLEN];
 
-    const char *user_ident = FormatName(al->cache.rfc931);
+    const char *user_ident = ::Format::QuoteUrlEncodeUsername(al->cache.rfc931);
 
-    const char *user_auth = FormatName(al->cache.authuser);
+    const char *user_auth = ::Format::QuoteUrlEncodeUsername(al->cache.authuser);
 
     const char *referer = al->request->header.getStr(HDR_REFERER);
     if (!referer || *referer == '\0')
@@ -71,7 +71,7 @@ Log::Format::HttpdCombined(AccessLogEntry * al, Logfile * logfile)
                   al->cache.replySize,
                   referer,
                   agent,
-                  log_tags[al->cache.code],
+                  ::Format::log_tags[al->cache.code],
                   al->http.statusSfx(),
                   hier_code_str[al->hier.code],
                   (Config.onoff.log_mime_hdrs?"":"\n"));
@@ -80,8 +80,8 @@ Log::Format::HttpdCombined(AccessLogEntry * al, Logfile * logfile)
     safe_free(user_auth);
 
     if (Config.onoff.log_mime_hdrs) {
-        char *ereq = QuoteMimeBlob(al->headers.request);
-        char *erep = QuoteMimeBlob(al->headers.reply);
+        char *ereq = ::Format::QuoteMimeBlob(al->headers.request);
+        char *erep = ::Format::QuoteMimeBlob(al->headers.reply);
         logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
         safe_free(ereq);
         safe_free(erep);
index 1f8ad8566ff52b03944d92619d63782d78c76fbc..a44d282f1500f559fc87c368f62288dedd3ad63c 100644 (file)
 
 #include "config.h"
 #include "AccessLogEntry.h"
+#include "format/Quoting.h"
+#include "format/Tokens.h"
 #include "log/File.h"
 #include "log/Formats.h"
-#include "log/Gadgets.h"
-#include "log/Tokens.h"
 #include "SquidTime.h"
 
 void
 Log::Format::HttpdCommon(AccessLogEntry * al, Logfile * logfile)
 {
     char clientip[MAX_IPSTRLEN];
-    const char *user_auth = FormatName(al->cache.authuser);
-    const char *user_ident = FormatName(al->cache.rfc931);
+    const char *user_auth = ::Format::QuoteUrlEncodeUsername(al->cache.authuser);
+    const char *user_ident = ::Format::QuoteUrlEncodeUsername(al->cache.rfc931);
 
     logfilePrintf(logfile, "%s %s %s [%s] \"%s %s %s/%d.%d\" %d %"PRId64" %s%s:%s%s",
                   al->cache.caddr.NtoA(clientip,MAX_IPSTRLEN),
@@ -58,7 +58,7 @@ Log::Format::HttpdCommon(AccessLogEntry * al, Logfile * logfile)
                   al->http.version.major, al->http.version.minor,
                   al->http.code,
                   al->cache.replySize,
-                  log_tags[al->cache.code],
+                  ::Format::log_tags[al->cache.code],
                   al->http.statusSfx(),
                   hier_code_str[al->hier.code],
                   (Config.onoff.log_mime_hdrs?"":"\n"));
@@ -67,8 +67,8 @@ Log::Format::HttpdCommon(AccessLogEntry * al, Logfile * logfile)
     safe_free(user_ident);
 
     if (Config.onoff.log_mime_hdrs) {
-        char *ereq = QuoteMimeBlob(al->headers.request);
-        char *erep = QuoteMimeBlob(al->headers.reply);
+        char *ereq = ::Format::QuoteMimeBlob(al->headers.request);
+        char *erep = ::Format::QuoteMimeBlob(al->headers.reply);
         logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
         safe_free(ereq);
         safe_free(erep);
index 4530b33f3fbbcc5e30f8ad820cdf7201d148bc84..bf43fe072046b0ffb6c5032fdafea08a8b2ee505 100644 (file)
 
 #include "config.h"
 #include "AccessLogEntry.h"
-#include "comm/Connection.h"
+#include "format/Tokens.h"
 #include "log/File.h"
 #include "log/Formats.h"
-#include "log/Gadgets.h"
-#include "log/Tokens.h"
-#include "SquidTime.h"
-
 #include "MemBuf.h"
-#include "HttpRequest.h"
-#include "rfc1738.h"
-#include "err_detail_type.h"
-#include "errorpage.h"
-
-static void
-log_quoted_string(const char *str, char *out)
-{
-    char *p = out;
-
-    while (*str) {
-        int l = strcspn(str, "\"\\\r\n\t");
-        memcpy(p, str, l);
-        str += l;
-        p += l;
-
-        switch (*str) {
-
-        case '\0':
-            break;
-
-        case '\r':
-            *p++ = '\\';
-            *p++ = 'r';
-            str++;
-            break;
-
-        case '\n':
-            *p++ = '\\';
-            *p++ = 'n';
-            str++;
-            break;
-
-        case '\t':
-            *p++ = '\\';
-            *p++ = 't';
-            str++;
-            break;
-
-        default:
-            *p++ = '\\';
-            *p++ = *str;
-            str++;
-            break;
-        }
-    }
-
-    *p++ = '\0';
-}
 
 void
 Log::Format::SquidCustom(AccessLogEntry * al, customlog * log)
 {
-    logformat *lf;
-    Logfile *logfile;
-    logformat_token *fmt;
     static MemBuf mb;
-    char tmp[1024];
-    String sb;
-
     mb.reset();
 
-    lf = log->logFormat;
-    logfile = log->logfile;
-
-    for (fmt = lf->format; fmt != NULL; fmt = fmt->next) {     /* for each token */
-        const char *out = NULL;
-        int quote = 0;
-        long int outint = 0;
-        int doint = 0;
-        int dofree = 0;
-        int64_t outoff = 0;
-        int dooff = 0;
-
-        switch (fmt->type) {
-
-        case LFT_NONE:
-            out = "";
-            break;
-
-        case LFT_STRING:
-            out = fmt->data.string;
-            break;
-
-        case LFT_CLIENT_IP_ADDRESS:
-            if (al->cache.caddr.IsNoAddr()) // e.g., ICAP OPTIONS lack client
-                out = "-";
-            else
-                out = al->cache.caddr.NtoA(tmp,1024);
-            break;
-
-        case LFT_CLIENT_FQDN:
-            if (al->cache.caddr.IsAnyAddr()) // e.g., ICAP OPTIONS lack client
-                out = "-";
-            else
-                out = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
-            if (!out) {
-                out = al->cache.caddr.NtoA(tmp,1024);
-            }
-
-            break;
-
-        case LFT_CLIENT_PORT:
-            if (al->request) {
-                outint = al->request->client_addr.GetPort();
-                doint = 1;
-            }
-            break;
-
-#if USE_SQUID_EUI
-        case LFT_CLIENT_EUI:
-            // TODO make the ACL checklist have a direct link to any TCP details.
-            if (al->request && al->request->clientConnectionManager.valid() && al->request->clientConnectionManager->clientConnection != NULL) {
-                if (al->request->clientConnectionManager->clientConnection->remote.IsIPv4())
-                    al->request->clientConnectionManager->clientConnection->remoteEui48.encode(tmp, 1024);
-                else
-                    al->request->clientConnectionManager->clientConnection->remoteEui64.encode(tmp, 1024);
-                out = tmp;
-            }
-            break;
-#endif
-
-            /* case LFT_SERVER_IP_ADDRESS: */
-
-        case LFT_SERVER_IP_OR_PEER_NAME:
-            out = al->hier.host;
-
-            break;
-
-            /* case LFT_SERVER_PORT: */
-
-        case LFT_LOCAL_IP:
-            if (al->request) {
-                out = al->request->my_addr.NtoA(tmp,sizeof(tmp));
-            }
-
-            break;
-
-        case LFT_LOCAL_PORT:
-            if (al->request) {
-                outint = al->request->my_addr.GetPort();
-                doint = 1;
-            }
-
-            break;
-
-            // the fmt->type can not be LFT_PEER_LOCAL_IP_OLD_27
-            // but compiler complains if ommited
-        case LFT_PEER_LOCAL_IP_OLD_27:
-        case LFT_PEER_LOCAL_IP:
-            if (!al->hier.peer_local_addr.IsAnyAddr()) {
-                out = al->hier.peer_local_addr.NtoA(tmp,sizeof(tmp));
-            }
-            break;
-
-        case LFT_PEER_LOCAL_PORT:
-            if ((outint = al->hier.peer_local_addr.GetPort())) {
-                doint = 1;
-            }
-
-            break;
-
-        case LFT_TIME_SECONDS_SINCE_EPOCH:
-            // some platforms store time in 32-bit, some 64-bit...
-            outoff = static_cast<int64_t>(current_time.tv_sec);
-            dooff = 1;
-            break;
-
-        case LFT_TIME_SUBSECOND:
-            outint = current_time.tv_usec / fmt->divisor;
-            doint = 1;
-            break;
-
-
-        case LFT_TIME_LOCALTIME:
-
-        case LFT_TIME_GMT: {
-            const char *spec;
-
-            struct tm *t;
-            spec = fmt->data.timespec;
-
-            if (fmt->type == LFT_TIME_LOCALTIME) {
-                if (!spec)
-                    spec = "%d/%b/%Y:%H:%M:%S %z";
-                t = localtime(&squid_curtime);
-            } else {
-                if (!spec)
-                    spec = "%d/%b/%Y:%H:%M:%S";
-
-                t = gmtime(&squid_curtime);
-            }
-
-            strftime(tmp, sizeof(tmp), spec, t);
-
-            out = tmp;
-        }
-
-        break;
-
-        case LFT_TIME_TO_HANDLE_REQUEST:
-            outint = al->cache.msec;
-            doint = 1;
-            break;
-
-        case LFT_PEER_RESPONSE_TIME:
-            if (al->hier.peer_response_time < 0) {
-                out = "-";
-            } else {
-                outoff = al->hier.peer_response_time;
-                dooff = 1;
-            }
-            break;
-
-        case LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME:
-            if (al->hier.total_response_time < 0) {
-                out = "-";
-            } else {
-                outoff = al->hier.total_response_time;
-                dooff = 1;
-            }
-            break;
-
-        case LFT_DNS_WAIT_TIME:
-            if (al->request && al->request->dnsWait >= 0) {
-                outint = al->request->dnsWait;
-                doint = 1;
-            }
-            break;
-
-        case LFT_REQUEST_HEADER:
-
-            if (al->request)
-                sb = al->request->header.getByName(fmt->data.header.header);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ADAPTED_REQUEST_HEADER:
-
-            if (al->request)
-                sb = al->adapted_request->header.getByName(fmt->data.header.header);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_REPLY_HEADER:
-            if (al->reply)
-                sb = al->reply->header.getByName(fmt->data.header.header);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-#if USE_ADAPTATION
-        case LTF_ADAPTATION_SUM_XACT_TIMES:
-            if (al->request) {
-                Adaptation::History::Pointer ah = al->request->adaptHistory();
-                if (ah != NULL)
-                    ah->sumLogString(fmt->data.string, sb);
-                out = sb.termedBuf();
-            }
-            break;
-
-        case LTF_ADAPTATION_ALL_XACT_TIMES:
-            if (al->request) {
-                Adaptation::History::Pointer ah = al->request->adaptHistory();
-                if (ah != NULL)
-                    ah->allLogString(fmt->data.string, sb);
-                out = sb.termedBuf();
-            }
-            break;
-
-        case LFT_ADAPTATION_LAST_HEADER:
-            if (al->request) {
-                const Adaptation::History::Pointer ah = al->request->adaptHistory();
-                if (ah != NULL) // XXX: add adapt::<all_h but use lastMeta here
-                    sb = ah->allMeta.getByName(fmt->data.header.header);
-            }
-
-            // XXX: here and elsewhere: move such code inside the if guard
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ADAPTATION_LAST_HEADER_ELEM:
-            if (al->request) {
-                const Adaptation::History::Pointer ah = al->request->adaptHistory();
-                if (ah != NULL) // XXX: add adapt::<all_h but use lastMeta here
-                    sb = ah->allMeta.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-            }
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ADAPTATION_LAST_ALL_HEADERS:
-            out = al->adapt.last_meta;
-
-            quote = 1;
-
-            break;
-#endif
-
-#if ICAP_CLIENT
-        case LFT_ICAP_ADDR:
-            if (!out)
-                out = al->icap.hostAddr.NtoA(tmp,1024);
-            break;
-
-        case LFT_ICAP_SERV_NAME:
-            out = al->icap.serviceName.termedBuf();
-            break;
-
-        case LFT_ICAP_REQUEST_URI:
-            out = al->icap.reqUri.termedBuf();
-            break;
-
-        case LFT_ICAP_REQUEST_METHOD:
-            out = Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod);
-            break;
-
-        case LFT_ICAP_BYTES_SENT:
-            outoff = al->icap.bytesSent;
-            dooff = 1;
-            break;
-
-        case LFT_ICAP_BYTES_READ:
-            outoff = al->icap.bytesRead;
-            dooff = 1;
-            break;
-
-        case LFT_ICAP_BODY_BYTES_READ:
-            if (al->icap.bodyBytesRead >= 0) {
-                outoff = al->icap.bodyBytesRead;
-                dooff = 1;
-            }
-            // else if icap.bodyBytesRead < 0, we do not have any http data,
-            // so just print a "-" (204 responses etc)
-            break;
-
-        case LFT_ICAP_REQ_HEADER:
-            if (NULL != al->icap.request) {
-                sb = al->icap.request->header.getByName(fmt->data.header.header);
-                out = sb.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_ICAP_REQ_HEADER_ELEM:
-            if (al->request)
-                sb = al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ICAP_REQ_ALL_HEADERS:
-            if (al->icap.request) {
-                HttpHeaderPos pos = HttpHeaderInitPos;
-                while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
-                    sb.append(e->name);
-                    sb.append(": ");
-                    sb.append(e->value);
-                    sb.append("\r\n");
-                }
-                out = sb.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_ICAP_REP_HEADER:
-            if (NULL != al->icap.reply) {
-                sb = al->icap.reply->header.getByName(fmt->data.header.header);
-                out = sb.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_ICAP_REP_HEADER_ELEM:
-            if (NULL != al->icap.reply)
-                sb = al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ICAP_REP_ALL_HEADERS:
-            if (al->icap.reply) {
-                HttpHeaderPos pos = HttpHeaderInitPos;
-                while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
-                    sb.append(e->name);
-                    sb.append(": ");
-                    sb.append(e->value);
-                    sb.append("\r\n");
-                }
-                out = sb.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_ICAP_TR_RESPONSE_TIME:
-            outint = al->icap.trTime;
-            doint = 1;
-            break;
-
-        case LFT_ICAP_IO_TIME:
-            outint = al->icap.ioTime;
-            doint = 1;
-            break;
-
-        case LFT_ICAP_STATUS_CODE:
-            outint = al->icap.resStatus;
-            doint  = 1;
-            break;
-
-        case LFT_ICAP_OUTCOME:
-            out = al->icap.outcome;
-            break;
-
-        case LFT_ICAP_TOTAL_TIME:
-            outint = al->icap.processingTime;
-            doint = 1;
-            break;
-#endif
-        case LFT_REQUEST_HEADER_ELEM:
-            if (al->request)
-                sb = al->request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ADAPTED_REQUEST_HEADER_ELEM:
-            if (al->adapted_request)
-                sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_REPLY_HEADER_ELEM:
-            if (al->reply)
-                sb = al->reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_REQUEST_ALL_HEADERS:
-            out = al->headers.request;
-
-            quote = 1;
-
-            break;
-
-        case LFT_ADAPTED_REQUEST_ALL_HEADERS:
-            out = al->headers.adapted_request;
-
-            quote = 1;
-
-            break;
-
-        case LFT_REPLY_ALL_HEADERS:
-            out = al->headers.reply;
-
-            quote = 1;
-
-            break;
-
-        case LFT_USER_NAME:
-            out = Log::FormatName(al->cache.authuser);
-
-            if (!out)
-                out = Log::FormatName(al->cache.extuser);
-
-#if USE_SSL
-
-            if (!out)
-                out = Log::FormatName(al->cache.ssluser);
-
-#endif
-
-            if (!out)
-                out = Log::FormatName(al->cache.rfc931);
-
-            dofree = 1;
-
-            break;
-
-        case LFT_USER_LOGIN:
-            out = Log::FormatName(al->cache.authuser);
-
-            dofree = 1;
-
-            break;
-
-        case LFT_USER_IDENT:
-            out = Log::FormatName(al->cache.rfc931);
-
-            dofree = 1;
-
-            break;
-
-        case LFT_USER_EXTERNAL:
-            out = Log::FormatName(al->cache.extuser);
-
-            dofree = 1;
-
-            break;
-
-            /* case LFT_USER_REALM: */
-            /* case LFT_USER_SCHEME: */
-
-            // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
-            // but compiler complains if ommited
-        case LFT_HTTP_SENT_STATUS_CODE_OLD_30:
-        case LFT_HTTP_SENT_STATUS_CODE:
-            outint = al->http.code;
-
-            doint = 1;
-
-            break;
-
-        case LFT_HTTP_RECEIVED_STATUS_CODE:
-            if (al->hier.peer_reply_status == HTTP_STATUS_NONE) {
-                out = "-";
-            } else {
-                outint = al->hier.peer_reply_status;
-                doint = 1;
-            }
-            break;
-            /* case LFT_HTTP_STATUS:
-             *           out = statusline->text;
-             *     quote = 1;
-             *     break;
-             */
-        case LFT_HTTP_BODY_BYTES_READ:
-            if (al->hier.bodyBytesRead >= 0) {
-                outoff = al->hier.bodyBytesRead;
-                dooff = 1;
-            }
-            // else if hier.bodyBytesRead < 0 we did not have any data exchange with
-            // a peer server so just print a "-" (eg requests served from cache,
-            // or internal error messages).
-            break;
-
-        case LFT_SQUID_STATUS:
-            if (al->http.timedout || al->http.aborted) {
-                snprintf(tmp, sizeof(tmp), "%s%s", log_tags[al->cache.code],
-                         al->http.statusSfx());
-                out = tmp;
-            } else {
-                out = log_tags[al->cache.code];
-            }
-
-            break;
-
-        case LFT_SQUID_ERROR:
-            if (al->request && al->request->errType != ERR_NONE)
-                out = errorPageName(al->request->errType);
-            break;
-
-        case LFT_SQUID_ERROR_DETAIL:
-            if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
-                if (al->request->errDetail > ERR_DETAIL_START  &&
-                        al->request->errDetail < ERR_DETAIL_MAX)
-                    out = errorDetailName(al->request->errDetail);
-                else {
-                    if (al->request->errDetail >= ERR_DETAIL_EXCEPTION_START)
-                        snprintf(tmp, sizeof(tmp), "%s=0x%X",
-                                 errorDetailName(al->request->errDetail), (uint32_t) al->request->errDetail);
-                    else
-                        snprintf(tmp, sizeof(tmp), "%s=%d",
-                                 errorDetailName(al->request->errDetail), al->request->errDetail);
-                    out = tmp;
-                }
-            }
-            break;
-
-        case LFT_SQUID_HIERARCHY:
-            if (al->hier.ping.timedout)
-                mb.append("TIMEOUT_", 8);
-
-            out = hier_code_str[al->hier.code];
-
-            break;
-
-        case LFT_MIME_TYPE:
-            out = al->http.content_type;
-
-            break;
-
-        case LFT_CLIENT_REQ_METHOD:
-            if (al->request) {
-                out = al->request->method.image();
-                quote = 1;
-            }
-            break;
-
-        case LFT_CLIENT_REQ_URI:
-            // original client URI
-            if (al->request) {
-                out = urlCanonical(al->request);
-                quote = 1;
-            }
-            break;
-
-        case LFT_REQUEST_URLPATH_OLD_31:
-        case LFT_CLIENT_REQ_URLPATH:
-            if (al->request) {
-                out = al->request->urlpath.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_CLIENT_REQ_VERSION:
-            if (al->request) {
-                snprintf(tmp, sizeof(tmp), "%d.%d", (int) al->request->http_ver.major, (int) al->request->http_ver.minor);
-                out = tmp;
-            }
-            break;
-
-        case LFT_REQUEST_METHOD:
-            out = al->_private.method_str;
-            break;
-
-        case LFT_REQUEST_URI:
-            out = al->url;
-            break;
-
-        case LFT_REQUEST_VERSION_OLD_2X:
-        case LFT_REQUEST_VERSION:
-            snprintf(tmp, sizeof(tmp), "%d.%d", (int) al->http.version.major, (int) al->http.version.minor);
-            out = tmp;
-            break;
-
-        case LFT_SERVER_REQ_METHOD:
-            if (al->adapted_request) {
-                out = al->adapted_request->method.image();
-                quote = 1;
-            }
-            break;
-
-        case LFT_SERVER_REQ_URI:
-            // adapted request URI sent to server/peer
-            if (al->adapted_request) {
-                out = urlCanonical(al->adapted_request);
-                quote = 1;
-            }
-            break;
-
-        case LFT_SERVER_REQ_URLPATH:
-            if (al->adapted_request) {
-                out = al->adapted_request->urlpath.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_SERVER_REQ_VERSION:
-            if (al->adapted_request) {
-                snprintf(tmp, sizeof(tmp), "%d.%d",
-                         (int) al->adapted_request->http_ver.major,
-                         (int) al->adapted_request->http_ver.minor);
-                out = tmp;
-            }
-            break;
-
-        case LFT_REQUEST_SIZE_TOTAL:
-            outoff = al->cache.requestSize;
-            dooff = 1;
-            break;
-
-            /*case LFT_REQUEST_SIZE_LINE: */
-        case LFT_REQUEST_SIZE_HEADERS:
-            outoff = al->cache.requestHeadersSize;
-            dooff =1;
-            break;
-            /*case LFT_REQUEST_SIZE_BODY: */
-            /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
-
-        case LFT_REPLY_SIZE_TOTAL:
-            outoff = al->cache.replySize;
-            dooff = 1;
-            break;
-
-        case LFT_REPLY_HIGHOFFSET:
-            outoff = al->cache.highOffset;
-
-            dooff = 1;
-
-            break;
-
-        case LFT_REPLY_OBJECTSIZE:
-            outoff = al->cache.objectSize;
-
-            dooff = 1;
-
-            break;
-
-            /*case LFT_REPLY_SIZE_LINE: */
-        case LFT_REPLY_SIZE_HEADERS:
-            outint = al->cache.replyHeadersSize;
-            doint = 1;
-            break;
-            /*case LFT_REPLY_SIZE_BODY: */
-            /*case LFT_REPLY_SIZE_BODY_NO_TE: */
-
-        case LFT_TAG:
-            if (al->request)
-                out = al->request->tag.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_IO_SIZE_TOTAL:
-            outint = al->cache.requestSize + al->cache.replySize;
-            doint = 1;
-            break;
-
-        case LFT_EXT_LOG:
-            if (al->request)
-                out = al->request->extacl_log.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_SEQUENCE_NUMBER:
-            outoff = logfile->sequence_number;
-            dooff = 1;
-            break;
-
-        case LFT_PERCENT:
-            out = "%";
-
-            break;
-        }
-
-        if (dooff) {
-            snprintf(tmp, sizeof(tmp), "%0*" PRId64, fmt->zero ? (int) fmt->width : 0, outoff);
-            out = tmp;
-
-        } else if (doint) {
-            snprintf(tmp, sizeof(tmp), "%0*ld", fmt->zero ? (int) fmt->width : 0, outint);
-            out = tmp;
-        }
-
-        if (out && *out) {
-            if (quote || fmt->quote != LOG_QUOTE_NONE) {
-                char *newout = NULL;
-                int newfree = 0;
-
-                switch (fmt->quote) {
-
-                case LOG_QUOTE_NONE:
-                    newout = rfc1738_escape_unescaped(out);
-                    break;
-
-                case LOG_QUOTE_QUOTES: {
-                    size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
-                    if (out_len >= sizeof(tmp)) {
-                        newout = (char *)xmalloc(out_len);
-                        newfree = 1;
-                    } else
-                        newout = tmp;
-                    log_quoted_string(out, newout);
-                }
-                break;
-
-                case LOG_QUOTE_MIMEBLOB:
-                    newout = Log::QuoteMimeBlob(out);
-                    newfree = 1;
-                    break;
-
-                case LOG_QUOTE_URL:
-                    newout = rfc1738_escape(out);
-                    break;
-
-                case LOG_QUOTE_RAW:
-                    break;
-                }
-
-                if (newout) {
-                    if (dofree)
-                        safe_free(out);
-
-                    out = newout;
-
-                    dofree = newfree;
-                }
-            }
-
-            if (fmt->width) {
-                if (fmt->left)
-                    mb.Printf("%-*s", (int) fmt->width, out);
-                else
-                    mb.Printf("%*s", (int) fmt->width, out);
-            } else
-                mb.append(out, strlen(out));
-        } else {
-            mb.append("-", 1);
-        }
-
-        if (fmt->space)
-            mb.append(" ", 1);
-
-        sb.clean();
-
-        if (dofree)
-            safe_free(out);
-    }
+    // XXX: because we do not yet have a neutral form of transaction slab. use AccessLogEntry
+    log->logFormat->assemble(mb, al, log->logfile->sequence_number);
 
-    logfilePrintf(logfile, "%s\n", mb.buf);
+    logfilePrintf(log->logfile, "%s\n", mb.buf);
 }
index 5fccc88f9eb5ee8661df4f5ff14402560af23104..5b41dc32982b38a569959a00cf293cabb59c1e84 100644 (file)
 #if ICAP_CLIENT
 
 #include "AccessLogEntry.h"
+#include "format/Quoting.h"
 #include "HttpRequest.h"
 #include "log/File.h"
 #include "log/Formats.h"
-#include "log/Gadgets.h"
 #include "SquidTime.h"
 
 void
@@ -59,18 +59,18 @@ Log::Format::SquidIcap(AccessLogEntry * al, Logfile * logfile)
             client = al->cache.caddr.NtoA(clientbuf, MAX_IPSTRLEN);
     }
 
-    user = Log::FormatName(al->cache.authuser);
+    user = ::Format::QuoteUrlEncodeUsername(al->cache.authuser);
 
     if (!user)
-        user = Log::FormatName(al->cache.extuser);
+        user = ::Format::QuoteUrlEncodeUsername(al->cache.extuser);
 
 #if USE_SSL
     if (!user)
-        user = Log::FormatName(al->cache.ssluser);
+        user = ::Format::QuoteUrlEncodeUsername(al->cache.ssluser);
 #endif
 
     if (!user)
-        user = Log::FormatName(al->cache.rfc931);
+        user = ::Format::QuoteUrlEncodeUsername(al->cache.rfc931);
 
     if (user && !*user)
         safe_free(user);
index d523c57f73cefa96223516fa78fedfb1b615d5e8..8325eaad5aa90b2dd62238ae1dc1cc5d6034b583 100644 (file)
 
 #include "config.h"
 #include "AccessLogEntry.h"
+#include "format/Quoting.h"
+#include "format/Tokens.h"
 #include "log/File.h"
 #include "log/Formats.h"
-#include "log/Gadgets.h"
-#include "log/Tokens.h"
 #include "SquidTime.h"
 
 void
@@ -46,18 +46,18 @@ Log::Format::SquidNative(AccessLogEntry * al, Logfile * logfile)
     const char *user = NULL;
     char clientip[MAX_IPSTRLEN];
 
-    user = FormatName(al->cache.authuser);
+    user = ::Format::QuoteUrlEncodeUsername(al->cache.authuser);
 
     if (!user)
-        user = FormatName(al->cache.extuser);
+        user = ::Format::QuoteUrlEncodeUsername(al->cache.extuser);
 
 #if USE_SSL
     if (!user)
-        user = FormatName(al->cache.ssluser);
+        user = ::Format::QuoteUrlEncodeUsername(al->cache.ssluser);
 #endif
 
     if (!user)
-        user = FormatName(al->cache.rfc931);
+        user = ::Format::QuoteUrlEncodeUsername(al->cache.rfc931);
 
     if (user && !*user)
         safe_free(user);
@@ -67,7 +67,7 @@ Log::Format::SquidNative(AccessLogEntry * al, Logfile * logfile)
                   (int) current_time.tv_usec / 1000,
                   al->cache.msec,
                   al->cache.caddr.NtoA(clientip, MAX_IPSTRLEN),
-                  log_tags[al->cache.code],
+                  ::Format::log_tags[al->cache.code],
                   al->http.statusSfx(),
                   al->http.code,
                   al->cache.replySize,
@@ -83,8 +83,8 @@ Log::Format::SquidNative(AccessLogEntry * al, Logfile * logfile)
     safe_free(user);
 
     if (Config.onoff.log_mime_hdrs) {
-        char *ereq = QuoteMimeBlob(al->headers.request);
-        char *erep = QuoteMimeBlob(al->headers.reply);
+        char *ereq = ::Format::QuoteMimeBlob(al->headers.request);
+        char *erep = ::Format::QuoteMimeBlob(al->headers.reply);
         logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
         safe_free(ereq);
         safe_free(erep);
index cab6f055809dba18d8e6df7bfeb8d1f48f1ab6b8..48a083b603704ab2a29f5fafcafd69b664b6f146 100644 (file)
@@ -17,8 +17,6 @@ liblog_la_SOURCES = \
        FormatSquidNative.cc \
        FormatSquidReferer.cc \
        FormatSquidUseragent.cc \
-       Gadgets.cc \
-       Gadgets.h \
        ModDaemon.cc \
        ModDaemon.h \
        ModStdio.cc \
@@ -28,7 +26,5 @@ liblog_la_SOURCES = \
        ModTcp.cc \
        ModTcp.h \
        ModUdp.cc \
-       ModUdp.h \
-       Tokens.cc \
-       Tokens.h
+       ModUdp.h
 
diff --git a/src/log/Tokens.cc b/src/log/Tokens.cc
deleted file mode 100644 (file)
index 76c2507..0000000
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * $Id$
- *
- * DEBUG: section 46    Access Log Format Tokens
- * AUTHOR: Duane Wessels
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- */
-
-#include "config.h"
-#include "log/Tokens.h"
-#include "Store.h"
-
-const char *log_tags[] = {
-    "NONE",
-    "TCP_HIT",
-    "TCP_MISS",
-    "TCP_REFRESH_UNMODIFIED",
-    "TCP_REFRESH_FAIL", // same tag logged for LOG_TCP_REFRESH_FAIL_OLD and
-    "TCP_REFRESH_FAIL", // LOG_TCP_REFRESH_FAIL_ERR for backward-compatibility
-    "TCP_REFRESH_MODIFIED",
-    "TCP_CLIENT_REFRESH_MISS",
-    "TCP_IMS_HIT",
-    "TCP_SWAPFAIL_MISS",
-    "TCP_NEGATIVE_HIT",
-    "TCP_MEM_HIT",
-    "TCP_DENIED",
-    "TCP_DENIED_REPLY",
-    "TCP_OFFLINE_HIT",
-#if LOG_TCP_REDIRECTS
-    "TCP_REDIRECT",
-#endif
-    "UDP_HIT",
-    "UDP_MISS",
-    "UDP_DENIED",
-    "UDP_INVALID",
-    "UDP_MISS_NOFETCH",
-    "ICP_QUERY",
-    "LOG_TYPE_MAX"
-};
-
-#if USE_ADAPTATION
-bool alLogformatHasAdaptToken = false;
-#endif
-
-#if ICAP_CLIENT
-bool alLogformatHasIcapToken = false;
-#endif
-
-struct logformat_token_table_entry logformat_token_table[] = {
-
-    {">a", LFT_CLIENT_IP_ADDRESS},
-    {">p", LFT_CLIENT_PORT},
-    {">A", LFT_CLIENT_FQDN},
-#if USE_SQUID_EUI
-    {">eui", LFT_CLIENT_EUI},
-#endif
-
-    /*{ "<a", LFT_SERVER_IP_ADDRESS }, */
-    /*{ "<p", LFT_SERVER_PORT }, */
-    {"<A", LFT_SERVER_IP_OR_PEER_NAME},
-
-    {"la", LFT_LOCAL_IP},
-    {"lp", LFT_LOCAL_PORT},
-    /*{ "lA", LFT_LOCAL_NAME }, */
-
-    {"<la", LFT_PEER_LOCAL_IP},
-    {"oa", LFT_PEER_LOCAL_IP_OLD_27},
-    {"<lp", LFT_PEER_LOCAL_PORT},
-    /* {"ot", LFT_PEER_OUTGOING_TOS}, */
-
-    {"ts", LFT_TIME_SECONDS_SINCE_EPOCH},
-    {"tu", LFT_TIME_SUBSECOND},
-    {"tl", LFT_TIME_LOCALTIME},
-    {"tg", LFT_TIME_GMT},
-    {"tr", LFT_TIME_TO_HANDLE_REQUEST},
-
-    {"<pt", LFT_PEER_RESPONSE_TIME},
-    {"<tt", LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME},
-    {"dt", LFT_DNS_WAIT_TIME},
-
-    {">ha", LFT_ADAPTED_REQUEST_HEADER},
-    {">ha", LFT_ADAPTED_REQUEST_ALL_HEADERS},
-    {">h", LFT_REQUEST_HEADER},
-    {">h", LFT_REQUEST_ALL_HEADERS},
-    {"<h", LFT_REPLY_HEADER},
-    {"<h", LFT_REPLY_ALL_HEADERS},
-
-    {"un", LFT_USER_NAME},
-    {"ul", LFT_USER_LOGIN},
-    /*{ "ur", LFT_USER_REALM }, */
-    /*{ "us", LFT_USER_SCHEME }, */
-    {"ui", LFT_USER_IDENT},
-    {"ue", LFT_USER_EXTERNAL},
-
-    {"Hs", LFT_HTTP_SENT_STATUS_CODE_OLD_30},
-    {">Hs", LFT_HTTP_SENT_STATUS_CODE},
-    {"<Hs", LFT_HTTP_RECEIVED_STATUS_CODE},
-    /*{ "Ht", LFT_HTTP_STATUS }, */
-    {"<bs", LFT_HTTP_BODY_BYTES_READ},
-
-    {"Ss", LFT_SQUID_STATUS},
-    { "err_code", LFT_SQUID_ERROR },
-    { "err_detail", LFT_SQUID_ERROR_DETAIL },
-    {"Sh", LFT_SQUID_HIERARCHY},
-
-    {"mt", LFT_MIME_TYPE},
-
-    {">rm", LFT_CLIENT_REQ_METHOD},
-    {">ru", LFT_CLIENT_REQ_URI},
-    {">rp", LFT_CLIENT_REQ_URLPATH},
-    /*{">rq", LFT_CLIENT_REQ_QUERY},*/
-    {">rv", LFT_CLIENT_REQ_VERSION},
-
-    {"rm", LFT_REQUEST_METHOD},
-    {"ru", LFT_REQUEST_URI},   /* doesn't include the query-string */
-    {"rp", LFT_REQUEST_URLPATH_OLD_31},
-    /* { "rq", LFT_REQUEST_QUERY }, * /     / * the query-string, INCLUDING the leading ? */
-    {">v", LFT_REQUEST_VERSION_OLD_2X},
-    {"rv", LFT_REQUEST_VERSION},
-
-    {"<rm", LFT_SERVER_REQ_METHOD},
-    {"<ru", LFT_SERVER_REQ_URI},
-    {"<rp", LFT_SERVER_REQ_URLPATH},
-    /*{"<rq", LFT_SERVER_REQ_QUERY},*/
-    {"<rv", LFT_SERVER_REQ_VERSION},
-
-    { ">st", LFT_REQUEST_SIZE_TOTAL },
-    /*{ ">sl", LFT_REQUEST_SIZE_LINE }, * / / * the request line "GET ... " */
-    { ">sh", LFT_REQUEST_SIZE_HEADERS },
-    /*{ ">sb", LFT_REQUEST_SIZE_BODY }, */
-    /*{ ">sB", LFT_REQUEST_SIZE_BODY_NO_TE }, */
-
-    {"<st", LFT_REPLY_SIZE_TOTAL},
-    {"<sH", LFT_REPLY_HIGHOFFSET},
-    {"<sS", LFT_REPLY_OBJECTSIZE},
-    /*{ "<sl", LFT_REPLY_SIZE_LINE }, * /   / * the reply line (protocol, code, text) */
-    { "<sh", LFT_REPLY_SIZE_HEADERS },
-    /*{ "<sb", LFT_REPLY_SIZE_BODY }, */
-    /*{ "<sB", LFT_REPLY_SIZE_BODY_NO_TE }, */
-
-    {"et", LFT_TAG},
-    {"st", LFT_IO_SIZE_TOTAL},
-    {"ea", LFT_EXT_LOG},
-    {"sn", LFT_SEQUENCE_NUMBER},
-
-    {"%", LFT_PERCENT},
-
-#if USE_ADAPTATION
-    {"adapt::all_trs", LTF_ADAPTATION_ALL_XACT_TIMES},
-    {"adapt::sum_trs", LTF_ADAPTATION_SUM_XACT_TIMES},
-    {"adapt::<last_h", LFT_ADAPTATION_LAST_HEADER},
-#endif
-
-#if ICAP_CLIENT
-    {"icap::tt", LFT_ICAP_TOTAL_TIME},
-    {"icap::<last_h", LFT_ADAPTATION_LAST_HEADER}, // deprecated
-
-    {"icap::<A",  LFT_ICAP_ADDR},
-    {"icap::<service_name",  LFT_ICAP_SERV_NAME},
-    {"icap::ru",  LFT_ICAP_REQUEST_URI},
-    {"icap::rm",  LFT_ICAP_REQUEST_METHOD},
-    {"icap::>st",  LFT_ICAP_BYTES_SENT},
-    {"icap::<st",  LFT_ICAP_BYTES_READ},
-    {"icap::<bs", LFT_ICAP_BODY_BYTES_READ},
-
-    {"icap::>h",  LFT_ICAP_REQ_HEADER},
-    {"icap::<h",  LFT_ICAP_REP_HEADER},
-
-    {"icap::tr",  LFT_ICAP_TR_RESPONSE_TIME},
-    {"icap::tio",  LFT_ICAP_IO_TIME},
-    {"icap::to",  LFT_ICAP_OUTCOME},
-    {"icap::Hs",  LFT_ICAP_STATUS_CODE},
-#endif
-
-    {NULL, LFT_NONE}           /* this must be last */
-};
-
-/* parses a single token. Returns the token length in characters,
- * and fills in the lt item with the token information.
- * def is for sure null-terminated
- */
-int
-accessLogGetNewLogFormatToken(logformat_token * lt, char *def, enum log_quote *quote)
-{
-    char *cur = def;
-
-    struct logformat_token_table_entry *lte;
-    int l;
-
-    memset(lt, 0, sizeof(*lt));
-    l = strcspn(cur, "%");
-
-    if (l > 0) {
-        char *cp;
-        /* it's a string for sure, until \0 or the next % */
-        cp = (char *)xmalloc(l + 1);
-        xstrncpy(cp, cur, l + 1);
-        lt->type = LFT_STRING;
-        lt->data.string = cp;
-
-        while (l > 0) {
-            switch (*cur) {
-
-            case '"':
-
-                if (*quote == LOG_QUOTE_NONE)
-                    *quote = LOG_QUOTE_QUOTES;
-                else if (*quote == LOG_QUOTE_QUOTES)
-                    *quote = LOG_QUOTE_NONE;
-
-                break;
-
-            case '[':
-                if (*quote == LOG_QUOTE_NONE)
-                    *quote = LOG_QUOTE_MIMEBLOB;
-
-                break;
-
-            case ']':
-                if (*quote == LOG_QUOTE_MIMEBLOB)
-                    *quote = LOG_QUOTE_NONE;
-
-                break;
-            }
-
-            cur++;
-            l--;
-        }
-
-        goto done;
-    }
-
-    if (!*cur)
-        goto done;
-
-    cur++;
-
-    switch (*cur) {
-
-    case '"':
-        lt->quote = LOG_QUOTE_QUOTES;
-        cur++;
-        break;
-
-    case '\'':
-        lt->quote = LOG_QUOTE_RAW;
-        cur++;
-        break;
-
-    case '[':
-        lt->quote = LOG_QUOTE_MIMEBLOB;
-        cur++;
-        break;
-
-    case '#':
-        lt->quote = LOG_QUOTE_URL;
-        cur++;
-        break;
-
-    default:
-        lt->quote = *quote;
-        break;
-    }
-
-    if (*cur == '-') {
-        lt->left = 1;
-        cur++;
-    }
-
-    if (*cur == '0') {
-        lt->zero = 1;
-        cur++;
-    }
-
-    if (xisdigit(*cur))
-        lt->width = strtol(cur, &cur, 10);
-
-    if (*cur == '.')
-        lt->precision = strtol(cur + 1, &cur, 10);
-
-    if (*cur == '{') {
-        char *cp;
-        cur++;
-        l = strcspn(cur, "}");
-        cp = (char *)xmalloc(l + 1);
-        xstrncpy(cp, cur, l + 1);
-        lt->data.string = cp;
-        cur += l;
-
-        if (*cur == '}')
-            cur++;
-    }
-
-    // For upward compatibility, assume "http::" prefix as default prefix
-    // for all log access formating codes, except those starting
-    // from "icap::", "adapt::" and "%"
-    if (strncmp(cur,"http::", 6) == 0 &&
-            strncmp(cur+6, "icap::", 6) != 0  &&
-            strncmp(cur+6, "adapt::", 12) != 0 && *(cur+6) != '%' ) {
-        cur += 6;
-    }
-
-    lt->type = LFT_NONE;
-
-    for (lte = logformat_token_table; lte->config != NULL; lte++) {
-        if (strncmp(lte->config, cur, strlen(lte->config)) == 0) {
-            lt->type = lte->token_type;
-            cur += strlen(lte->config);
-            break;
-        }
-    }
-
-    if (lt->type == LFT_NONE) {
-        fatalf("Can't parse configuration token: '%s'\n",
-               def);
-    }
-
-    if (*cur == ' ') {
-        lt->space = 1;
-        cur++;
-    }
-
-done:
-
-    switch (lt->type) {
-
-#if USE_ADAPTATION
-    case LFT_ADAPTATION_LAST_HEADER:
-#endif
-
-#if ICAP_CLIENT
-    case LFT_ICAP_REQ_HEADER:
-
-    case LFT_ICAP_REP_HEADER:
-#endif
-
-    case LFT_ADAPTED_REQUEST_HEADER:
-
-    case LFT_REQUEST_HEADER:
-
-    case LFT_REPLY_HEADER:
-
-        if (lt->data.string) {
-            char *header = lt->data.string;
-            char *cp = strchr(header, ':');
-
-            if (cp) {
-                *cp++ = '\0';
-
-                if (*cp == ',' || *cp == ';' || *cp == ':')
-                    lt->data.header.separator = *cp++;
-                else
-                    lt->data.header.separator = ',';
-
-                lt->data.header.element = cp;
-
-                switch (lt->type) {
-                case LFT_REQUEST_HEADER:
-                    lt->type = LFT_REQUEST_HEADER_ELEM;
-                    break;
-
-                case LFT_ADAPTED_REQUEST_HEADER:
-                    lt->type = LFT_ADAPTED_REQUEST_HEADER_ELEM;
-                    break;
-
-                case LFT_REPLY_HEADER:
-                    lt->type = LFT_REPLY_HEADER_ELEM;
-                    break;
-#if USE_ADAPTATION
-                case LFT_ADAPTATION_LAST_HEADER:
-                    lt->type = LFT_ADAPTATION_LAST_HEADER_ELEM;
-                    break;
-#endif
-#if ICAP_CLIENT
-                case LFT_ICAP_REQ_HEADER:
-                    lt->type = LFT_ICAP_REQ_HEADER_ELEM;
-                    break;
-                case LFT_ICAP_REP_HEADER:
-                    lt->type = LFT_ICAP_REP_HEADER_ELEM;
-                    break;
-#endif
-                default:
-                    break;
-                }
-            }
-
-            lt->data.header.header = header;
-        } else {
-            switch (lt->type) {
-            case LFT_REQUEST_HEADER:
-                lt->type = LFT_REQUEST_ALL_HEADERS;
-                break;
-
-            case LFT_ADAPTED_REQUEST_HEADER:
-                lt->type = LFT_ADAPTED_REQUEST_ALL_HEADERS;
-                break;
-
-            case LFT_REPLY_HEADER:
-                lt->type = LFT_REPLY_ALL_HEADERS;
-                break;
-#if USE_ADAPTATION
-            case LFT_ADAPTATION_LAST_HEADER:
-                lt->type = LFT_ADAPTATION_LAST_ALL_HEADERS;
-                break;
-#endif
-#if ICAP_CLIENT
-            case LFT_ICAP_REQ_HEADER:
-                lt->type = LFT_ICAP_REQ_ALL_HEADERS;
-                break;
-            case LFT_ICAP_REP_HEADER:
-                lt->type = LFT_ICAP_REP_ALL_HEADERS;
-                break;
-#endif
-            default:
-                break;
-            }
-            Config.onoff.log_mime_hdrs = 1;
-        }
-
-        break;
-
-    case LFT_CLIENT_FQDN:
-        Config.onoff.log_fqdn = 1;
-        break;
-
-    case LFT_TIME_SUBSECOND:
-        lt->divisor = 1000;
-
-        if (lt->precision) {
-            int i;
-            lt->divisor = 1000000;
-
-            for (i = lt->precision; i > 1; i--)
-                lt->divisor /= 10;
-
-            if (!lt->divisor)
-                lt->divisor = 0;
-        }
-
-        break;
-
-    case LFT_HTTP_SENT_STATUS_CODE_OLD_30:
-        debugs(46, 0, "WARNING: The \"Hs\" formatting code is deprecated. Use the \">Hs\" instead.");
-        lt->type = LFT_HTTP_SENT_STATUS_CODE;
-        break;
-
-    case LFT_PEER_LOCAL_IP_OLD_27:
-        debugs(46, 0, "WARNING: The \"oa\" formatting code is deprecated. Use the \"<la\" instead.");
-        lt->type = LFT_PEER_LOCAL_IP;
-        break;
-
-    case LFT_REQUEST_URLPATH_OLD_31:
-        debugs(46, 0, "WARNING: The \"rp\" formatting code is deprecated. Use the \">rp\" instead.");
-        lt->type = LFT_CLIENT_REQ_URLPATH;
-        break;
-
-    case LFT_REQUEST_VERSION_OLD_2X:
-        debugs(46, 0, "WARNING: The \">v\" formatting code is deprecated. Use the \">rv\" instead.");
-        lt->type = LFT_REQUEST_VERSION;
-        break;
-
-    default:
-        break;
-    }
-
-    return (cur - def);
-}
-
-int
-accessLogParseLogFormat(logformat_token ** fmt, char *def)
-{
-    char *cur, *eos;
-    logformat_token *new_lt, *last_lt;
-    enum log_quote quote = LOG_QUOTE_NONE;
-
-    debugs(46, 2, "accessLogParseLogFormat: got definition '" << def << "'");
-
-    /* very inefficent parser, but who cares, this needs to be simple */
-    /* First off, let's tokenize, we'll optimize in a second pass.
-     * A token can either be a %-prefixed sequence (usually a dynamic
-     * token but it can be an escaped sequence), or a string. */
-    cur = def;
-    eos = def + strlen(def);
-    *fmt = new_lt = last_lt = (logformat_token *)xmalloc(sizeof(logformat_token));
-    cur += accessLogGetNewLogFormatToken(new_lt, cur, &quote);
-
-    while (cur < eos) {
-        new_lt = (logformat_token *)xmalloc(sizeof(logformat_token));
-        last_lt->next = new_lt;
-        last_lt = new_lt;
-        cur += accessLogGetNewLogFormatToken(new_lt, cur, &quote);
-    }
-
-    return 1;
-}
-
-void
-accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definitions)
-{
-    logformat_token *t;
-    logformat *format;
-
-    struct logformat_token_table_entry *te;
-    debugs(46, 4, "accessLogDumpLogFormat called");
-
-    for (format = definitions; format; format = format->next) {
-        debugs(46, 3, "Dumping logformat definition for " << format->name);
-        storeAppendPrintf(entry, "logformat %s ", format->name);
-
-        for (t = format->format; t; t = t->next) {
-            if (t->type == LFT_STRING)
-                storeAppendPrintf(entry, "%s", t->data.string);
-            else {
-                char argbuf[256];
-                char *arg = NULL;
-                logformat_bcode_t type = t->type;
-
-                switch (type) {
-                    /* special cases */
-
-                case LFT_STRING:
-                    break;
-#if USE_ADAPTATION
-                case LFT_ADAPTATION_LAST_HEADER_ELEM:
-#endif
-#if ICAP_CLIENT
-                case LFT_ICAP_REQ_HEADER_ELEM:
-                case LFT_ICAP_REP_HEADER_ELEM:
-#endif
-                case LFT_REQUEST_HEADER_ELEM:
-                case LFT_ADAPTED_REQUEST_HEADER_ELEM:
-                case LFT_REPLY_HEADER_ELEM:
-
-                    if (t->data.header.separator != ',')
-                        snprintf(argbuf, sizeof(argbuf), "%s:%c%s", t->data.header.header, t->data.header.separator, t->data.header.element);
-                    else
-                        snprintf(argbuf, sizeof(argbuf), "%s:%s", t->data.header.header, t->data.header.element);
-
-                    arg = argbuf;
-
-                    switch (type) {
-                    case LFT_REQUEST_HEADER_ELEM:
-                        type = LFT_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
-                        break;
-                    case LFT_ADAPTED_REQUEST_HEADER_ELEM:
-                        type = LFT_ADAPTED_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
-                        break;
-                    case LFT_REPLY_HEADER_ELEM:
-                        type = LFT_REPLY_HEADER_ELEM; // XXX: remove _ELEM?
-                        break;
-#if USE_ADAPTATION
-                    case LFT_ADAPTATION_LAST_HEADER_ELEM:
-                        type = LFT_ADAPTATION_LAST_HEADER;
-                        break;
-#endif
-#if ICAP_CLIENT
-                    case LFT_ICAP_REQ_HEADER_ELEM:
-                        type = LFT_ICAP_REQ_HEADER;
-                        break;
-                    case LFT_ICAP_REP_HEADER_ELEM:
-                        type = LFT_ICAP_REP_HEADER;
-                        break;
-#endif
-                    default:
-                        break;
-                    }
-
-                    break;
-
-                case LFT_REQUEST_ALL_HEADERS:
-                case LFT_ADAPTED_REQUEST_ALL_HEADERS:
-                case LFT_REPLY_ALL_HEADERS:
-
-#if USE_ADAPTATION
-                case LFT_ADAPTATION_LAST_ALL_HEADERS:
-#endif
-#if ICAP_CLIENT
-                case LFT_ICAP_REQ_ALL_HEADERS:
-                case LFT_ICAP_REP_ALL_HEADERS:
-#endif
-
-                    switch (type) {
-                    case LFT_REQUEST_ALL_HEADERS:
-                        type = LFT_REQUEST_HEADER;
-                        break;
-                    case LFT_ADAPTED_REQUEST_ALL_HEADERS:
-                        type = LFT_ADAPTED_REQUEST_HEADER;
-                        break;
-                    case LFT_REPLY_ALL_HEADERS:
-                        type = LFT_REPLY_HEADER;
-                        break;
-#if USE_ADAPTATION
-                    case LFT_ADAPTATION_LAST_ALL_HEADERS:
-                        type = LFT_ADAPTATION_LAST_HEADER;
-                        break;
-#endif
-#if ICAP_CLIENT
-                    case LFT_ICAP_REQ_ALL_HEADERS:
-                        type = LFT_ICAP_REQ_HEADER;
-                        break;
-                    case LFT_ICAP_REP_ALL_HEADERS:
-                        type = LFT_ICAP_REP_HEADER;
-                        break;
-#endif
-                    default:
-                        break;
-                    }
-
-                    break;
-
-                default:
-                    if (t->data.string)
-                        arg = t->data.string;
-
-                    break;
-                }
-
-                entry->append("%", 1);
-
-                switch (t->quote) {
-
-                case LOG_QUOTE_QUOTES:
-                    entry->append("\"", 1);
-                    break;
-
-                case LOG_QUOTE_MIMEBLOB:
-                    entry->append("[", 1);
-                    break;
-
-                case LOG_QUOTE_URL:
-                    entry->append("#", 1);
-                    break;
-
-                case LOG_QUOTE_RAW:
-                    entry->append("'", 1);
-                    break;
-
-                case LOG_QUOTE_NONE:
-                    break;
-                }
-
-                if (t->left)
-                    entry->append("-", 1);
-
-                if (t->zero)
-                    entry->append("0", 1);
-
-                if (t->width)
-                    storeAppendPrintf(entry, "%d", (int) t->width);
-
-                if (t->precision)
-                    storeAppendPrintf(entry, ".%d", (int) t->precision);
-
-                if (arg)
-                    storeAppendPrintf(entry, "{%s}", arg);
-
-                for (te = logformat_token_table; te->config != NULL; te++) {
-                    if (te->token_type == type) {
-                        storeAppendPrintf(entry, "%s", te->config);
-                        break;
-                    }
-                }
-
-                if (t->space)
-                    entry->append(" ", 1);
-
-                assert(te->config != NULL);
-            }
-        }
-
-        entry->append("\n", 1);
-    }
-
-}
-
-void
-accessLogFreeLogFormat(logformat_token ** tokens)
-{
-    while (*tokens) {
-        logformat_token *token = *tokens;
-        *tokens = token->next;
-        safe_free(token->data.string);
-        xfree(token);
-    }
-}
-
-logformat::logformat(const char *n) :
-        format(NULL),
-        next(NULL)
-{
-    name = xstrdup(n);
-}
-
-logformat::~logformat()
-{
-    // erase the list without consuming stack space
-    while (next) {
-        // unlink the next entry for deletion
-        logformat *temp = next;
-        next = temp->next;
-        temp->next = NULL;
-        delete temp;
-    }
-
-    // remove locals
-    xfree(name);
-    accessLogFreeLogFormat(&format);
-}
index e2f75ddffb5c225c628fa07094f6fc31913e7e2d..a1160e1fb5a6e563891914c71e4803de15ad92a7 100644 (file)
 #include "eui/Eui48.h"
 #include "eui/Eui64.h"
 #endif
+#include "format/Tokens.h"
 #include "hier_code.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
+#include "log/Config.h"
 #include "log/File.h"
 #include "log/Formats.h"
-#include "log/Gadgets.h"
-#include "log/Tokens.h"
 #include "MemBuf.h"
 #include "mgr/Registration.h"
 #include "rfc1738.h"
@@ -297,10 +297,10 @@ accessLogInit(void)
     accessLogRegisterWithCacheManager();
 
 #if USE_ADAPTATION
-    alLogformatHasAdaptToken = false;
+    Log::TheConfig.hasAdaptToken = false;
 #endif
 #if ICAP_CLIENT
-    alLogformatHasIcapToken = false;
+    Log::TheConfig.hasIcapToken = false;
 #endif
 
     for (log = Config.Log.accesslogs; log; log = log->next) {
@@ -312,17 +312,17 @@ accessLogInit(void)
         LogfileStatus = LOG_ENABLE;
 
 #if USE_ADAPTATION
-        for (logformat_token * curr_token = (log->logFormat?log->logFormat->format:NULL); curr_token; curr_token = curr_token->next) {
-            if (curr_token->type == LTF_ADAPTATION_SUM_XACT_TIMES ||
-                    curr_token->type == LTF_ADAPTATION_ALL_XACT_TIMES ||
-                    curr_token->type == LFT_ADAPTATION_LAST_HEADER ||
-                    curr_token->type == LFT_ADAPTATION_LAST_HEADER_ELEM ||
-                    curr_token->type == LFT_ADAPTATION_LAST_ALL_HEADERS) {
-                alLogformatHasAdaptToken = true;
+        for (Format::Token * curr_token = (log->logFormat?log->logFormat->format:NULL); curr_token; curr_token = curr_token->next) {
+            if (curr_token->type == Format::LTF_ADAPTATION_SUM_XACT_TIMES ||
+                    curr_token->type == Format::LTF_ADAPTATION_ALL_XACT_TIMES ||
+                    curr_token->type == Format::LFT_ADAPTATION_LAST_HEADER ||
+                    curr_token->type == Format::LFT_ADAPTATION_LAST_HEADER_ELEM ||
+                    curr_token->type == Format::LFT_ADAPTATION_LAST_ALL_HEADERS) {
+                Log::TheConfig.hasAdaptToken = true;
             }
 #if ICAP_CLIENT
-            if (curr_token->type == LFT_ICAP_TOTAL_TIME) {
-                alLogformatHasIcapToken = true;
+            if (curr_token->type == Format::LFT_ICAP_TOTAL_TIME) {
+                Log::TheConfig.hasIcapToken = true;
             }
 #endif
         }
index f49f936f84f1f30dd85e28640c089c911aebb80f..206d049f93ad4c10abee7feef79be5db67454792 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "squid.h"
 #include "event.h"
+#include "format/Tokens.h"
 #include "StoreClient.h"
 #if USE_AUTH
 #include "auth/UserRequest.h"
@@ -42,7 +43,6 @@
 #include "mgr/Registration.h"
 #include "Store.h"
 #include "HttpRequest.h"
-#include "log/Tokens.h"
 #include "MemObject.h"
 #include "fde.h"
 #include "mem_node.h"
@@ -2038,7 +2038,7 @@ statClientRequests(StoreEntry * s)
         }
 
         storeAppendPrintf(s, "uri %s\n", http->uri);
-        storeAppendPrintf(s, "logType %s\n", log_tags[http->logType]);
+        storeAppendPrintf(s, "logType %s\n", Format::log_tags[http->logType]);
         storeAppendPrintf(s, "out.offset %ld, out.size %lu\n",
                           (long int) http->out.offset, (unsigned long int) http->out.size);
         storeAppendPrintf(s, "req_sz %ld\n", (long int) http->req_sz);
index 56bbcec8c2343f78753db0f0fbc3c414d3c92ad3..c68c377162df6fb727eab0ce34ec6a583520196d 100644 (file)
@@ -33,9 +33,9 @@
  */
 
 #include "squid.h"
+#include "format/Tokens.h"
 #include "HttpReply.h"
 #include "log/File.h"
-#include "log/Tokens.h"
 #include "MemObject.h"
 #include "mgr/Registration.h"
 #include "Store.h"
index 8598d080567b122cd78d0efed4357adc319f0424..69d1a7ab0b0b1c743e527d44d7148b787837407a 100644 (file)
@@ -1289,13 +1289,13 @@ struct _store_rebuild_data {
 };
 
 class Logfile;
-class logformat;
 
+#include "format/Format.h"
 #include "log/Formats.h"
 struct _customlog {
     char *filename;
     ACLList *aclList;
-    logformat *logFormat;
+    Format::Format *logFormat;
     Logfile *logfile;
     customlog *next;
     Log::Format::log_type type;