=== modified file 'configure.in'
--- configure.in 2010-11-27 06:44:33 +0000
+++ configure.in 2010-11-28 11:19:02 +0000
@@ -932,28 +932,6 @@
dnl ])
-AC_ARG_ENABLE(useragent-log,
- AS_HELP_STRING([--enable-useragent-log],
- [Enable logging of User-Agent header]), [
-SQUID_YESNO([$enableval],
- [unrecognized argument to --enable-useragent-log: $enableval])
- enable_useragent_log=$enableval
-])
-SQUID_DEFINE_BOOL(USE_USERAGENT_LOG,${enable_useragent_log:=no},
- [If you want to log User-Agent request header values, define this.])
-AC_MSG_NOTICE([User-Agent logging enabled: $enable_useragent_log])
-
-AC_ARG_ENABLE(referer-log,
- AS_HELP_STRING([--enable-referer-log],[Enable logging of Referer header]), [
-SQUID_YESNO([$enableval],
- [unrecognized argument to --enable-referer-log: $enableval])
-])
-SQUID_DEFINE_BOOL(USE_REFERER_LOG,${enable_referer_log:=no},
- [If you want to log Referer request header values, define this.
- By default, they are written to referer.log in the Squid logdir.
- This feature is deprecated in favour of custom log formats])
-AC_MSG_NOTICE([Referer logging enabled: $enable_referer_log])
-
AC_ARG_ENABLE(wccp,
AS_HELP_STRING([--disable-wccp],[Disable Web Cache Coordination Protocol]), [
SQUID_YESNO([$enableval],[unrecognized argument to --disable-wccp: $enableval])
=== modified file 'doc/debug-sections.txt'
--- doc/debug-sections.txt 2010-10-29 00:12:28 +0000
+++ doc/debug-sections.txt 2010-11-21 04:53:18 +0000
@@ -1,14 +1,10 @@
-section -- CGI Cache Manager
section -- External DISKD process implementation.
-section -- Refcount allocator
section -- Unlink Daemon
-section -- WWW Client
section 00 Announcement Server
section 00 Client Database
section 00 DNS Resolver Daemon
section 00 Debug Routines
-section 00 Hash Tables
section 00 UFS Store Dump Tool
section 01 Main Loop
section 01 Startup and Main Loop
@@ -70,8 +66,6 @@
section 39 Cache Array Routing Protocol
section 39 Peer source hash based selection
section 39 Peer user hash based selection
-section 40 Referer Logging
-section 40 User-Agent Logging
section 41 Event Processing
section 42 ICMP Pinger program
section 43 AIOPS
@@ -79,6 +73,14 @@
section 44 Peer Selection Algorithm
section 45 Callback Data Registry
section 46 Access Log
+section 46 Access Log - Apache combined format
+section 46 Access Log - Apache common format
+section 46 Access Log - Squid Custom format
+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
@@ -88,7 +90,6 @@
section 51 Filedescriptor Functions
section 52 URN Parsing
section 53 AS Number handling
-section 53 Radix Tree data structure implementation
section 54 Interprocess Communication
section 54 Windows Interprocess Communication
section 55 HTTP Header
@@ -99,7 +100,6 @@
section 60 Packer: A uniform interface to store-like modules
section 61 Redirector
section 62 Generic Histogram
-section 63 Low Level Memory Pool Management
section 64 HTTP Range Header
section 65 HTTP Cache Control Header
section 66 HTTP Header Tools
@@ -129,7 +129,6 @@
section 83 SSL accelerator support
section 84 Helper process maintenance
section 85 Client-side Request Routines
-section 86 ESI Expressions
section 86 ESI processing
section 87 Client-side Stream routines.
section 88 Client-side Reply Routines
=== modified file 'doc/release-notes/release-3.2.sgml'
--- doc/release-notes/release-3.2.sgml 2010-11-22 11:19:17 +0000
+++ doc/release-notes/release-3.2.sgml 2010-11-26 06:14:12 +0000
@@ -287,6 +287,8 @@
logging a single cache.log at relatively high debug levels on a high-traffic system. Or one which is
required to store a long period of access.log and needs to conserve disk space.
+
The referer_log and useragent_log directives have been converted to built-in log formats.
+ These logs are now created using an access_log line with the format "referrer" or "useragent".
Client Bandwidth Limits
In mobile environments, Squid may need to limit Squid-to-client bandwidth
@@ -448,6 +450,8 @@
New installs, or installs with no logs configured explicitly will use this module by default.
New tcp module to send each log line as text data to a TCP receiver.
New udp module to send each log line as text data to a UDP receiver.
+
New format referrer to log with the format prevously used by referer_log directive.
+
New format useragent to log with the format prevously used by useragent_log directive.
acl random
New type random . Pseudo-randomly match requests based on a configured probability.
@@ -532,6 +536,12 @@
Removed tags
+ emulate_httpd_log
+ Replaced by common format option on an access_log directive.
+
+ forward_log
+
Obsolete.
+
ftp_list_width
Obsolete.
@@ -541,9 +551,14 @@
log_fqdn
Obsolete. Replaced by automatic detection of the %>A logformat tag.
+ referer_log
+
Replaced by the referrer format option on an access_log directive.
+
url_rewrite_concurrency
Replaced by url_rewrite_children ... concurrency=N option.
+ useragent_log
+
Replaced by the useragent format option on an access_log directive.
@@ -644,6 +659,12 @@
--enable-auth-ntlm-helpers
replaced by --enable-auth-ntlm .
+ --enable-referer-log
+
Obsolete.
+
+ --enable-useragent-log
+
Obsolete.
+
=== modified file 'lib/rfc1123.c'
--- lib/rfc1123.c 2010-11-01 05:44:28 +0000
+++ lib/rfc1123.c 2010-11-20 23:19:50 +0000
@@ -246,48 +246,6 @@
return buf;
}
-const char *
-mkhttpdlogtime(const time_t * t)
-{
- static char buf[128];
-
- struct tm *gmt = gmtime(t);
-
-#if !USE_GMT
- int gmt_min, gmt_hour, gmt_yday, day_offset;
- size_t len;
- struct tm *lt;
- int min_offset;
-
- /* localtime & gmtime may use the same static data */
- gmt_min = gmt->tm_min;
- gmt_hour = gmt->tm_hour;
- gmt_yday = gmt->tm_yday;
-
- lt = localtime(t);
-
- day_offset = lt->tm_yday - gmt_yday;
- /* wrap round on end of year */
- if (day_offset > 1)
- day_offset = -1;
- else if (day_offset < -1)
- day_offset = 1;
-
- min_offset = day_offset * 1440 + (lt->tm_hour - gmt_hour) * 60
- + (lt->tm_min - gmt_min);
-
- len = strftime(buf, 127 - 5, "%d/%b/%Y:%H:%M:%S ", lt);
- snprintf(buf + len, 128 - len, "%+03d%02d",
- (min_offset / 60) % 24,
- min_offset % 60);
-#else /* USE_GMT */
- buf[0] = '\0';
- strftime(buf, 127, "%d/%b/%Y:%H:%M:%S -000", gmt);
-#endif /* USE_GMT */
-
- return buf;
-}
-
#if 0
int
main()
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2010-11-27 06:44:33 +0000
+++ src/Makefile.am 2010-11-28 11:19:02 +0000
@@ -419,7 +419,6 @@
PingData.h \
protos.h \
redirect.cc \
- referer.cc \
refresh.cc \
RemovalPolicy.cc \
RemovalPolicy.h \
@@ -488,7 +487,6 @@
URLScheme.cc \
URLScheme.h \
urn.cc \
- useragent.cc \
wccp.cc \
wccp2.cc \
whois.cc \
@@ -1234,7 +1232,6 @@
peer_sourcehash.cc \
peer_userhash.cc \
redirect.cc \
- referer.cc \
refresh.cc \
RemovalPolicy.cc \
Server.cc \
@@ -1272,7 +1269,6 @@
url.cc \
URLScheme.cc \
urn.cc \
- useragent.cc \
wccp2.cc \
whois.cc \
FadingCounter.cc \
@@ -1439,7 +1435,6 @@
peer_sourcehash.cc \
peer_userhash.cc \
redirect.cc \
- referer.cc \
refresh.cc \
Server.cc \
$(SNMP_SOURCE) \
@@ -1476,7 +1471,6 @@
url.cc \
URLScheme.cc \
urn.cc \
- useragent.cc \
wccp2.cc \
whois.cc \
FadingCounter.cc \
@@ -1602,7 +1596,6 @@
peer_sourcehash.cc \
peer_userhash.cc \
redirect.cc \
- referer.cc \
refresh.cc \
Server.cc \
$(SNMP_SOURCE) \
@@ -1639,7 +1632,6 @@
url.cc \
URLScheme.cc \
urn.cc \
- useragent.cc \
wccp2.cc \
whois.cc \
FadingCounter.cc \
@@ -1755,7 +1747,6 @@
peer_userhash.cc \
pconn.cc \
redirect.cc \
- referer.cc \
refresh.cc \
RemovalPolicy.cc \
Server.cc \
@@ -1795,7 +1786,6 @@
url.cc \
URLScheme.cc \
urn.cc \
- useragent.cc \
wccp2.cc \
whois.cc \
FadingCounter.cc \
@@ -1922,7 +1912,6 @@
peer_sourcehash.cc \
peer_userhash.cc \
redirect.cc \
- referer.cc \
refresh.cc \
RemovalPolicy.cc \
Server.cc \
@@ -1960,7 +1949,6 @@
url.cc \
URLScheme.cc \
urn.cc \
- useragent.cc \
wccp2.cc \
whois.cc \
FadingCounter.cc \
@@ -2340,7 +2328,6 @@
peer_sourcehash.cc \
peer_userhash.cc \
redirect.cc \
- referer.cc \
refresh.cc \
Server.cc \
$(SNMP_SOURCE) \
@@ -2375,7 +2362,6 @@
tunnel.cc \
SwapDir.cc \
urn.cc \
- useragent.cc \
wccp2.cc \
whois.cc \
FadingCounter.cc \
=== modified file 'src/SquidTime.h'
--- src/SquidTime.h 2010-11-21 04:40:05 +0000
+++ src/SquidTime.h 2010-11-21 04:51:17 +0000
@@ -58,4 +58,25 @@
virtual void tick();
};
+namespace Time
+{
+
+/** Display time as a formatted human-readable string.
+ * Time syntax is
+ * "YYYY/MM/DD hh:mm:ss"
+ *
+ * Output is only valid until next call to this function.
+ */
+const char *FormatStrf(time_t t);
+
+/** Display time as a formatted human-readable string.
+ * Time string syntax used is that of Apache httpd.
+ * "DD/MMM/YYYY:hh:mm:ss zzzz"
+ *
+ * Output is only valid until next call to this function.
+ */
+const char *FormatHttpd(time_t t);
+
+} // namespace Time
+
#endif /* SQUID_TIME_H */
=== modified file 'src/StatHist.cc'
--- src/StatHist.cc 2009-01-21 03:47:47 +0000
+++ src/StatHist.cc 2010-11-21 04:51:18 +0000
@@ -58,9 +58,12 @@
* HP-UX and GCC (2.8?) give strange errors when these simple
* functions are static.
*/
+namespace Math
+{
static hbase_f Log;
static hbase_f Exp;
static hbase_f Null;
+};
#endif
/* low level init, higher level functions has less params */
@@ -278,7 +281,7 @@
static
#endif
double
-Log(double x)
+Math::Log(double x)
{
assert((x + 1.0) >= 0.0);
return log(x + 1.0);
@@ -288,7 +291,7 @@
static
#endif
double
-Exp(double x)
+Math::Exp(double x)
{
return exp(x) - 1.0;
}
@@ -296,7 +299,7 @@
void
statHistLogInit(StatHist * H, int capacity, double min, double max)
{
- statHistInit(H, capacity, Log, Exp, min, max);
+ statHistInit(H, capacity, Math::Log, Math::Exp, min, max);
}
/* linear histogram for enums */
@@ -305,7 +308,7 @@
static
#endif
double
-Null(double x)
+Math::Null(double x)
{
return x;
}
@@ -313,7 +316,7 @@
void
statHistEnumInit(StatHist * H, int last_enum)
{
- statHistInit(H, last_enum + 3, Null, Null, (double) -1, (double) (last_enum + 1 + 1));
+ statHistInit(H, last_enum + 3, Math::Null, Math::Null, (double) -1, (double) (last_enum + 1 + 1));
}
void
@@ -327,7 +330,7 @@
void
statHistIntInit(StatHist * H, int n)
{
- statHistInit(H, n, Null, Null, (double) 0, (double) n - 1);
+ statHistInit(H, n, Math::Null, Math::Null, (double) 0, (double) n - 1);
}
void
=== modified file 'src/adaptation/icap/icap_log.cc'
--- src/adaptation/icap/icap_log.cc 2009-11-22 20:37:27 +0000
+++ src/adaptation/icap/icap_log.cc 2010-11-21 04:51:44 +0000
@@ -2,6 +2,7 @@
#include "icap_log.h"
#include "AccessLogEntry.h"
#include "log/File.h"
+#include "log/Formats.h"
int IcapLogfileStatus = LOG_DISABLE;
@@ -11,11 +12,11 @@
customlog *log;
for (log = Config.Log.icaplogs; log; log = log->next) {
- if (log->type == CLF_NONE)
+ if (log->type == Log::Format::CLF_NONE)
continue;
- if (log->type == CLF_AUTO)
- log->type = CLF_ICAP_SQUID;
+ if (log->type == Log::Format::CLF_AUTO)
+ log->type = Log::Format::CLF_ICAP_SQUID;
log->logfile = logfileOpen(log->filename, MAX_URL << 1, 1);
=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc 2010-11-27 06:44:33 +0000
+++ src/cache_cf.cc 2010-11-28 11:19:02 +0000
@@ -132,13 +132,9 @@
static const char *const list_sep = ", \t\n\r";
-static void parse_logformat(logformat ** logformat_definitions);
static void parse_access_log(customlog ** customlog_definitions);
static int check_null_access_log(customlog *customlog_definitions);
-
-static void dump_logformat(StoreEntry * entry, const char *name, logformat * definitions);
static void dump_access_log(StoreEntry * entry, const char *name, customlog * definitions);
-static void free_logformat(logformat ** definitions);
static void free_access_log(customlog ** definitions);
static void update_maxobjsize(void);
@@ -3974,36 +3970,6 @@
}
#include "AccessLogEntry.h"
-/* TODO: split out parsing somehow ...*/
-static void
-parse_logformat(logformat ** logformat_definitions)
-{
- logformat *nlf;
- char *name, *def;
-
- if ((name = strtok(NULL, w_space)) == NULL)
- self_destruct();
-
- if ((def = strtok(NULL, "\r\n")) == NULL) {
- self_destruct();
- return;
- }
-
- debugs(3, 2, "Logformat for '" << name << "' is '" << def << "'");
-
- nlf = (logformat *)xcalloc(1, sizeof(logformat));
-
- nlf->name = xstrdup(name);
-
- if (!accessLogParseLogFormat(&nlf->format, def)) {
- self_destruct();
- return;
- }
-
- nlf->next = *logformat_definitions;
-
- *logformat_definitions = nlf;
-}
static void
parse_access_log(customlog ** logs)
@@ -4020,19 +3986,19 @@
}
if (strcmp(filename, "none") == 0) {
- cl->type = CLF_NONE;
+ cl->type = Log::Format::CLF_NONE;
goto done;
}
if ((logdef_name = strtok(NULL, w_space)) == NULL)
- logdef_name = "auto";
+ logdef_name = "squid";
debugs(3, 9, "Log definition name '" << logdef_name << "' file '" << filename << "'");
cl->filename = xstrdup(filename);
/* look for the definition pointer corresponding to this name */
- lf = Config.Log.logformats;
+ lf = Log::TheConfig.logformats;
while (lf != NULL) {
debugs(3, 9, "Comparing against '" << lf->name << "'");
@@ -4044,18 +4010,25 @@
}
if (lf != NULL) {
- cl->type = CLF_CUSTOM;
+ cl->type = Log::Format::CLF_CUSTOM;
cl->logFormat = lf;
} else if (strcmp(logdef_name, "auto") == 0) {
- cl->type = CLF_AUTO;
+ debugs(0,0, "WARNING: Log format 'auto' no longer exists. Using 'squid' instead.");
+ cl->type = Log::Format::CLF_SQUID;
} else if (strcmp(logdef_name, "squid") == 0) {
- cl->type = CLF_SQUID;
+ cl->type = Log::Format::CLF_SQUID;
} else if (strcmp(logdef_name, "common") == 0) {
- cl->type = CLF_COMMON;
+ cl->type = Log::Format::CLF_COMMON;
+ } else if (strcmp(logdef_name, "combined") == 0) {
+ cl->type = Log::Format::CLF_COMBINED;
#if ICAP_CLIENT
} else if (strcmp(logdef_name, "icap_squid") == 0) {
- cl->type = CLF_ICAP_SQUID;
+ cl->type = Log::Format::CLF_ICAP_SQUID;
#endif
+ } else if (strcmp(logdef_name, "useragent") == 0) {
+ cl->type = Log::Format::CLF_USERAGENT;
+ } else if (strcmp(logdef_name, "referrer") == 0) {
+ cl->type = Log::Format::CLF_REFERER;
} else {
debugs(3, 0, "Log format '" << logdef_name << "' is not defined");
self_destruct();
@@ -4078,12 +4051,6 @@
}
static void
-dump_logformat(StoreEntry * entry, const char *name, logformat * definitions)
-{
- accessLogDumpLogFormat(entry, name, definitions);
-}
-
-static void
dump_access_log(StoreEntry * entry, const char *name, customlog * logs)
{
customlog *log;
@@ -4093,36 +4060,40 @@
switch (log->type) {
- case CLF_CUSTOM:
+ case Log::Format::CLF_CUSTOM:
storeAppendPrintf(entry, "%s %s", log->filename, log->logFormat->name);
break;
- case CLF_NONE:
+ case Log::Format::CLF_NONE:
storeAppendPrintf(entry, "none");
break;
- case CLF_SQUID:
- storeAppendPrintf(entry, "%s squid", log->filename);
- break;
-
- case CLF_COMMON:
- storeAppendPrintf(entry, "%s squid", log->filename);
- break;
+ case Log::Format::CLF_SQUID:
+ storeAppendPrintf(entry, "%s squid", log->filename);
+ break;
+
+ case Log::Format::CLF_COMBINED:
+ storeAppendPrintf(entry, "%s combined", log->filename);
+ break;
+
+ case Log::Format::CLF_COMMON:
+ storeAppendPrintf(entry, "%s common", log->filename);
+ break;
+
#if ICAP_CLIENT
- case CLF_ICAP_SQUID:
+ case Log::Format::CLF_ICAP_SQUID:
storeAppendPrintf(entry, "%s icap_squid", log->filename);
break;
#endif
- case CLF_AUTO:
-
- if (log->aclList)
- storeAppendPrintf(entry, "%s auto", log->filename);
- else
- storeAppendPrintf(entry, "%s", log->filename);
-
- break;
-
- case CLF_UNKNOWN:
+ case Log::Format::CLF_USERAGENT:
+ storeAppendPrintf(entry, "%s useragent", log->filename);
+ break;
+
+ case Log::Format::CLF_REFERER:
+ storeAppendPrintf(entry, "%s referrer", log->filename);
+ break;
+
+ case Log::Format::CLF_UNKNOWN:
break;
}
@@ -4134,18 +4105,6 @@
}
static void
-free_logformat(logformat ** definitions)
-{
- while (*definitions) {
- logformat *format = *definitions;
- *definitions = format->next;
- safe_free(format->name);
- accessLogFreeLogFormat(&format->format);
- xfree(format);
- }
-}
-
-static void
free_access_log(customlog ** definitions)
{
while (*definitions) {
@@ -4153,7 +4112,7 @@
*definitions = log->next;
log->logFormat = NULL;
- log->type = CLF_UNKNOWN;
+ log->type = Log::Format::CLF_UNKNOWN;
if (log->aclList)
aclDestroyAclList(&log->aclList);
=== modified file 'src/cf.data.pre'
--- src/cf.data.pre 2010-11-27 23:15:46 +0000
+++ src/cf.data.pre 2010-11-28 11:19:02 +0000
@@ -2812,7 +2812,7 @@
NAME: logformat
TYPE: logformat
-LOC: Config.Log.logformats
+LOC: Log::TheConfig
DEFAULT: none
DOC_START
Usage:
@@ -2957,10 +2957,18 @@
The default formats available (which do not need re-defining) are:
-logformat squid %ts.%03tu %6tr %>a %Ss/%03>Hs %a %Ss/%03>Hs %h] [%a %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %a %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %h" "%{User-Agent}>h" %Ss:%Sh
+logformat squid %ts.%03tu %6tr %>a %Ss/%03>Hs %a %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %a %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %h" "%{User-Agent}>h" %Ss:%Sh
+logformat referrer %ts.%03tu %>a %{Referer}>h %ru
+logformat useragent %>a [%tl] "%{User-Agent}>h"
+
+ When the log_mime_hdrs directive is set to ON. The squid, common and combined
+ formats have a safely encoded copy of the mime headers appended to each line
+ within a pair of brackets.
+
+ The common and combined formats are not quite true to the Apache definition.
+ The logs from Squid contain an extra status and hierarchy code appended.
DOC_END
NAME: access_log cache_access_log
@@ -3221,16 +3229,9 @@
DOC_END
NAME: emulate_httpd_log
-COMMENT: on|off
-TYPE: onoff
-DEFAULT: off
-LOC: Config.onoff.common_log
+TYPE: obsolete
DOC_START
- The Cache can emulate the log file format which many 'httpd'
- programs use. To disable/enable this emulation, set
- emulate_httpd_log to 'off' or 'on'. The default
- is to use the native log format since it includes useful
- information Squid-specific log analyzers use.
+ Replace this with an access_log directive using the format 'common' or 'combined'.
DOC_END
NAME: log_ip_on_direct
@@ -3268,27 +3269,15 @@
DOC_END
NAME: useragent_log
-TYPE: string
-LOC: Config.Log.useragent
-DEFAULT: none
-IFDEF: USE_USERAGENT_LOG
+TYPE: obsolete
DOC_START
- Squid will write the User-Agent field from HTTP requests
- to the filename specified here. By default useragent_log
- is disabled.
+ Replace this with an access_log directive using the format 'useragent'.
DOC_END
NAME: referer_log referrer_log
-TYPE: string
-LOC: Config.Log.referer
-DEFAULT: none
-IFDEF: USE_REFERER_LOG
+TYPE: obsolete
DOC_START
- Squid will write the Referer field from HTTP requests to the
- filename specified here. By default referer_log is disabled.
- Note that "referer" is actually a misspelling of "referrer"
- however the misspelt version has been accepted into the HTTP RFCs
- and we accept both.
+ Replace this with an access_log directive using the format 'referrer'.
DOC_END
NAME: pid_filename
@@ -3317,14 +3306,9 @@
DOC_END
NAME: forward_log
-IFDEF: WIP_FWD_LOG
-TYPE: string
-DEFAULT: none
-LOC: Config.Log.forward
+TYPE: obsolete
DOC_START
- Logs the server-side requests.
-
- This is currently work in progress.
+ Use a regular access.log with ACL limiting it to MISS events.
DOC_END
NAME: strip_query_terms
=== modified file 'src/cf_gen_defines'
--- src/cf_gen_defines 2010-11-27 06:44:33 +0000
+++ src/cf_gen_defines 2010-11-28 11:19:02 +0000
@@ -23,11 +23,9 @@
define["USE_ICMP"]="--enable-icmp"
define["USE_IDENT"]="--enable-ident-lookups"
define["USE_LOADABLE_MODULES"]="--enable-loadable-modules"
- define["USE_REFERER_LOG"]="--enable-referer-log"
define["USE_SQUID_ESI"]="--enable-esi"
define["USE_SSL"]="--enable-ssl"
define["USE_UNLINKD"]="--enable-unlinkd"
- define["USE_USERAGENT_LOG"]="--enable-useragent-log"
define["USE_WCCP"]="--enable-wccp"
define["USE_WCCPv2"]="--enable-wccpv2"
define["USE_QOS_TOS"]="--enable-zph-qos"
=== modified file 'src/client_side_request.cc'
--- src/client_side_request.cc 2010-11-27 01:46:22 +0000
+++ src/client_side_request.cc 2010-11-28 11:19:02 +0000
@@ -951,21 +951,6 @@
s.clean();
}
- /**
- \todo --enable-useragent-log and --enable-referer-log. We should
- probably drop those two as the custom log formats accomplish pretty much the same thing..
- */
-#if USE_USERAGENT_LOG
- if ((str = req_hdr->getStr(HDR_USER_AGENT)))
- logUserAgent(fqdnFromAddr(http->getConn()->log_addr), str);
-
-#endif
-#if USE_REFERER_LOG
-
- if ((str = req_hdr->getStr(HDR_REFERER)))
- logReferer(fqdnFromAddr(http->getConn()->log_addr), str, http->log_uri);
-
-#endif
#if USE_FORW_VIA_DB
if (req_hdr->has(HDR_X_FORWARDED_FOR)) {
=== modified file 'src/enums.h'
--- src/enums.h 2010-10-04 15:32:20 +0000
+++ src/enums.h 2010-11-21 04:52:05 +0000
@@ -342,20 +342,7 @@
_WIN_OS_WINLON,
_WIN_OS_WIN7
};
-
-#endif
-
-typedef enum {
- CLF_UNKNOWN,
- CLF_AUTO,
- CLF_CUSTOM,
- CLF_SQUID,
- CLF_COMMON,
-#if ICAP_CLIENT
- CLF_ICAP_SQUID,
-#endif
- CLF_NONE
-} customlog_type;
+#endif
enum {
DISABLE_PMTU_OFF,
=== modified file 'src/errorpage.cc'
--- src/errorpage.cc 2010-11-27 01:46:22 +0000
+++ src/errorpage.cc 2010-11-28 11:19:02 +0000
@@ -804,7 +804,7 @@
break;
case 't':
- mb.Printf("%s", mkhttpdlogtime(&squid_curtime));
+ mb.Printf("%s", Time::FormatHttpd(squid_curtime));
break;
case 'T':
=== modified file 'src/forward.cc'
--- src/forward.cc 2010-10-28 18:52:59 +0000
+++ src/forward.cc 2010-11-21 04:52:13 +0000
@@ -67,11 +67,6 @@
#define MAX_FWD_STATS_IDX 9
static int FwdReplyCodes[MAX_FWD_STATS_IDX + 1][HTTP_INVALID_HEADER + 1];
-#if WIP_FWD_LOG
-static void fwdLog(FwdState * fwdState);
-static Logfile *logfile = NULL;
-#endif
-
static PconnPool *fwdPconnPool = new PconnPool("server-side");
CBDATA_CLASS_INIT(FwdState);
@@ -136,10 +131,6 @@
entry->mem_obj->checkUrlChecksum();
#endif
-#if WIP_FWD_LOG
-
- log();
-#endif
if (entry->store_status == STORE_PENDING) {
if (entry->isEmpty()) {
@@ -1263,18 +1254,6 @@
FwdState::initModule()
{
memDataInit(MEM_FWD_SERVER, "FwdServer", sizeof(FwdServer), 0);
-
-#if WIP_FWD_LOG
-
- if (logfile)
- (void) 0;
- else if (NULL == Config.Log.forward)
- (void) 0;
- else
- logfile = logfileOpen(Config.Log.forward, 0, 1);
-
-#endif
-
RegisterWithCacheManager();
}
@@ -1469,47 +1448,3 @@
return aclMapNfmark(Ip::Qos::TheConfig.nfmarkToServer, &ch);
}
-
-
-/**** WIP_FWD_LOG *************************************************************/
-
-#if WIP_FWD_LOG
-void
-fwdUninit(void)
-{
- if (NULL == logfile)
- return;
-
- logfileClose(logfile);
-
- logfile = NULL;
-}
-
-void
-fwdLogRotate(void)
-{
- if (logfile)
- logfileRotate(logfile);
-}
-
-static void
-FwdState::log()
-{
- if (NULL == logfile)
- return;
-
- logfilePrintf(logfile, "%9d.%03d %03d %s %s\n",
- (int) current_time.tv_sec,
- (int) current_time.tv_usec / 1000,
- last_status,
- RequestMethodStr(request->method),
- request->canonical);
-}
-
-void
-FwdState::status(http_status s)
-{
- last_status = s;
-}
-
-#endif
=== modified file 'src/forward.h'
--- src/forward.h 2010-10-06 03:50:45 +0000
+++ src/forward.h 2010-11-21 04:52:14 +0000
@@ -81,13 +81,6 @@
ErrorState *makeConnectingError(const err_type type) const;
static void RegisterWithCacheManager(void);
-#if WIP_FWD_LOG
-
- void uninit /**DOCS_NOSEMI*/
- static void logRotate /**DOCS_NOSEMI*/
- void status() /**DOCS_NOSEMI*/
-#endif
-
public:
StoreEntry *entry;
HttpRequest *request;
@@ -102,10 +95,6 @@
time_t start_t;
int n_tries;
int origin_tries;
-#if WIP_FWD_LOG
-
- http_status last_status;
-#endif
struct {
unsigned int dont_retry:1;
=== modified file 'src/helper.cc'
--- src/helper.cc 2010-11-27 01:46:22 +0000
+++ src/helper.cc 2010-11-28 11:19:02 +0000
@@ -35,6 +35,7 @@
#include "squid.h"
#include "comm/Write.h"
#include "helper.h"
+#include "log/Gadgets.h"
#include "SquidMath.h"
#include "SquidTime.h"
#include "Store.h"
@@ -441,7 +442,7 @@
srv->flags.shutdown ? 'S' : ' ',
tt < 0.0 ? 0.0 : tt,
(int) srv->roffset,
- srv->requests[0] ? log_quote(srv->requests[0]->buf) : "(none)");
+ srv->requests[0] ? Log::QuoteMimeBlob(srv->requests[0]->buf) : "(none)");
}
storeAppendPrintf(sentry, "\nFlags key:\n\n");
@@ -495,7 +496,7 @@
srv->request ? (srv->request->placeholder ? 'P' : ' ') : ' ',
tt < 0.0 ? 0.0 : tt,
(int) srv->roffset,
- srv->request ? log_quote(srv->request->buf) : "(none)");
+ srv->request ? Log::QuoteMimeBlob(srv->request->buf) : "(none)");
}
storeAppendPrintf(sentry, "\nFlags key:\n\n");
=== modified file 'src/http.cc'
--- src/http.cc 2010-11-27 06:44:33 +0000
+++ src/http.cc 2010-11-28 11:19:02 +0000
@@ -906,10 +906,6 @@
entry->mem_obj->vary_headers = xstrdup(vary);
}
-#if WIP_FWD_LOG
- fwdStatus(fwd, s);
-
-#endif
/*
* If its not a reply that we will re-forward, then
* allow the client to get it.
=== modified file 'src/log/Config.cc'
--- src/log/Config.cc 2009-11-22 20:37:27 +0000
+++ src/log/Config.cc 2010-11-21 04:52:42 +0000
@@ -1,4 +1,33 @@
#include "config.h"
#include "log/Config.h"
+#include "log/Tokens.h"
+#include "protos.h"
Log::LogConfig Log::TheConfig;
+
+void
+Log::LogConfig::parseFormats()
+{
+ char *name, *def;
+
+ if ((name = strtok(NULL, w_space)) == NULL)
+ self_destruct();
+
+ if ((def = strtok(NULL, "\r\n")) == NULL) {
+ self_destruct();
+ return;
+ }
+
+ debugs(3, 2, "Logformat for '" << name << "' is '" << def << "'");
+
+ logformat *nlf = new logformat(name);
+
+ if (!accessLogParseLogFormat(&nlf->format, def)) {
+ self_destruct();
+ return;
+ }
+
+ // add to global config list
+ nlf->next = logformats;
+ logformats = nlf;
+}
=== modified file 'src/log/Config.h'
--- src/log/Config.h 2010-11-27 01:58:38 +0000
+++ src/log/Config.h 2010-11-28 11:19:02 +0000
@@ -1,17 +1,35 @@
#ifndef SQUID_SRC_LOG_CONFIG_H
#define SQUID_SRC_LOG_CONFIG_H
+#include "log/Tokens.h"
+
+class StoreEntry;
+
namespace Log
{
class LogConfig
{
public:
+ void parseFormats();
+ void dumpFormats(StoreEntry *e, const char *name) {
+ accessLogDumpLogFormat(e, name, logformats);
+ }
+
+ /// File path to logging daemon executable
char *logfile_daemon;
+
+ /// Linked list of custom log formats
+ logformat *logformats;
};
extern LogConfig TheConfig;
} // namespace Log
+// Legacy parsing wrappers
+#define parse_logformat(X) (X)->parseFormats()
+#define free_logformat(X) do{ delete (*X).logformats; (*X).logformats=NULL; }while(false)
+#define dump_logformat(E,N,D) (D).dumpFormats((E),(N))
+
#endif
=== added file 'src/log/FormatHttpdCombined.cc'
--- src/log/FormatHttpdCombined.cc 1970-01-01 00:00:00 +0000
+++ src/log/FormatHttpdCombined.cc 2010-11-21 04:52:42 +0000
@@ -0,0 +1,87 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46 Access Log - Apache combined format
+ * AUTHOR: Amos Jeffries
+ *
+ * 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 "AccessLogEntry.h"
+#include "HttpRequest.h"
+#include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.h"
+#include "SquidTime.h"
+
+void
+Log::Format::HttpdCombined(AccessLogEntry * al, Logfile * logfile)
+{
+ char clientip[MAX_IPSTRLEN];
+
+ const char *user_ident = FormatName(al->cache.rfc931);
+
+ const char *user_auth = FormatName(al->cache.authuser);
+
+ const char *referer = al->request->header.getStr(HDR_REFERER);
+ if (!referer || *referer == '\0')
+ referer = "-";
+
+ const char *agent = al->request->header.getStr(HDR_USER_AGENT);
+ if (!agent || *agent == '\0')
+ agent = "-";
+
+ logfilePrintf(logfile, "%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %"PRId64" \"%s\" \"%s\" %s%s:%s%s",
+ al->cache.caddr.NtoA(clientip,MAX_IPSTRLEN),
+ user_ident ? user_ident : dash_str,
+ user_auth ? user_auth : dash_str,
+ Time::FormatHttpd(squid_curtime),
+ al->_private.method_str,
+ al->url,
+ al->http.version.major, al->http.version.minor,
+ al->http.code,
+ al->cache.replySize,
+ referer,
+ agent,
+ log_tags[al->cache.code],
+ al->http.statusSfx(),
+ hier_code_str[al->hier.code],
+ (Config.onoff.log_mime_hdrs?"":"\n"));
+
+ safe_free(user_ident);
+ safe_free(user_auth);
+
+ if (Config.onoff.log_mime_hdrs) {
+ char *ereq = QuoteMimeBlob(al->headers.request);
+ char *erep = QuoteMimeBlob(al->headers.reply);
+ logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
+ safe_free(ereq);
+ safe_free(erep);
+ }
+}
=== added file 'src/log/FormatHttpdCommon.cc'
--- src/log/FormatHttpdCommon.cc 1970-01-01 00:00:00 +0000
+++ src/log/FormatHttpdCommon.cc 2010-11-21 04:52:42 +0000
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46 Access Log - Apache common format
+ * 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 "AccessLogEntry.h"
+#include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.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);
+
+ logfilePrintf(logfile, "%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %"PRId64" %s%s:%s%s",
+ al->cache.caddr.NtoA(clientip,MAX_IPSTRLEN),
+ user_ident ? user_ident : dash_str,
+ user_auth ? user_auth : dash_str,
+ Time::FormatHttpd(squid_curtime),
+ al->_private.method_str,
+ al->url,
+ al->http.version.major, al->http.version.minor,
+ al->http.code,
+ al->cache.replySize,
+ log_tags[al->cache.code],
+ al->http.statusSfx(),
+ hier_code_str[al->hier.code],
+ (Config.onoff.log_mime_hdrs?"":"\n"));
+
+ safe_free(user_auth);
+ safe_free(user_ident);
+
+ if (Config.onoff.log_mime_hdrs) {
+ char *ereq = QuoteMimeBlob(al->headers.request);
+ char *erep = QuoteMimeBlob(al->headers.reply);
+ logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
+ safe_free(ereq);
+ safe_free(erep);
+ }
+}
=== added file 'src/log/FormatSquidCustom.cc'
--- src/log/FormatSquidCustom.cc 1970-01-01 00:00:00 +0000
+++ src/log/FormatSquidCustom.cc 2010-11-21 08:40:05 +0000
@@ -0,0 +1,817 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46 Access Log - Squid Custom format
+ * 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 "AccessLogEntry.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:
+ if (al->request) {
+ if (al->cache.caddr.IsIPv4())
+ al->request->client_eui48.encode(tmp, 1024);
+ else
+ al->request->client_eui64.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,1024);
+ }
+
+ break;
+
+ case LFT_LOCAL_PORT:
+ if (al->request) {
+ outint = al->request->my_addr.GetPort();
+ doint = 1;
+ }
+
+ break;
+
+ case LFT_PEER_LOCAL_PORT:
+ if (al->hier.peer_local_port) {
+ outint = al->hier.peer_local_port;
+ doint = 1;
+ }
+
+ break;
+
+ case LFT_TIME_SECONDS_SINCE_EPOCH:
+ // some platforms store time in 32-bit, some 64-bit...
+ outoff = static_cast(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;
+#endif
+
+#if ICAP_CLIENT
+ case LFT_ICAP_LAST_MATCHED_HEADER:
+ if (al->request) {
+ Adaptation::Icap::History::Pointer ih = al->request->icapHistory();
+ if (ih != NULL)
+ sb = ih->mergeOfIcapHeaders.getByName(fmt->data.header.header);
+ }
+
+ out = sb.termedBuf();
+
+ quote = 1;
+
+ break;
+
+ case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
+ if (al->request) {
+ Adaptation::Icap::History::Pointer ih = al->request->icapHistory();
+ if (ih != NULL)
+ sb = ih->mergeOfIcapHeaders.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+ }
+
+ out = sb.termedBuf();
+
+ quote = 1;
+
+ break;
+
+ case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
+ out = al->headers.icap;
+
+ quote = 1;
+
+ break;
+
+ 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_REQUEST_METHOD:
+ out = al->_private.method_str;
+
+ break;
+
+ case LFT_REQUEST_URI:
+ out = al->url;
+
+ break;
+
+ case LFT_REQUEST_URLPATH:
+ if (al->request) {
+ out = al->request->urlpath.termedBuf();
+ quote = 1;
+ }
+ break;
+
+ 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_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(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);
+ }
+
+ logfilePrintf(logfile, "%s\n", mb.buf);
+}
=== added file 'src/log/FormatSquidIcap.cc'
--- src/log/FormatSquidIcap.cc 1970-01-01 00:00:00 +0000
+++ src/log/FormatSquidIcap.cc 2010-11-27 11:06:38 +0000
@@ -0,0 +1,91 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46 Access Log - Squid ICAP Logging
+ * AUTHOR: Alex Rousskov
+ *
+ * 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"
+
+#if ICAP_CLIENT
+
+#include "AccessLogEntry.h"
+#include "HttpRequest.h"
+#include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.h"
+#include "SquidTime.h"
+
+void
+Log::Format::SquidIcap(AccessLogEntry * al, Logfile * logfile)
+{
+ const char *client = NULL;
+ const char *user = NULL;
+ char tmp[MAX_IPSTRLEN], clientbuf[MAX_IPSTRLEN];
+
+ if (al->cache.caddr.IsAnyAddr()) { // ICAP OPTIONS xactions lack client
+ client = "-";
+ } else {
+ if (Config.onoff.log_fqdn)
+ client = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
+ if (!client)
+ client = al->cache.caddr.NtoA(clientbuf, MAX_IPSTRLEN);
+ }
+
+ user = Log::FormatName(al->cache.authuser);
+
+ if (!user)
+ user = Log::FormatName(al->cache.extuser);
+
+#if USE_SSL
+ if (!user)
+ user = Log::FormatName(al->cache.ssluser);
+#endif
+
+ if (!user)
+ user = Log::FormatName(al->cache.rfc931);
+
+ if (user && !*user)
+ safe_free(user);
+
+ logfilePrintf(logfile, "%9ld.%03d %6d %s -/%03d %"PRId64" %s %s %s -/%s -\n",
+ (long int) current_time.tv_sec,
+ (int) current_time.tv_usec / 1000,
+ al->icap.trTime,
+ client,
+ al->icap.resStatus,
+ al->icap.bytesRead,
+ Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod),
+ al->icap.reqUri.termedBuf(),
+ user ? user : "-",
+ al->icap.hostAddr.NtoA(tmp, MAX_IPSTRLEN));
+ safe_free(user);
+}
+#endif
=== added file 'src/log/FormatSquidNative.cc'
--- src/log/FormatSquidNative.cc 1970-01-01 00:00:00 +0000
+++ src/log/FormatSquidNative.cc 2010-11-21 04:52:43 +0000
@@ -0,0 +1,91 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46 Access Log - Squid format
+ * 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 "AccessLogEntry.h"
+#include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.h"
+#include "SquidTime.h"
+
+void
+Log::Format::SquidNative(AccessLogEntry * al, Logfile * logfile)
+{
+ const char *user = NULL;
+ char clientip[MAX_IPSTRLEN];
+
+ user = FormatName(al->cache.authuser);
+
+ if (!user)
+ user = FormatName(al->cache.extuser);
+
+#if USE_SSL
+ if (!user)
+ user = FormatName(al->cache.ssluser);
+#endif
+
+ if (!user)
+ user = FormatName(al->cache.rfc931);
+
+ if (user && !*user)
+ safe_free(user);
+
+ logfilePrintf(logfile, "%9ld.%03d %6d %s %s%s/%03d %"PRId64" %s %s %s %s%s/%s %s%s",
+ (long int) current_time.tv_sec,
+ (int) current_time.tv_usec / 1000,
+ al->cache.msec,
+ al->cache.caddr.NtoA(clientip, MAX_IPSTRLEN),
+ log_tags[al->cache.code],
+ al->http.statusSfx(),
+ al->http.code,
+ al->cache.replySize,
+ al->_private.method_str,
+ al->url,
+ user ? user : dash_str,
+ al->hier.ping.timedout ? "TIMEOUT_" : "",
+ hier_code_str[al->hier.code],
+ al->hier.host,
+ al->http.content_type,
+ (Config.onoff.log_mime_hdrs?"":"\n"));
+
+ safe_free(user);
+
+ if (Config.onoff.log_mime_hdrs) {
+ char *ereq = QuoteMimeBlob(al->headers.request);
+ char *erep = QuoteMimeBlob(al->headers.reply);
+ logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
+ safe_free(ereq);
+ safe_free(erep);
+ }
+}
=== renamed file 'src/referer.cc' => 'src/log/FormatSquidReferer.cc'
--- src/referer.cc 2009-11-22 20:37:27 +0000
+++ src/log/FormatSquidReferer.cc 2010-11-21 04:52:43 +0000
@@ -1,9 +1,9 @@
/*
* $Id$
*
- * DEBUG: section 40 Referer Logging
+ * DEBUG: section 46 Access Log - Squid referer format
* AUTHOR: Joe Ramey (useragent)
- * Jens-S. Vöckler (mod 4 referer)
+ * Jens-S. V?ckler (mod 4 referer)
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
@@ -33,71 +33,26 @@
*
*/
-#include "squid.h"
+#include "config.h"
+#include "AccessLogEntry.h"
+#include "HttpRequest.h"
#include "log/File.h"
+#include "log/Formats.h"
#include "SquidTime.h"
-#if USE_REFERER_LOG
-static Logfile *refererlog = NULL;
-#endif
-
-void
-refererOpenLog(void)
-{
-#if USE_REFERER_LOG
- assert(NULL == refererlog);
-
- if (!Config.Log.referer || (0 == strcmp(Config.Log.referer, "none"))) {
- debugs(40, 1, "Referer logging is disabled.");
- return;
- }
-
- refererlog = logfileOpen(Config.Log.referer, 0, 1);
-#endif
-}
-
-void
-refererRotateLog(void)
-{
-#if USE_REFERER_LOG
-
- if (NULL == refererlog)
- return;
-
- logfileRotate(refererlog);
-
-#endif
-}
-
-void
-logReferer(const char *client, const char *referer, const char *uri)
-{
-#if USE_REFERER_LOG
-
- if (NULL == refererlog)
- return;
-
- logfilePrintf(refererlog, "%9d.%03d %s %s %s\n",
- (int) current_time.tv_sec,
+void
+Log::Format::SquidReferer(AccessLogEntry *al, Logfile *logfile)
+{
+ const char *referer = al->request->header.getStr(HDR_REFERER);
+ if (!referer || *referer == '\0')
+ referer = "-";
+
+ char clientip[MAX_IPSTRLEN];
+
+ logfilePrintf(logfile, "%9ld.%03d %s %s %s\n",
+ (long int) current_time.tv_sec,
(int) current_time.tv_usec / 1000,
- client,
+ al->cache.caddr.NtoA(clientip, MAX_IPSTRLEN),
referer,
- uri ? uri : "-");
-
-#endif
-}
-
-void
-refererCloseLog(void)
-{
-#if USE_REFERER_LOG
-
- if (NULL == refererlog)
- return;
-
- logfileClose(refererlog);
-
- refererlog = NULL;
-
-#endif
+ al->url ? al->url : "-");
}
=== renamed file 'src/useragent.cc' => 'src/log/FormatSquidUseragent.cc'
--- src/useragent.cc 2009-11-22 20:37:27 +0000
+++ src/log/FormatSquidUseragent.cc 2010-11-21 04:52:43 +0000
@@ -1,8 +1,9 @@
/*
* $Id$
*
- * DEBUG: section 40 User-Agent Logging
+ * DEBUG: section 46 Access Log - Squid useragent format
* AUTHOR: Joe Ramey
+ * AUTHOR: Amos Jeffries
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
@@ -32,77 +33,24 @@
*
*/
-#include "squid.h"
+#include "config.h"
+#include "AccessLogEntry.h"
+#include "HttpRequest.h"
#include "log/File.h"
+#include "log/Formats.h"
#include "SquidTime.h"
-#if USE_USERAGENT_LOG
-static Logfile *useragentlog = NULL;
-#endif
-
-void
-useragentOpenLog(void)
-{
-#if USE_USERAGENT_LOG
- assert(NULL == useragentlog);
-
- if (!Config.Log.useragent || (0 == strcmp(Config.Log.useragent, "none"))) {
- debugs(40, 1, "User-Agent logging is disabled.");
- return;
- }
-
- useragentlog = logfileOpen(Config.Log.useragent, 0, 1);
-#endif
-}
-
-void
-useragentRotateLog(void)
-{
-#if USE_USERAGENT_LOG
-
- if (NULL == useragentlog)
- return;
-
- logfileRotate(useragentlog);
-
-#endif
-}
-
-void
-logUserAgent(const char *client, const char *agent)
-{
-#if USE_USERAGENT_LOG
- static time_t last_time = 0;
- static char time_str[128];
- const char *s;
-
- if (NULL == useragentlog)
- return;
-
- if (squid_curtime != last_time) {
- s = mkhttpdlogtime(&squid_curtime);
- strcpy(time_str, s);
- last_time = squid_curtime;
- }
-
- logfilePrintf(useragentlog, "%s [%s] \"%s\"\n",
- client,
- time_str,
+void
+Log::Format::SquidUserAgent(AccessLogEntry * al, Logfile * logfile)
+{
+ char clientip[MAX_IPSTRLEN];
+
+ const char *agent = al->request->header.getStr(HDR_USER_AGENT);
+ if (!agent || *agent == '\0')
+ agent = "-";
+
+ logfilePrintf(logfile, "%s [%s] \"%s\"\n",
+ al->cache.caddr.NtoA(clientip,MAX_IPSTRLEN),
+ Time::FormatHttpd(squid_curtime),
agent);
-#endif
-}
-
-void
-useragentLogClose(void)
-{
-#if USE_USERAGENT_LOG
-
- if (NULL == useragentlog)
- return;
-
- logfileClose(useragentlog);
-
- useragentlog = NULL;
-
-#endif
}
=== added file 'src/log/Formats.h'
--- src/log/Formats.h 1970-01-01 00:00:00 +0000
+++ src/log/Formats.h 2010-11-21 04:52:44 +0000
@@ -0,0 +1,51 @@
+#ifndef _SQUID_LOG_FORMATS_H
+#define _SQUID_LOG_FORMATS_H
+
+class AccessLogEntry;
+class Logfile;
+
+namespace Log
+{
+
+namespace Format
+{
+
+typedef enum {
+ CLF_UNKNOWN,
+ CLF_COMBINED,
+ CLF_COMMON,
+ CLF_CUSTOM,
+#if ICAP_CLIENT
+ CLF_ICAP_SQUID,
+#endif
+ CLF_REFERER,
+ CLF_SQUID,
+ CLF_USERAGENT,
+ CLF_NONE
+} log_type;
+
+/// Native Squid Format Display
+void SquidNative(AccessLogEntry * al, Logfile * logfile);
+
+/// Display log details in Squid ICAP format.
+void SquidIcap(AccessLogEntry * al, Logfile * logfile);
+
+/// Display log details in useragent format.
+void SquidUserAgent(AccessLogEntry * al, Logfile * logfile);
+
+/// Display log details in Squid old refererlog format.
+void SquidReferer(AccessLogEntry * al, Logfile * logfile);
+
+/// Log with a local custom format
+void SquidCustom(AccessLogEntry * al, customlog * log);
+
+/// Log with Apache httpd common format
+void HttpdCommon(AccessLogEntry * al, Logfile * logfile);
+
+/// Log with Apache httpd combined format
+void HttpdCombined(AccessLogEntry * al, Logfile * logfile);
+
+}; // namespace Format
+}; // namespace Log
+
+#endif /* _SQUID_LOG_FORMATS_H */
=== added file 'src/log/Gadgets.cc'
--- src/log/Gadgets.cc 1970-01-01 00:00:00 +0000
+++ src/log/Gadgets.cc 2010-11-21 04:52:44 +0000
@@ -0,0 +1,156 @@
+#include "config.h"
+#include "log/Gadgets.h"
+
+static const char c2x[] =
+ "000102030405060708090a0b0c0d0e0f"
+ "101112131415161718191a1b1c1d1e1f"
+ "202122232425262728292a2b2c2d2e2f"
+ "303132333435363738393a3b3c3d3e3f"
+ "404142434445464748494a4b4c4d4e4f"
+ "505152535455565758595a5b5c5d5e5f"
+ "606162636465666768696a6b6c6d6e6f"
+ "707172737475767778797a7b7c7d7e7f"
+ "808182838485868788898a8b8c8d8e8f"
+ "909192939495969798999a9b9c9d9e9f"
+ "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
+ "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
+ "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
+ "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
+ "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
+
+#if DEAD_USING_QUOTEMIMEBLOB
+/** copy of Log::QuoteMimeBlob. Bugs there will be found here.
+ * This omits [] characters but is otherwise identical to Log::QuoteMimeBlob when OLD_LOG_MIME = 1
+ */
+static char *
+username_quote(const char *header)
+{
+ int c;
+ int i;
+ char *buf;
+ char *buf_cursor;
+
+ if (header == NULL) {
+ buf = static_cast(xcalloc(1, 1));
+ *buf = '\0';
+ return buf;
+ }
+
+ buf = static_cast(xcalloc(1, (strlen(header) * 3) + 1));
+ buf_cursor = buf;
+ /*
+ * We escape: space \x00-\x1F and space (0x40) and \x7F-\xFF
+ * to prevent garbage in the logs. CR and LF are also there just in case.
+ */
+
+ while ((c = *(const unsigned char *) header++) != '\0') {
+ if (c == '\r') {
+ *buf_cursor++ = '\\';
+ *buf_cursor++ = 'r';
+ } else if (c == '\n') {
+ *buf_cursor++ = '\\';
+ *buf_cursor++ = 'n';
+ } else if (c <= 0x1F
+ || c >= 0x7F
+ || c == '%'
+ || c == ' ') {
+ *buf_cursor++ = '%';
+ i = c * 2;
+ *buf_cursor++ = c2x[i];
+ *buf_cursor++ = c2x[i + 1];
+ } else {
+ *buf_cursor++ = (char) c;
+ }
+ }
+
+ *buf_cursor = '\0';
+ return buf;
+}
+#endif // DEAD
+
+char *
+Log::FormatName(const char *name)
+{
+ if (NULL == name)
+ return NULL;
+
+ if (name[0] == '\0')
+ return NULL;
+
+ return QuoteMimeBlob(name);
+// return username_quote(name);
+}
+
+char *
+Log::QuoteMimeBlob(const char *header)
+{
+ int c;
+ int i;
+ char *buf;
+ char *buf_cursor;
+
+ if (header == NULL) {
+ buf = static_cast(xcalloc(1, 1));
+ *buf = '\0';
+ return buf;
+ }
+
+ buf = static_cast(xcalloc(1, (strlen(header) * 3) + 1));
+ buf_cursor = buf;
+ /**
+ * Whe OLD_LOG_MIME is defined we escape: \x00-\x1F"#%;<>?{}|\\\\^~`\[\]\x7F-\xFF
+ * which is the default escape list for the CPAN Perl5 URI module
+ * modulo the inclusion of space (x40) to make the raw logs a bit
+ * more readable.
+ */
+
+ while ((c = *(const unsigned char *) header++) != '\0') {
+#if !OLD_LOG_MIME
+ if (c == '\r') {
+ *buf_cursor++ = '\\';
+ *buf_cursor++ = 'r';
+ } else if (c == '\n') {
+ *buf_cursor++ = '\\';
+ *buf_cursor++ = 'n';
+ } else
+#endif
+ if (c <= 0x1F
+ || c >= 0x7F
+ || c == '%'
+#if OLD_LOG_MIME
+ || c == '"'
+ || c == '#'
+ || c == ';'
+ || c == '<'
+ || c == '>'
+ || c == '?'
+ || c == '{'
+ || c == '}'
+ || c == '|'
+ || c == '\\'
+ || c == '^'
+ || c == '~'
+ || c == '`'
+#endif
+ || c == '['
+ || c == ']') {
+ *buf_cursor++ = '%';
+ i = c * 2;
+ *buf_cursor++ = c2x[i];
+ *buf_cursor++ = c2x[i + 1];
+#if !OLD_LOG_MIME
+
+ } else if (c == '\\') {
+ *buf_cursor++ = '\\';
+ *buf_cursor++ = '\\';
+#endif
+
+ } else {
+ *buf_cursor++ = (char) c;
+ }
+ }
+
+ *buf_cursor = '\0';
+ return buf;
+}
=== added file 'src/log/Gadgets.h'
--- src/log/Gadgets.h 1970-01-01 00:00:00 +0000
+++ src/log/Gadgets.h 2010-11-21 04:52:44 +0000
@@ -0,0 +1,19 @@
+#ifndef _SQUID_LOG_GADGETS_H
+#define _SQUID_LOG_GADGETS_H
+
+namespace Log
+{
+
+/// Safely URL-encode a username.
+/// Accepts NULL or empty strings.
+char * FormatName(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);
+
+}; // namespace Log
+
+#endif /* _SQUID_LOG_GADGETS_H */
=== modified file 'src/log/Makefile.am'
--- src/log/Makefile.am 2010-04-19 10:03:17 +0000
+++ src/log/Makefile.am 2010-11-21 04:52:44 +0000
@@ -9,6 +9,16 @@
Config.h \
File.cc \
File.h \
+ FormatHttpdCombined.cc \
+ FormatHttpdCommon.cc \
+ Formats.h \
+ FormatSquidCustom.cc \
+ FormatSquidIcap.cc \
+ FormatSquidNative.cc \
+ FormatSquidReferer.cc \
+ FormatSquidUseragent.cc \
+ Gadgets.cc \
+ Gadgets.h \
ModDaemon.cc \
ModDaemon.h \
ModStdio.cc \
@@ -18,4 +28,7 @@
ModTcp.cc \
ModTcp.h \
ModUdp.cc \
- ModUdp.h
+ ModUdp.h \
+ Tokens.cc \
+ Tokens.h
+
=== added file 'src/log/Tokens.cc'
--- src/log/Tokens.cc 1970-01-01 00:00:00 +0000
+++ src/log/Tokens.cc 2010-11-21 05:34:20 +0000
@@ -0,0 +1,690 @@
+/*
+ * $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
+
+ /*{ "ha", LFT_ADAPTED_REQUEST_HEADER},
+ {">ha", LFT_ADAPTED_REQUEST_ALL_HEADERS},
+ {">h", LFT_REQUEST_HEADER},
+ {">h", LFT_REQUEST_ALL_HEADERS},
+ {"Hs", LFT_HTTP_SENT_STATUS_CODE},
+ {"v", LFT_REQUEST_VERSION},
+ {"rv", LFT_REQUEST_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_ICAP_BYTES_SENT},
+ {"icap::h", LFT_ICAP_REQ_HEADER},
+ {"icap:: 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 ICAP_CLIENT
+ case LFT_ICAP_LAST_MATCHED_HEADER:
+
+ 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 ICAP_CLIENT
+ case LFT_ICAP_LAST_MATCHED_HEADER:
+ lt->type = LFT_ICAP_LAST_MATCHED_HEADER_ELEM;
+ break;
+ 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 ICAP_CLIENT
+ case LFT_ICAP_LAST_MATCHED_HEADER:
+ lt->type = LFT_ICAP_LAST_MATCHED_ALL_HEADERS;
+ break;
+ 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\" formating code is deprecated use the \">Hs\" instead");
+ lt->type = LFT_HTTP_SENT_STATUS_CODE;
+ 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, "e);
+
+ 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, "e);
+ }
+
+ 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 ICAP_CLIENT
+ case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
+ 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;
+ break;
+ case LFT_ADAPTED_REQUEST_HEADER_ELEM:
+ type = LFT_ADAPTED_REQUEST_HEADER_ELEM;
+ break;
+ case LFT_REPLY_HEADER_ELEM:
+ type = LFT_REPLY_HEADER_ELEM;
+ break;
+#if ICAP_CLIENT
+ case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
+ type = LFT_ICAP_LAST_MATCHED_HEADER;
+ break;
+ 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 ICAP_CLIENT
+ case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
+ 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 ICAP_CLIENT
+ case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
+ type = LFT_ICAP_LAST_MATCHED_HEADER;
+ break;
+ 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);
+}
=== added file 'src/log/Tokens.h'
--- src/log/Tokens.h 1970-01-01 00:00:00 +0000
+++ src/log/Tokens.h 2010-11-21 04:52:47 +0000
@@ -0,0 +1,246 @@
+/*
+ * $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.
+ *
+ */
+#ifndef _SQUID_LOG_TOKENS_H
+#define _SQUID_LOG_TOKENS_H
+
+class StoreEntry;
+
+#define LOG_BUF_SZ (MAX_URL<<2)
+
+/*
+ * Bytecodes for the configureable logformat stuff
+ */
+typedef enum {
+ LFT_NONE, /* dummy */
+ LFT_STRING,
+
+ LFT_CLIENT_IP_ADDRESS,
+ LFT_CLIENT_FQDN,
+ LFT_CLIENT_PORT,
+#if USE_SQUID_EUI
+ LFT_CLIENT_EUI,
+#endif
+
+ /*LFT_SERVER_IP_ADDRESS, */
+ LFT_SERVER_IP_OR_PEER_NAME,
+ /*LFT_SERVER_PORT, */
+
+ LFT_LOCAL_IP,
+ LFT_LOCAL_PORT,
+ /*LFT_LOCAL_NAME, */
+ LFT_PEER_LOCAL_PORT,
+
+ LFT_TIME_SECONDS_SINCE_EPOCH,
+ LFT_TIME_SUBSECOND,
+ LFT_TIME_LOCALTIME,
+ LFT_TIME_GMT,
+ LFT_TIME_TO_HANDLE_REQUEST,
+
+ LFT_PEER_RESPONSE_TIME,
+ LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME,
+ LFT_DNS_WAIT_TIME,
+
+ LFT_REQUEST_HEADER,
+ LFT_REQUEST_HEADER_ELEM,
+ LFT_REQUEST_ALL_HEADERS,
+
+ LFT_ADAPTED_REQUEST_HEADER,
+ LFT_ADAPTED_REQUEST_HEADER_ELEM,
+ LFT_ADAPTED_REQUEST_ALL_HEADERS,
+
+ LFT_REPLY_HEADER,
+ LFT_REPLY_HEADER_ELEM,
+ LFT_REPLY_ALL_HEADERS,
+
+ LFT_USER_NAME,
+ LFT_USER_LOGIN,
+ LFT_USER_IDENT,
+ /*LFT_USER_REALM, */
+ /*LFT_USER_SCHEME, */
+ LFT_USER_EXTERNAL,
+
+ LFT_HTTP_SENT_STATUS_CODE_OLD_30,
+ LFT_HTTP_SENT_STATUS_CODE,
+ LFT_HTTP_RECEIVED_STATUS_CODE,
+ /*LFT_HTTP_STATUS, */
+ LFT_HTTP_BODY_BYTES_READ,
+
+ LFT_SQUID_STATUS,
+ LFT_SQUID_ERROR,
+ LFT_SQUID_ERROR_DETAIL,
+ LFT_SQUID_HIERARCHY,
+
+ LFT_MIME_TYPE,
+
+ LFT_REQUEST_METHOD,
+ LFT_REQUEST_URI,
+ LFT_REQUEST_URLPATH,
+ /*LFT_REQUEST_QUERY, * // * this is not needed. see strip_query_terms */
+ LFT_REQUEST_VERSION,
+
+ LFT_REQUEST_SIZE_TOTAL,
+ /*LFT_REQUEST_SIZE_LINE, */
+ LFT_REQUEST_SIZE_HEADERS,
+ /*LFT_REQUEST_SIZE_BODY, */
+ /*LFT_REQUEST_SIZE_BODY_NO_TE, */
+
+ LFT_REPLY_SIZE_TOTAL,
+ LFT_REPLY_HIGHOFFSET,
+ LFT_REPLY_OBJECTSIZE,
+ /*LFT_REPLY_SIZE_LINE, */
+ LFT_REPLY_SIZE_HEADERS,
+ /*LFT_REPLY_SIZE_BODY, */
+ /*LFT_REPLY_SIZE_BODY_NO_TE, */
+
+ LFT_TAG,
+ LFT_IO_SIZE_TOTAL,
+ LFT_EXT_LOG,
+
+ LFT_SEQUENCE_NUMBER,
+
+#if USE_ADAPTATION
+ LTF_ADAPTATION_SUM_XACT_TIMES,
+ LTF_ADAPTATION_ALL_XACT_TIMES,
+#endif
+
+#if ICAP_CLIENT
+
+ LFT_ICAP_TOTAL_TIME,
+ LFT_ICAP_LAST_MATCHED_HEADER,
+ LFT_ICAP_LAST_MATCHED_HEADER_ELEM,
+ LFT_ICAP_LAST_MATCHED_ALL_HEADERS,
+
+ LFT_ICAP_ADDR,
+ LFT_ICAP_SERV_NAME,
+ LFT_ICAP_REQUEST_URI,
+ LFT_ICAP_REQUEST_METHOD,
+ LFT_ICAP_BYTES_SENT,
+ LFT_ICAP_BYTES_READ,
+ LFT_ICAP_BODY_BYTES_READ,
+
+ LFT_ICAP_REQ_HEADER,
+ LFT_ICAP_REQ_HEADER_ELEM,
+ LFT_ICAP_REQ_ALL_HEADERS,
+
+ LFT_ICAP_REP_HEADER,
+ LFT_ICAP_REP_HEADER_ELEM,
+ LFT_ICAP_REP_ALL_HEADERS,
+
+ LFT_ICAP_TR_RESPONSE_TIME,
+ LFT_ICAP_IO_TIME,
+ LFT_ICAP_OUTCOME,
+ LFT_ICAP_STATUS_CODE,
+#endif
+
+ LFT_PERCENT /* special string cases for escaped chars */
+} logformat_bcode_t;
+
+enum log_quote {
+ LOG_QUOTE_NONE = 0,
+ LOG_QUOTE_QUOTES,
+ LOG_QUOTE_MIMEBLOB,
+ LOG_QUOTE_URL,
+ LOG_QUOTE_RAW
+};
+
+/* FIXME: public class so we can pre-define its type. */
+class logformat_token
+{
+public:
+ logformat_bcode_t type;
+ union {
+ char *string;
+
+ struct {
+ char *header;
+ char *element;
+ char separator;
+ } header;
+ char *timespec;
+ } data;
+ unsigned char width;
+ unsigned char precision;
+ enum log_quote 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 */
+};
+
+struct logformat_token_table_entry {
+ const char *config;
+ logformat_bcode_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);
+
+void accessLogFreeLogFormat(logformat_token ** tokens);
+
+#endif /* _SQUID_LOG_TOKENS_H */
=== modified file 'src/log/access_log.cc'
--- src/log/access_log.cc 2010-10-29 00:12:28 +0000
+++ src/log/access_log.cc 2010-11-21 08:38:59 +0000
@@ -51,14 +51,14 @@
#include "HttpReply.h"
#include "HttpRequest.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"
#include "SquidTime.h"
-static void accessLogSquid(AccessLogEntry * al, Logfile * logfile);
-static void accessLogCommon(AccessLogEntry * al, Logfile * logfile);
-static void accessLogCustom(AccessLogEntry * al, customlog * log);
#if HEADERS_LOG
static Logfile *headerslog = NULL;
#endif
@@ -70,34 +70,6 @@
static void mcast_encode(unsigned int *, size_t, const unsigned int *);
#endif
-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_FORW_VIA_DB
typedef struct {
@@ -118,1872 +90,6 @@
int LogfileStatus = LOG_DISABLE;
-#if USE_ADAPTATION
-bool alLogformatHasAdaptToken = false;
-#endif
-
-#if ICAP_CLIENT
-bool alLogformatHasIcapToken = false;
-#endif
-
-#define LOG_BUF_SZ (MAX_URL<<2)
-
-static const char c2x[] =
- "000102030405060708090a0b0c0d0e0f"
- "101112131415161718191a1b1c1d1e1f"
- "202122232425262728292a2b2c2d2e2f"
- "303132333435363738393a3b3c3d3e3f"
- "404142434445464748494a4b4c4d4e4f"
- "505152535455565758595a5b5c5d5e5f"
- "606162636465666768696a6b6c6d6e6f"
- "707172737475767778797a7b7c7d7e7f"
- "808182838485868788898a8b8c8d8e8f"
- "909192939495969798999a9b9c9d9e9f"
- "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
- "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
- "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
- "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
- "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
- "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
-
-/* log_quote -- URL-style encoding on MIME headers. */
-
-char *
-log_quote(const char *header)
-{
- int c;
- int i;
- char *buf;
- char *buf_cursor;
-
- if (header == NULL) {
- buf = static_cast(xcalloc(1, 1));
- *buf = '\0';
- return buf;
- }
-
- buf = static_cast(xcalloc(1, (strlen(header) * 3) + 1));
- buf_cursor = buf;
- /*
- * We escape: \x00-\x1F"#%;<>?{}|\\\\^~`\[\]\x7F-\xFF
- * which is the default escape list for the CPAN Perl5 URI module
- * modulo the inclusion of space (x40) to make the raw logs a bit
- * more readable.
- */
-
- while ((c = *(const unsigned char *) header++) != '\0') {
-#if !OLD_LOG_MIME
-
- if (c == '\r') {
- *buf_cursor++ = '\\';
- *buf_cursor++ = 'r';
- } else if (c == '\n') {
- *buf_cursor++ = '\\';
- *buf_cursor++ = 'n';
- } else
-#endif
- if (c <= 0x1F
- || c >= 0x7F
- || c == '%'
-#if OLD_LOG_MIME
- || c == '"'
- || c == '#'
- || c == ';'
- || c == '<'
- || c == '>'
- || c == '?'
- || c == '{'
- || c == '}'
- || c == '|'
- || c == '\\'
- || c == '^'
- || c == '~'
- || c == '`'
-#endif
- || c == '['
- || c == ']') {
- *buf_cursor++ = '%';
- i = c * 2;
- *buf_cursor++ = c2x[i];
- *buf_cursor++ = c2x[i + 1];
-#if !OLD_LOG_MIME
-
- } else if (c == '\\') {
- *buf_cursor++ = '\\';
- *buf_cursor++ = '\\';
-#endif
-
- } else {
- *buf_cursor++ = (char) c;
- }
- }
-
- *buf_cursor = '\0';
- return buf;
-}
-
-static char *
-username_quote(const char *header)
-/* copy of log_quote. Bugs there will be found here */
-{
- int c;
- int i;
- char *buf;
- char *buf_cursor;
-
- if (header == NULL) {
- buf = static_cast(xcalloc(1, 1));
- *buf = '\0';
- return buf;
- }
-
- buf = static_cast(xcalloc(1, (strlen(header) * 3) + 1));
- buf_cursor = buf;
- /*
- * We escape: space \x00-\x1F and space (0x40) and \x7F-\xFF
- * to prevent garbage in the logs. CR and LF are also there just in case.
- */
-
- while ((c = *(const unsigned char *) header++) != '\0') {
- if (c == '\r') {
- *buf_cursor++ = '\\';
- *buf_cursor++ = 'r';
- } else if (c == '\n') {
- *buf_cursor++ = '\\';
- *buf_cursor++ = 'n';
- } else if (c <= 0x1F
- || c >= 0x7F
- || c == '%'
- || c == ' ') {
- *buf_cursor++ = '%';
- i = c * 2;
- *buf_cursor++ = c2x[i];
- *buf_cursor++ = c2x[i + 1];
- } else {
- *buf_cursor++ = (char) c;
- }
- }
-
- *buf_cursor = '\0';
- return buf;
-}
-
-static char *
-accessLogFormatName(const char *name)
-{
- if (NULL == name)
- return NULL;
-
- if (name[0] == '\0')
- return NULL;
-
- return username_quote(name);
-}
-
-static char *
-log_quoted_string(const char *str)
-{
- char *out = (char *)xmalloc(strlen(str) * 2 + 1);
- 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';
- return out;
-}
-
-/*
- * Bytecodes for the configureable logformat stuff
- */
-typedef enum {
- LFT_NONE, /* dummy */
- LFT_STRING,
-
- LFT_CLIENT_IP_ADDRESS,
- LFT_CLIENT_FQDN,
- LFT_CLIENT_PORT,
-#if USE_SQUID_EUI
- LFT_CLIENT_EUI,
-#endif
-
- /*LFT_SERVER_IP_ADDRESS, */
- LFT_SERVER_IP_OR_PEER_NAME,
- /*LFT_SERVER_PORT, */
-
- LFT_LOCAL_IP,
- LFT_LOCAL_PORT,
- /*LFT_LOCAL_NAME, */
- LFT_PEER_LOCAL_PORT,
-
- LFT_TIME_SECONDS_SINCE_EPOCH,
- LFT_TIME_SUBSECOND,
- LFT_TIME_LOCALTIME,
- LFT_TIME_GMT,
- LFT_TIME_TO_HANDLE_REQUEST,
-
- LFT_PEER_RESPONSE_TIME,
- LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME,
- LFT_DNS_WAIT_TIME,
-
- LFT_REQUEST_HEADER,
- LFT_REQUEST_HEADER_ELEM,
- LFT_REQUEST_ALL_HEADERS,
-
- LFT_ADAPTED_REQUEST_HEADER,
- LFT_ADAPTED_REQUEST_HEADER_ELEM,
- LFT_ADAPTED_REQUEST_ALL_HEADERS,
-
- LFT_REPLY_HEADER,
- LFT_REPLY_HEADER_ELEM,
- LFT_REPLY_ALL_HEADERS,
-
- LFT_USER_NAME,
- LFT_USER_LOGIN,
- LFT_USER_IDENT,
- /*LFT_USER_REALM, */
- /*LFT_USER_SCHEME, */
- LFT_USER_EXTERNAL,
-
- LFT_HTTP_SENT_STATUS_CODE_OLD_30,
- LFT_HTTP_SENT_STATUS_CODE,
- LFT_HTTP_RECEIVED_STATUS_CODE,
- /*LFT_HTTP_STATUS, */
- LFT_HTTP_BODY_BYTES_READ,
-
- LFT_SQUID_STATUS,
- LFT_SQUID_ERROR,
- LFT_SQUID_ERROR_DETAIL,
- LFT_SQUID_HIERARCHY,
-
- LFT_MIME_TYPE,
-
- LFT_REQUEST_METHOD,
- LFT_REQUEST_URI,
- LFT_REQUEST_URLPATH,
- /*LFT_REQUEST_QUERY, * // * this is not needed. see strip_query_terms */
- LFT_REQUEST_VERSION,
-
- LFT_REQUEST_SIZE_TOTAL,
- /*LFT_REQUEST_SIZE_LINE, */
- LFT_REQUEST_SIZE_HEADERS,
- /*LFT_REQUEST_SIZE_BODY, */
- /*LFT_REQUEST_SIZE_BODY_NO_TE, */
-
- LFT_REPLY_SIZE_TOTAL,
- LFT_REPLY_HIGHOFFSET,
- LFT_REPLY_OBJECTSIZE,
- /*LFT_REPLY_SIZE_LINE, */
- LFT_REPLY_SIZE_HEADERS,
- /*LFT_REPLY_SIZE_BODY, */
- /*LFT_REPLY_SIZE_BODY_NO_TE, */
-
- LFT_TAG,
- LFT_IO_SIZE_TOTAL,
- LFT_EXT_LOG,
-
- LFT_SEQUENCE_NUMBER,
-
-#if USE_ADAPTATION
- LTF_ADAPTATION_SUM_XACT_TIMES,
- LTF_ADAPTATION_ALL_XACT_TIMES,
-#endif
-
-#if ICAP_CLIENT
-
- LFT_ICAP_TOTAL_TIME,
- LFT_ICAP_LAST_MATCHED_HEADER,
- LFT_ICAP_LAST_MATCHED_HEADER_ELEM,
- LFT_ICAP_LAST_MATCHED_ALL_HEADERS,
-
- LFT_ICAP_ADDR,
- LFT_ICAP_SERV_NAME,
- LFT_ICAP_REQUEST_URI,
- LFT_ICAP_REQUEST_METHOD,
- LFT_ICAP_BYTES_SENT,
- LFT_ICAP_BYTES_READ,
- LFT_ICAP_BODY_BYTES_READ,
-
- LFT_ICAP_REQ_HEADER,
- LFT_ICAP_REQ_HEADER_ELEM,
- LFT_ICAP_REQ_ALL_HEADERS,
-
- LFT_ICAP_REP_HEADER,
- LFT_ICAP_REP_HEADER_ELEM,
- LFT_ICAP_REP_ALL_HEADERS,
-
- LFT_ICAP_TR_RESPONSE_TIME,
- LFT_ICAP_IO_TIME,
- LFT_ICAP_OUTCOME,
- LFT_ICAP_STATUS_CODE,
-#endif
-
- LFT_PERCENT /* special string cases for escaped chars */
-} logformat_bcode_t;
-
-enum log_quote {
- LOG_QUOTE_NONE = 0,
- LOG_QUOTE_QUOTES,
- LOG_QUOTE_BRAKETS,
- LOG_QUOTE_URL,
- LOG_QUOTE_RAW
-};
-
-/* FIXME: public class so we can pre-define its type. */
-class logformat_token
-{
-public:
- logformat_bcode_t type;
- union {
- char *string;
-
- struct {
- char *header;
- char *element;
- char separator;
- } header;
- char *timespec;
- } data;
- unsigned char width;
- unsigned char precision;
- enum log_quote 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 */
-};
-
-struct logformat_token_table_entry {
- const char *config;
- logformat_bcode_t token_type;
- int options;
-};
-
-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
-
- /*{ "ha", LFT_ADAPTED_REQUEST_HEADER},
- {">ha", LFT_ADAPTED_REQUEST_ALL_HEADERS},
- {">h", LFT_REQUEST_HEADER},
- {">h", LFT_REQUEST_ALL_HEADERS},
- {"Hs", LFT_HTTP_SENT_STATUS_CODE},
- {"v", LFT_REQUEST_VERSION},
- {"rv", LFT_REQUEST_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_ICAP_BYTES_SENT},
- {"icap::h", LFT_ICAP_REQ_HEADER},
- {"icap::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:
- if (al->request) {
- if (al->cache.caddr.IsIPv4())
- al->request->client_eui48.encode(tmp, 1024);
- else
- al->request->client_eui64.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,1024);
- }
-
- break;
-
- case LFT_LOCAL_PORT:
- if (al->request) {
- outint = al->request->my_addr.GetPort();
- doint = 1;
- }
-
- break;
-
- case LFT_PEER_LOCAL_PORT:
- if (al->hier.peer_local_port) {
- outint = al->hier.peer_local_port;
- doint = 1;
- }
-
- break;
-
- case LFT_TIME_SECONDS_SINCE_EPOCH:
- // some platforms store time in 32-bit, some 64-bit...
- outoff = static_cast(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;
-#endif
-
-#if ICAP_CLIENT
- case LFT_ICAP_LAST_MATCHED_HEADER:
- if (al->request) {
- Adaptation::Icap::History::Pointer ih = al->request->icapHistory();
- if (ih != NULL)
- sb = ih->mergeOfIcapHeaders.getByName(fmt->data.header.header);
- }
-
- out = sb.termedBuf();
-
- quote = 1;
-
- break;
-
- case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
- if (al->request) {
- Adaptation::Icap::History::Pointer ih = al->request->icapHistory();
- if (ih != NULL)
- sb = ih->mergeOfIcapHeaders.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
- }
-
- out = sb.termedBuf();
-
- quote = 1;
-
- break;
-
- case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
- out = al->headers.icap;
-
- quote = 1;
-
- break;
-
- 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 = accessLogFormatName(al->cache.authuser);
-
- if (!out)
- out = accessLogFormatName(al->cache.extuser);
-
-#if USE_SSL
-
- if (!out)
- out = accessLogFormatName(al->cache.ssluser);
-
-#endif
-
- if (!out)
- out = accessLogFormatName(al->cache.rfc931);
-
- dofree = 1;
-
- break;
-
- case LFT_USER_LOGIN:
- out = accessLogFormatName(al->cache.authuser);
-
- dofree = 1;
-
- break;
-
- case LFT_USER_IDENT:
- out = accessLogFormatName(al->cache.rfc931);
-
- dofree = 1;
-
- break;
-
- case LFT_USER_EXTERNAL:
- out = accessLogFormatName(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_REQUEST_METHOD:
- out = al->_private.method_str;
-
- break;
-
- case LFT_REQUEST_URI:
- out = al->url;
-
- break;
-
- case LFT_REQUEST_URLPATH:
- if (al->request) {
- out = al->request->urlpath.termedBuf();
- quote = 1;
- }
- break;
-
- 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_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:
- newout = log_quoted_string(out);
- newfree = 1;
- break;
-
- case LOG_QUOTE_BRAKETS:
- newout = log_quote(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);
- }
-
- logfilePrintf(logfile, "%s\n", mb.buf);
-}
-
-/* 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
- */
-static 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_BRAKETS;
-
- break;
-
- case ']':
- if (*quote == LOG_QUOTE_BRAKETS)
- *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_BRAKETS;
- 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 ICAP_CLIENT
- case LFT_ICAP_LAST_MATCHED_HEADER:
-
- 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 ICAP_CLIENT
- case LFT_ICAP_LAST_MATCHED_HEADER:
- lt->type = LFT_ICAP_LAST_MATCHED_HEADER_ELEM;
- break;
- 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 ICAP_CLIENT
- case LFT_ICAP_LAST_MATCHED_HEADER:
- lt->type = LFT_ICAP_LAST_MATCHED_ALL_HEADERS;
- break;
- 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\" formating code is deprecated use the \">Hs\" instead");
- lt->type = LFT_HTTP_SENT_STATUS_CODE;
- 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, "e);
-
- 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, "e);
- }
-
- 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 ICAP_CLIENT
- case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
- 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;
- break;
- case LFT_ADAPTED_REQUEST_HEADER_ELEM:
- type = LFT_ADAPTED_REQUEST_HEADER_ELEM;
- break;
- case LFT_REPLY_HEADER_ELEM:
- type = LFT_REPLY_HEADER_ELEM;
- break;
-#if ICAP_CLIENT
- case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
- type = LFT_ICAP_LAST_MATCHED_HEADER;
- break;
- 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 ICAP_CLIENT
- case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
- 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 ICAP_CLIENT
- case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
- type = LFT_ICAP_LAST_MATCHED_HEADER;
- break;
- 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_BRAKETS:
- 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);
- }
-}
-
-static void
-accessLogSquid(AccessLogEntry * al, Logfile * logfile)
-{
- const char *client = NULL;
- const char *user = NULL;
- char buf[MAX_IPSTRLEN];
-
- if (Config.onoff.log_fqdn) {
- client = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
- }
-
- if (client == NULL) {
- client = al->cache.caddr.NtoA(buf,MAX_IPSTRLEN);
- }
-
- user = accessLogFormatName(al->cache.authuser);
-
- if (!user)
- user = accessLogFormatName(al->cache.extuser);
-
-#if USE_SSL
-
- if (!user)
- user = accessLogFormatName(al->cache.ssluser);
-
-#endif
-
- if (!user)
- user = accessLogFormatName(al->cache.rfc931);
-
- if (user && !*user)
- safe_free(user);
-
- if (!Config.onoff.log_mime_hdrs) {
- logfilePrintf(logfile, "%9ld.%03d %6d %s %s%s/%03d %"PRId64" %s %s %s %s%s/%s %s\n",
- (long int) current_time.tv_sec,
- (int) current_time.tv_usec / 1000,
- al->cache.msec,
- client,
- log_tags[al->cache.code],
- al->http.statusSfx(),
- al->http.code,
- al->cache.replySize,
- al->_private.method_str,
- al->url,
- user ? user : dash_str,
- al->hier.ping.timedout ? "TIMEOUT_" : "",
- hier_code_str[al->hier.code],
- al->hier.host,
- al->http.content_type);
- } else {
- char *ereq = log_quote(al->headers.request);
- char *erep = log_quote(al->headers.reply);
- logfilePrintf(logfile, "%9ld.%03d %6d %s %s%s/%03d %"PRId64" %s %s %s %s%s/%s %s [%s] [%s]\n",
- (long int) current_time.tv_sec,
- (int) current_time.tv_usec / 1000,
- al->cache.msec,
- client,
- log_tags[al->cache.code],
- al->http.statusSfx(),
- al->http.code,
- al->cache.replySize,
- al->_private.method_str,
- al->url,
- user ? user : dash_str,
- al->hier.ping.timedout ? "TIMEOUT_" : "",
- hier_code_str[al->hier.code],
- al->hier.host,
- al->http.content_type,
- ereq,
- erep);
- safe_free(ereq);
- safe_free(erep);
- }
- safe_free(user);
-}
-
-static void
-accessLogCommon(AccessLogEntry * al, Logfile * logfile)
-{
- const char *client = NULL;
- char *user1 = NULL, *user2 = NULL;
- char buf[MAX_IPSTRLEN];
-
- if (Config.onoff.log_fqdn) {
- client = fqdncache_gethostbyaddr(al->cache.caddr, 0);
- }
-
- if (client == NULL) {
- client = al->cache.caddr.NtoA(buf,MAX_IPSTRLEN);
- }
-
- user1 = accessLogFormatName(al->cache.authuser);
-
- user2 = accessLogFormatName(al->cache.rfc931);
-
- logfilePrintf(logfile, "%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %"PRId64" %s%s:%s%s",
- client,
- user2 ? user2 : dash_str,
- user1 ? user1 : dash_str,
- mkhttpdlogtime(&squid_curtime),
- al->_private.method_str,
- al->url,
- al->http.version.major, al->http.version.minor,
- al->http.code,
- al->cache.replySize,
- log_tags[al->cache.code],
- al->http.statusSfx(),
- hier_code_str[al->hier.code],
- (Config.onoff.log_mime_hdrs?"":"\n"));
-
- safe_free(user1);
-
- safe_free(user2);
-
- if (Config.onoff.log_mime_hdrs) {
- char *ereq = log_quote(al->headers.request);
- char *erep = log_quote(al->headers.reply);
- logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
- safe_free(ereq);
- safe_free(erep);
- }
-}
-
-#if ICAP_CLIENT
-static void
-accessLogICAPSquid(AccessLogEntry * al, Logfile * logfile)
-{
- const char *client = NULL;
- const char *user = NULL;
- char tmp[MAX_IPSTRLEN], clientbuf[MAX_IPSTRLEN];
-
- if (al->cache.caddr.IsAnyAddr()) { // ICAP OPTIONS xactions lack client
- client = "-";
- } else {
- if (Config.onoff.log_fqdn)
- client = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
- if (!client)
- client = al->cache.caddr.NtoA(clientbuf, MAX_IPSTRLEN);
- }
-
- user = accessLogFormatName(al->cache.authuser);
-
- if (!user)
- user = accessLogFormatName(al->cache.extuser);
-
-#if USE_SSL
-
- if (!user)
- user = accessLogFormatName(al->cache.ssluser);
-
-#endif
-
- if (!user)
- user = accessLogFormatName(al->cache.rfc931);
-
- if (user && !*user)
- safe_free(user);
-
- logfilePrintf(logfile, "%9ld.%03d %6d %s -/%03d %"PRId64" %s %s %s -/%s -\n",
- (long int) current_time.tv_sec,
- (int) current_time.tv_usec / 1000,
-
- al->icap.trTime,
- client,
-
- al->icap.resStatus,
- al->icap.bytesRead,
- Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod),
- al->icap.reqUri.termedBuf(),
- user ? user : dash_str,
- al->icap.hostAddr.NtoA(tmp, MAX_IPSTRLEN));
- safe_free(user);
-}
-#endif
-
void
accessLogLogTo(customlog* log, AccessLogEntry * al, ACLChecklist * checklist)
{
@@ -2013,32 +119,37 @@
switch (log->type) {
- case CLF_AUTO:
- if (Config.onoff.common_log)
- accessLogCommon(al, log->logfile);
- else
- accessLogSquid(al, log->logfile);
- break;
-
- case CLF_SQUID:
- accessLogSquid(al, log->logfile);
- break;
-
- case CLF_COMMON:
- accessLogCommon(al, log->logfile);
- break;
-
- case CLF_CUSTOM:
- accessLogCustom(al, log);
+ case Log::Format::CLF_SQUID:
+ Log::Format::SquidNative(al, log->logfile);
+ break;
+
+ case Log::Format::CLF_COMBINED:
+ Log::Format::HttpdCombined(al, log->logfile);
+ break;
+
+ case Log::Format::CLF_COMMON:
+ Log::Format::HttpdCommon(al, log->logfile);
+ break;
+
+ case Log::Format::CLF_REFERER:
+ Log::Format::SquidReferer(al, log->logfile);
+ break;
+
+ case Log::Format::CLF_USERAGENT:
+ Log::Format::SquidUserAgent(al, log->logfile);
+ break;
+
+ case Log::Format::CLF_CUSTOM:
+ Log::Format::SquidCustom(al, log);
break;
#if ICAP_CLIENT
- case CLF_ICAP_SQUID:
- accessLogICAPSquid(al, log->logfile);
+ case Log::Format::CLF_ICAP_SQUID:
+ Log::Format::SquidIcap(al, log->logfile);
break;
#endif
- case CLF_NONE:
+ case Log::Format::CLF_NONE:
return; // abort!
default:
@@ -2185,8 +296,6 @@
accessLogRegisterWithCacheManager();
- assert(sizeof(log_tags) == (LOG_TYPE_MAX + 1) * sizeof(char *));
-
#if USE_ADAPTATION
alLogformatHasAdaptToken = false;
#endif
@@ -2195,7 +304,7 @@
#endif
for (log = Config.Log.accesslogs; log; log = log->next) {
- if (log->type == CLF_NONE)
+ if (log->type == Log::Format::CLF_NONE)
continue;
log->logfile = logfileOpen(log->filename, MAX_URL << 2, 1);
@@ -2261,24 +370,6 @@
#endif
}
-const char *
-accessLogTime(time_t t)
-{
-
- struct tm *tm;
- static char buf[128];
- static time_t last_t = 0;
-
- if (t != last_t) {
- tm = localtime(&t);
- strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
- last_t = t;
- }
-
- return buf;
-}
-
-
#if USE_FORW_VIA_DB
static void
=== modified file 'src/main.cc'
--- src/main.cc 2010-11-27 06:44:33 +0000
+++ src/main.cc 2010-11-28 11:19:02 +0000
@@ -756,8 +756,6 @@
#if ICAP_CLIENT
icapLogClose();
#endif
- useragentLogClose();
- refererCloseLog();
eventAdd("mainReconfigureFinish", &mainReconfigureFinish, NULL, 0, 1,
false);
@@ -823,8 +821,6 @@
icapLogOpen();
#endif
storeLogOpen();
- useragentOpenLog();
- refererOpenLog();
#if USE_DNSSERVERS
dnsInit();
@@ -893,15 +889,9 @@
storeDirWriteCleanLogs(1);
storeLogRotate(); /* store.log */
accessLogRotate(); /* access.log */
- useragentRotateLog(); /* useragent.log */
- refererRotateLog(); /* referer.log */
#if ICAP_CLIENT
icapLogRotate(); /*icap.log*/
#endif
-#if WIP_FWD_LOG
- fwdLogRotate();
-#endif
-
icmpEngine.Open();
#if USE_DNSSERVERS
dnsInit();
@@ -1040,10 +1030,6 @@
externalAclInit();
- useragentOpenLog();
-
- refererOpenLog();
-
httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
httpReplyInitModule(); /* must go before accepting replies */
@@ -1875,13 +1861,6 @@
Store::Root().sync(); /* Flush log writes */
storeLogClose();
accessLogClose();
- useragentLogClose();
- refererCloseLog();
-#if WIP_FWD_LOG
-
- fwdUninit();
-#endif
-
Store::Root().sync(); /* Flush log close */
StoreFileSystem::FreeAllFs();
DiskIOModule::FreeAllModules();
=== modified file 'src/neighbors.cc'
--- src/neighbors.cc 2010-11-27 06:44:33 +0000
+++ src/neighbors.cc 2010-11-28 11:19:02 +0000
@@ -1755,7 +1755,7 @@
if (e->stats.last_connect_failure) {
storeAppendPrintf(sentry, "Last failed connect() at: %s\n",
- mkhttpdlogtime(&(e->stats.last_connect_failure)));
+ Time::FormatHttpd(e->stats.last_connect_failure));
}
if (e->peer_domain != NULL) {
=== modified file 'src/protos.h'
--- src/protos.h 2010-11-27 06:44:33 +0000
+++ src/protos.h 2010-11-28 11:19:02 +0000
@@ -57,7 +57,6 @@
#if HEADERS_LOG
SQUIDCEXTERN void headersLog(int cs, int pq, const HttpRequestMethod& m, void *data);
#endif
-SQUIDCEXTERN char *log_quote(const char *header);
SQUIDCEXTERN int logTypeIsATcpHit(log_type);
/*
@@ -632,14 +631,6 @@
SQUIDCEXTERN char *urlHostname(const char *url);
SQUIDCEXTERN void urlExtMethodConfigure(void);
-SQUIDCEXTERN void useragentOpenLog(void);
-SQUIDCEXTERN void useragentRotateLog(void);
-SQUIDCEXTERN void logUserAgent(const char *, const char *);
-SQUIDCEXTERN void useragentLogClose(void);
-SQUIDCEXTERN void refererOpenLog(void);
-SQUIDCEXTERN void refererRotateLog(void);
-SQUIDCEXTERN void logReferer(const char *, const char *, const char *);
-SQUIDCEXTERN void refererCloseLog(void);
SQUIDCEXTERN peer_t parseNeighborType(const char *s);
/* tools.c */
=== modified file 'src/send-announce.cc'
--- src/send-announce.cc 2010-04-17 02:29:04 +0000
+++ src/send-announce.cc 2010-11-21 04:52:58 +0000
@@ -92,7 +92,7 @@
snprintf(tbuf, 256, "generated %d [%s]\n",
(int) squid_curtime,
- mkhttpdlogtime(&squid_curtime));
+ Time::FormatHttpd(squid_curtime));
strcat(sndbuf, tbuf);
l = strlen(sndbuf);
=== modified file 'src/structs.h'
--- src/structs.h 2010-11-27 06:44:33 +0000
+++ src/structs.h 2010-11-28 11:19:02 +0000
@@ -256,27 +256,10 @@
struct {
char *store;
char *swap;
-#if USE_USERAGENT_LOG
-
- char *useragent;
-#endif
-#if USE_REFERER_LOG
-
- char *referer;
-#endif
-#if WIP_FWD_LOG
-
- char *forward;
-#endif
-
- logformat *logformats;
-
customlog *accesslogs;
-
#if ICAP_CLIENT
customlog *icaplogs;
#endif
-
int rotateNumber;
} Log;
char *adminEmail;
@@ -1310,23 +1293,17 @@
int zero_object_sz;
};
-class logformat_token;
-
-struct _logformat {
- char *name;
- logformat_token *format;
- logformat *next;
-};
-
class Logfile;
+class logformat;
+#include "log/Formats.h"
struct _customlog {
char *filename;
ACLList *aclList;
logformat *logFormat;
Logfile *logfile;
customlog *next;
- customlog_type type;
+ Log::Format::log_type type;
};
#endif /* SQUID_STRUCTS_H */
=== modified file 'src/time.cc'
--- src/time.cc 2010-11-02 00:12:43 +0000
+++ src/time.cc 2010-11-21 04:53:14 +0000
@@ -68,3 +68,66 @@
{
getCurrentTime();
}
+
+const char *
+Time::FormatStrf(time_t t)
+{
+ struct tm *tm;
+ static char buf[128];
+ static time_t last_t = 0;
+
+ if (t != last_t) {
+ tm = localtime(&t);
+ strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
+ last_t = t;
+ }
+
+ return buf;
+}
+
+const char *
+Time::FormatHttpd(time_t t)
+{
+ static char buf[128];
+ static time_t last_t = 0;
+
+ if (t != last_t) {
+ struct tm *gmt = gmtime(&t);
+
+#if !USE_GMT
+ int gmt_min, gmt_hour, gmt_yday, day_offset;
+ size_t len;
+ struct tm *lt;
+ int min_offset;
+
+ /* localtime & gmtime may use the same static data */
+ gmt_min = gmt->tm_min;
+ gmt_hour = gmt->tm_hour;
+ gmt_yday = gmt->tm_yday;
+
+ lt = localtime(&t);
+
+ day_offset = lt->tm_yday - gmt_yday;
+ /* wrap round on end of year */
+ if (day_offset > 1)
+ day_offset = -1;
+ else if (day_offset < -1)
+ day_offset = 1;
+
+ min_offset = day_offset * 1440 + (lt->tm_hour - gmt_hour) * 60
+ + (lt->tm_min - gmt_min);
+
+ len = strftime(buf, 127 - 5, "%d/%b/%Y:%H:%M:%S ", lt);
+ snprintf(buf + len, 128 - len, "%+03d%02d",
+ (min_offset / 60) % 24,
+ min_offset % 60);
+#else /* USE_GMT */
+ buf[0] = '\0';
+ strftime(buf, 127, "%d/%b/%Y:%H:%M:%S -000", gmt);
+#endif /* USE_GMT */
+
+ last_t = t;
+ }
+
+ return buf;
+}
=== modified file 'src/typedefs.h'
--- src/typedefs.h 2010-10-06 03:50:45 +0000
+++ src/typedefs.h 2010-11-21 04:53:15 +0000
@@ -169,8 +169,6 @@
typedef struct _link_list link_list;
-typedef struct _logformat logformat;
-
typedef struct _customlog customlog;
#if SQUID_SNMP