-#include "config.h"
+#include "squid.h"
#include "AccessLogEntry.h"
+#include "client_side.h"
#include "comm/Connection.h"
#include "err_detail_type.h"
#include "errorpage.h"
+#include "fde.h"
#include "format/Format.h"
#include "format/Quoting.h"
-#include "format/Tokens.h"
+#include "format/Token.h"
#include "HttpRequest.h"
#include "MemBuf.h"
+#include "protos.h"
#include "rfc1738.h"
#include "SquidTime.h"
#include "Store.h"
+#if USE_SSL
+#include "ssl/ErrorDetail.h"
+#endif
/// Convert a string to NULL pointer if it is ""
#define strOrNull(s) ((s)==NULL||(s)[0]=='\0'?NULL:(s))
}
bool
-Format::Format::parse(char *def)
+Format::Format::parse(const char *def)
{
- char *cur, *eos;
+ const char *cur, *eos;
Token *new_lt, *last_lt;
enum Quoting quote = LOG_QUOTE_NONE;
if (t->zero)
entry->append("0", 1);
- if (t->width)
- storeAppendPrintf(entry, "%d", (int) t->width);
+ if (t->widthMin >= 0)
+ storeAppendPrintf(entry, "%d", t->widthMin);
- if (t->precision)
- storeAppendPrintf(entry, ".%d", (int) t->precision);
+ if (t->widthMax >= 0)
+ storeAppendPrintf(entry, ".%d", t->widthMax);
if (arg)
storeAppendPrintf(entry, "{%s}", arg);
break;
case '\r':
- *p++ = '\\';
- *p++ = 'r';
- str++;
+ *p = '\\';
+ ++p;
+ *p = 'r';
+ ++p;
+ ++str;
break;
case '\n':
- *p++ = '\\';
- *p++ = 'n';
- str++;
+ *p = '\\';
+ ++p;
+ *p = 'n';
+ ++p;
+ ++str;
break;
case '\t':
- *p++ = '\\';
- *p++ = 't';
- str++;
+ *p = '\\';
+ ++p;
+ *p = 't';
+ ++p;
+ ++str;
break;
default:
- *p++ = '\\';
- *p++ = *str;
- str++;
+ *p = '\\';
+ ++p;
+ *p = *str;
+ ++p;
+ ++str;
break;
}
}
- *p++ = '\0';
+ *p = '\0';
}
void
-Format::Format::assemble(MemBuf &mb, AccessLogEntry *al, int logSequenceNumber) const
+Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logSequenceNumber) const
{
char tmp[1024];
String sb;
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);
+ al->getLogClientIp(tmp, sizeof(tmp));
+ out = tmp;
break;
case LFT_CLIENT_FQDN:
}
break;
- case LFT_CLIENT_LOCAL_IP_OLD_31:
+ case LFT_LOCAL_LISTENING_IP: {
+ // avoid logging a dash if we have reliable info
+ const bool interceptedAtKnownPort = al->request ?
+ (al->request->flags.spoof_client_ip ||
+ al->request->flags.intercepted) && al->cache.port :
+ false;
+ if (interceptedAtKnownPort) {
+ const bool portAddressConfigured = !al->cache.port->s.IsAnyAddr();
+ if (portAddressConfigured)
+ out = al->cache.port->s.NtoA(tmp, sizeof(tmp));
+ } else if (al->tcpClient != NULL)
+ out = al->tcpClient->local.NtoA(tmp, sizeof(tmp));
+ }
+ break;
+
case LFT_CLIENT_LOCAL_IP:
if (al->tcpClient != NULL) {
out = al->tcpClient->local.NtoA(tmp,sizeof(tmp));
}
break;
- case LFT_CLIENT_LOCAL_PORT_OLD_31:
+ case LFT_LOCAL_LISTENING_PORT:
+ if (al->cache.port) {
+ outint = al->cache.port->s.GetPort();
+ doint = 1;
+ }
+ break;
+
case LFT_CLIENT_LOCAL_PORT:
if (al->tcpClient != NULL) {
outint = al->tcpClient->local.GetPort();
doint = 1;
break;
-
case LFT_TIME_LOCALTIME:
case LFT_TIME_GMT: {
break;
#if USE_ADAPTATION
- case LTF_ADAPTATION_SUM_XACT_TIMES:
+ case LFT_ADAPTATION_SUM_XACT_TIMES:
if (al->request) {
Adaptation::History::Pointer ah = al->request->adaptHistory();
if (ah != NULL)
}
break;
- case LTF_ADAPTATION_ALL_XACT_TIMES:
+ case LFT_ADAPTATION_ALL_XACT_TIMES:
if (al->request) {
Adaptation::History::Pointer ah = al->request->adaptHistory();
if (ah != NULL)
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);
+#if USE_SSL
+ if (al->request && al->request->errType == ERR_SECURE_CONNECT_FAIL) {
+ if (! (out = Ssl::GetErrorName(al->request->errDetail))) {
+ snprintf(tmp, sizeof(tmp), "SSL_ERR=%d", al->request->errDetail);
out = tmp;
}
- }
+ } else
+#endif
+ 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:
dooff = 1;
break;
+#if USE_SSL
+ case LFT_SSL_BUMP_MODE: {
+ const Ssl::BumpMode mode = static_cast<Ssl::BumpMode>(al->ssl.bumpMode);
+ // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
+ out = Ssl::bumpMode(mode);
+ break;
+ }
+
+ case LFT_SSL_USER_CERT_SUBJECT:
+ if (X509 *cert = al->cache.sslClientCert.get()) {
+ if (X509_NAME *subject = X509_get_subject_name(cert)) {
+ X509_NAME_oneline(subject, tmp, sizeof(tmp));
+ out = tmp;
+ }
+ }
+ break;
+
+ case LFT_SSL_USER_CERT_ISSUER:
+ if (X509 *cert = al->cache.sslClientCert.get()) {
+ if (X509_NAME *issuer = X509_get_issuer_name(cert)) {
+ X509_NAME_oneline(issuer, tmp, sizeof(tmp));
+ out = tmp;
+ }
+ }
+ break;
+#endif
+
case LFT_PERCENT:
out = "%";
}
if (dooff) {
- snprintf(tmp, sizeof(tmp), "%0*" PRId64, fmt->zero ? (int) fmt->width : 0, outoff);
+ snprintf(tmp, sizeof(tmp), "%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff);
out = tmp;
} else if (doint) {
- snprintf(tmp, sizeof(tmp), "%0*ld", fmt->zero ? (int) fmt->width : 0, outint);
+ snprintf(tmp, sizeof(tmp), "%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
out = tmp;
}
}
// enforce width limits if configured
- const bool haveMaxWidth = fmt->precision && !doint && !dooff;
- if (haveMaxWidth || fmt->width) {
- const int minWidth = fmt->width ?
- static_cast<int>(fmt->width) : 0;
+ const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff;
+ if (haveMaxWidth || fmt->widthMin) {
+ const int minWidth = fmt->widthMin >= 0 ?
+ fmt->widthMin :0;
const int maxWidth = haveMaxWidth ?
- static_cast<int>(fmt->precision) : strlen(out);
+ fmt->widthMax : strlen(out);
if (fmt->left)
mb.Printf("%-*.*s", minWidth, maxWidth, out);