Format.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #include "squid.h"
10 #include "AccessLogEntry.h"
11 #include "base64.h"
12 #include "client_side.h"
13 #include "comm/Connection.h"
14 #include "error/Detail.h"
15 #include "errorpage.h"
16 #include "fde.h"
17 #include "format/Format.h"
18 #include "format/Quoting.h"
19 #include "format/Token.h"
20 #include "http/Stream.h"
21 #include "HttpRequest.h"
22 #include "MemBuf.h"
23 #include "proxyp/Header.h"
24 #include "rfc1738.h"
25 #include "sbuf/Stream.h"
26 #include "sbuf/StringConvert.h"
27 #include "security/CertError.h"
28 #include "security/Certificate.h"
30 #include "Store.h"
31 #include "tools.h"
32 #if USE_OPENSSL
33 #include "ssl/ErrorDetail.h"
34 #include "ssl/ServerBump.h"
35 #endif
36 
38 #define strOrNull(s) ((s)==NULL||(s)[0]=='\0'?NULL:(s))
39 
40 const SBuf Format::Dash("-");
41 
42 Format::Format::Format(const char *n) :
43  format(NULL),
44  next(NULL)
45 {
46  name = xstrdup(n);
47 }
48 
50 {
51  // erase the list without consuming stack space
52  while (next) {
53  // unlink the next entry for deletion
54  Format *temp = next;
55  next = temp->next;
56  temp->next = NULL;
57  delete temp;
58  }
59 
60  // remove locals
61  xfree(name);
62  delete format;
63 }
64 
65 bool
66 Format::Format::parse(const char *def)
67 {
68  const char *cur, *eos;
69  Token *new_lt, *last_lt;
71 
72  debugs(46, 2, "got definition '" << def << "'");
73 
74  if (format) {
75  debugs(46, DBG_IMPORTANT, "WARNING: existing format for '" << name << " " << def << "'");
76  return false;
77  }
78 
79  /* very inefficient parser, but who cares, this needs to be simple */
80  /* First off, let's tokenize, we'll optimize in a second pass.
81  * A token can either be a %-prefixed sequence (usually a dynamic
82  * token but it can be an escaped sequence), or a string. */
83  cur = def;
84  eos = def + strlen(def);
85  format = new_lt = last_lt = new Token;
86  cur += new_lt->parse(cur, &quote);
87 
88  while (cur < eos) {
89  new_lt = new Token;
90  last_lt->next = new_lt;
91  last_lt = new_lt;
92  cur += new_lt->parse(cur, &quote);
93  }
94 
95  return true;
96 }
97 
98 size_t
99 Format::AssembleOne(const char *token, MemBuf &mb, const AccessLogEntryPointer &ale)
100 {
101  Token tkn;
103  const auto tokenSize = tkn.parse(token, &quote);
104  assert(tokenSize > 0);
105  if (ale != nullptr) {
106  Format fmt("SimpleToken");
107  fmt.format = &tkn;
108  fmt.assemble(mb, ale, 0);
109  fmt.format = nullptr;
110  } else {
111  mb.append("-", 1);
112  }
113  return static_cast<size_t>(tokenSize);
114 }
115 
116 void
117 Format::Format::dump(StoreEntry * entry, const char *directiveName, bool eol) const
118 {
119  debugs(46, 4, MYNAME);
120 
121  // loop rather than recursing to conserve stack space.
122  for (const Format *fmt = this; fmt; fmt = fmt->next) {
123  debugs(46, 3, "Dumping format definition for " << fmt->name);
124  if (directiveName)
125  storeAppendPrintf(entry, "%s %s ", directiveName, fmt->name);
126 
127  for (Token *t = fmt->format; t; t = t->next) {
128  if (t->type == LFT_STRING)
129  storeAppendPrintf(entry, "%s", t->data.string);
130  else {
131  char argbuf[256];
132  char *arg = NULL;
133  ByteCode_t type = t->type;
134 
135  switch (type) {
136  /* special cases */
137 
138  case LFT_STRING:
139  break;
140 #if USE_ADAPTATION
142 #endif
143 #if ICAP_CLIENT
146 #endif
150 
151  if (t->data.header.separator != ',')
152  snprintf(argbuf, sizeof(argbuf), "%s:%c%s", t->data.header.header, t->data.header.separator, t->data.header.element);
153  else
154  snprintf(argbuf, sizeof(argbuf), "%s:%s", t->data.header.header, t->data.header.element);
155 
156  arg = argbuf;
157 
158  switch (type) {
160  type = LFT_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
161  break;
163  type = LFT_ADAPTED_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
164  break;
166  type = LFT_REPLY_HEADER_ELEM; // XXX: remove _ELEM?
167  break;
168 #if USE_ADAPTATION
171  break;
172 #endif
173 #if ICAP_CLIENT
176  break;
179  break;
180 #endif
181  default:
182  break;
183  }
184 
185  break;
186 
190 
191 #if USE_ADAPTATION
193 #endif
194 #if ICAP_CLIENT
197 #endif
198 
199  switch (type) {
202  break;
205  break;
208  break;
209 #if USE_ADAPTATION
212  break;
213 #endif
214 #if ICAP_CLIENT
217  break;
220  break;
221 #endif
222  default:
223  break;
224  }
225 
226  break;
227 
228  default:
229  if (t->data.string)
230  arg = t->data.string;
231 
232  break;
233  }
234 
235  entry->append("%", 1);
236 
237  switch (t->quote) {
238 
239  case LOG_QUOTE_QUOTES:
240  entry->append("\"", 1);
241  break;
242 
243  case LOG_QUOTE_MIMEBLOB:
244  entry->append("[", 1);
245  break;
246 
247  case LOG_QUOTE_URL:
248  entry->append("#", 1);
249  break;
250 
251  case LOG_QUOTE_RAW:
252  entry->append("'", 1);
253  break;
254 
255  case LOG_QUOTE_SHELL:
256  entry->append("/", 1);
257  break;
258 
259  case LOG_QUOTE_NONE:
260  break;
261  }
262 
263  if (t->left)
264  entry->append("-", 1);
265 
266  if (t->zero)
267  entry->append("0", 1);
268 
269  if (t->widthMin >= 0)
270  storeAppendPrintf(entry, "%d", t->widthMin);
271 
272  if (t->widthMax >= 0)
273  storeAppendPrintf(entry, ".%d", t->widthMax);
274 
275  if (arg)
276  storeAppendPrintf(entry, "{%s}", arg);
277 
278  storeAppendPrintf(entry, "%s", t->label);
279 
280  if (t->space)
281  entry->append(" ", 1);
282  }
283  }
284 
285  if (eol)
286  entry->append("\n", 1);
287  }
288 
289 }
290 
291 static void
292 log_quoted_string(const char *str, char *out)
293 {
294  char *p = out;
295 
296  while (*str) {
297  int l = strcspn(str, "\"\\\r\n\t");
298  memcpy(p, str, l);
299  str += l;
300  p += l;
301 
302  switch (*str) {
303 
304  case '\0':
305  break;
306 
307  case '\r':
308  *p = '\\';
309  ++p;
310  *p = 'r';
311  ++p;
312  ++str;
313  break;
314 
315  case '\n':
316  *p = '\\';
317  ++p;
318  *p = 'n';
319  ++p;
320  ++str;
321  break;
322 
323  case '\t':
324  *p = '\\';
325  ++p;
326  *p = 't';
327  ++p;
328  ++str;
329  break;
330 
331  default:
332  *p = '\\';
333  ++p;
334  *p = *str;
335  ++p;
336  ++str;
337  break;
338  }
339  }
340 
341  *p = '\0';
342 }
343 
349 static const Http::Message *
351 {
352  const Http::Message *msg = al->reply.getRaw();
353 #if ICAP_CLIENT
354  // al->icap.reqMethod is methodNone in access.log context
355  if (!msg && al->icap.reqMethod == Adaptation::methodReqmod)
356  msg = al->adapted_request;
357 #endif
358  return msg;
359 }
360 
363 static const Http::Message *
365 {
366 #if ICAP_CLIENT
367  // al->icap.reqMethod is methodNone in access.log context
368  if (al->icap.reqMethod == Adaptation::methodRespmod) {
369  // XXX: for now AccessLogEntry lacks virgin response headers
370  return nullptr;
371  }
372 #endif
373  return al->request;
374 }
375 
376 void
377 Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logSequenceNumber) const
378 {
379  static char tmp[1024];
380  SBuf sb;
381 
382  for (Token *fmt = format; fmt; fmt = fmt->next) { /* for each token */
383  const char *out = nullptr;
384  int quote = 0;
385  long int outint = 0;
386  int doint = 0;
387  int dofree = 0;
388  int64_t outoff = 0;
389  int dooff = 0;
390  struct timeval outtv = {};
391  int doMsec = 0;
392  int doSec = 0;
393  bool doUint64 = false;
394  uint64_t outUint64 = 0;
395 
396  switch (fmt->type) {
397 
398  case LFT_NONE:
399  out = "";
400  break;
401 
402  case LFT_STRING:
403  out = fmt->data.string;
404  break;
405 
407  al->getLogClientIp(tmp, sizeof(tmp));
408  out = tmp;
409  break;
410 
411  case LFT_CLIENT_FQDN:
412  out = al->getLogClientFqdn(tmp, sizeof(tmp));
413  break;
414 
415  case LFT_CLIENT_PORT:
416  if (al->request) {
417  outint = al->request->client_addr.port();
418  doint = 1;
419  } else if (al->tcpClient) {
420  outint = al->tcpClient->remote.port();
421  doint = 1;
422  }
423  break;
424 
425  case LFT_CLIENT_EUI:
426 #if USE_SQUID_EUI
427  // TODO make the ACL checklist have a direct link to any TCP details.
428  if (al->request && al->request->clientConnectionManager.valid() &&
431  if (conn->remote.isIPv4())
432  conn->remoteEui48.encode(tmp, sizeof(tmp));
433  else
434  conn->remoteEui64.encode(tmp, sizeof(tmp));
435  out = tmp;
436  }
437 #endif
438  break;
439 
441 #if USE_SQUID_EUI
442  if (al->request && al->request->clientConnectionManager.valid() &&
446  out = tmp;
447  }
448 #endif
449  break;
450 
452 #if USE_SQUID_EUI
453  if (al->request && al->request->clientConnectionManager.valid() &&
457  out = tmp;
458  }
459 #endif
460  break;
461 
463  if (al->hier.tcpServer)
464  out = al->hier.tcpServer->remote.toStr(tmp, sizeof(tmp));
465  break;
466 
468  out = al->hier.host;
469  break;
470 
471  case LFT_SERVER_PORT:
472  if (al->hier.tcpServer) {
473  outint = al->hier.tcpServer->remote.port();
474  doint = 1;
475  }
476  break;
477 
479  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw()))
480  out = addr->toStr(tmp, sizeof(tmp));
481  break;
482 
483  case LFT_CLIENT_LOCAL_IP:
484  if (al->tcpClient)
485  out = al->tcpClient->local.toStr(tmp, sizeof(tmp));
486  break;
487 
489  if (al->tcpClient) {
490  sb.appendf("0x%x", static_cast<uint32_t>(al->tcpClient->tos));
491  out = sb.c_str();
492  }
493  break;
494 
496  if (al->tcpClient) {
497  outUint64 = al->tcpClient->id.value;
498  doUint64 = true;
499  }
500  break;
501 
503  if (al->tcpClient) {
504  sb.appendf("0x%x", al->tcpClient->nfmark);
505  out = sb.c_str();
506  }
507  break;
508 
510  if (const auto port = FindListeningPortNumber(nullptr, al.getRaw())) {
511  outint = port;
512  doint = 1;
513  }
514  break;
515 
517  if (al->tcpClient) {
518  outint = al->tcpClient->local.port();
519  doint = 1;
520  }
521  break;
522 
524  case LFT_SERVER_LOCAL_IP:
525  if (al->hier.tcpServer)
526  out = al->hier.tcpServer->local.toStr(tmp, sizeof(tmp));
527  break;
528 
530  if (al->hier.tcpServer) {
531  outint = al->hier.tcpServer->local.port();
532  doint = 1;
533  }
534  break;
535 
537  if (al->hier.tcpServer) {
538  sb.appendf("0x%x", static_cast<uint32_t>(al->hier.tcpServer->tos));
539  out = sb.c_str();
540  }
541  break;
542 
544  if (al->hier.tcpServer) {
545  sb.appendf("0x%x", al->hier.tcpServer->nfmark);
546  out = sb.c_str();
547  }
548  break;
549 
551  if (al->request && al->request->clientConnectionManager.valid()) {
552  const auto &handshake = al->request->clientConnectionManager->preservedClientData;
553  if (const auto rawLength = handshake.length()) {
554  // add 1 byte to optimize the c_str() conversion below
555  char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1);
556 
557  struct base64_encode_ctx ctx;
558  base64_encode_init(&ctx);
559  auto encLength = base64_encode_update(&ctx, buf, rawLength, reinterpret_cast<const uint8_t*>(handshake.rawContent()));
560  encLength += base64_encode_final(&ctx, buf + encLength);
561 
562  sb.rawAppendFinish(buf, encLength);
563  out = sb.c_str();
564  }
565  }
566  break;
567 
569  // some platforms store time in 32-bit, some 64-bit...
570  outoff = static_cast<int64_t>(current_time.tv_sec);
571  dooff = 1;
572  break;
573 
574  case LFT_TIME_SUBSECOND:
575  outint = current_time.tv_usec / fmt->divisor;
576  doint = 1;
577  break;
578 
579  case LFT_TIME_LOCALTIME:
580  case LFT_TIME_GMT: {
581  const char *spec;
582  struct tm *t;
583  spec = fmt->data.string;
584 
585  if (fmt->type == LFT_TIME_LOCALTIME) {
586  if (!spec)
587  spec = "%d/%b/%Y:%H:%M:%S %z";
588  t = localtime(&squid_curtime);
589  } else {
590  if (!spec)
591  spec = "%d/%b/%Y:%H:%M:%S";
592 
593  t = gmtime(&squid_curtime);
594  }
595 
596  strftime(tmp, sizeof(tmp), spec, t);
597  out = tmp;
598  }
599  break;
600 
601  case LFT_TIME_START:
602  outtv = al->cache.start_time;
603  doSec = 1;
604  break;
605 
607  outtv = al->cache.trTime;
608  doMsec = 1;
609  break;
610 
612  struct timeval peerResponseTime;
613  if (al->hier.peerResponseTime(peerResponseTime)) {
614  outtv = peerResponseTime;
615  doMsec = 1;
616  }
617  break;
618 
620  struct timeval totalResponseTime;
621  if (al->hier.totalResponseTime(totalResponseTime)) {
622  outtv = totalResponseTime;
623  doMsec = 1;
624  }
625  }
626  break;
627 
628  case LFT_DNS_WAIT_TIME:
629  if (al->request && al->request->dnsWait >= 0) {
630  // TODO: microsecond precision for dns wait time.
631  // Convert milliseconds to timeval struct:
632  outtv.tv_sec = al->request->dnsWait / 1000;
633  outtv.tv_usec = (al->request->dnsWait % 1000) * 1000;
634  doMsec = 1;
635  }
636  break;
637 
638  case LFT_REQUEST_HEADER:
639  if (const Http::Message *msg = actualRequestHeader(al)) {
640  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
641  out = sb.c_str();
642  quote = 1;
643  }
644  break;
645 
647  if (al->adapted_request) {
648  sb = StringToSBuf(al->adapted_request->header.getByName(fmt->data.header.header));
649  out = sb.c_str();
650  quote = 1;
651  }
652  break;
653 
654  case LFT_REPLY_HEADER:
655  if (const Http::Message *msg = actualReplyHeader(al)) {
656  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
657  out = sb.c_str();
658  quote = 1;
659  }
660  break;
661 
662 #if USE_ADAPTATION
664  if (al->request) {
666  if (ah) {
667  ah->sumLogString(fmt->data.string, sb);
668  out = sb.c_str();
669  }
670  }
671  break;
672 
674  if (al->request) {
676  if (ah) {
677  ah->allLogString(fmt->data.string, sb);
678  out = sb.c_str();
679  }
680  }
681  break;
682 
684  if (al->request) {
686  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
687  sb = StringToSBuf(ah->allMeta.getByName(fmt->data.header.header));
688  out = sb.c_str();
689  quote = 1;
690  }
691  }
692  break;
693 
695  if (al->request) {
697  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
698  sb = ah->allMeta.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
699  out = sb.c_str();
700  quote = 1;
701  }
702  }
703  break;
704 
706  out = al->adapt.last_meta;
707  quote = 1;
708  break;
709 #endif
710 
711 #if ICAP_CLIENT
712  case LFT_ICAP_ADDR:
713  out = al->icap.hostAddr.toStr(tmp, sizeof(tmp));
714  break;
715 
716  case LFT_ICAP_SERV_NAME:
717  out = al->icap.serviceName.termedBuf();
718  break;
719 
721  out = al->icap.reqUri.termedBuf();
722  break;
723 
726  break;
727 
728  case LFT_ICAP_BYTES_SENT:
729  outoff = al->icap.bytesSent;
730  dooff = 1;
731  break;
732 
733  case LFT_ICAP_BYTES_READ:
734  outoff = al->icap.bytesRead;
735  dooff = 1;
736  break;
737 
739  if (al->icap.bodyBytesRead >= 0) {
740  outoff = al->icap.bodyBytesRead;
741  dooff = 1;
742  }
743  // else if icap.bodyBytesRead < 0, we do not have any http data,
744  // so just print a "-" (204 responses etc)
745  break;
746 
747  case LFT_ICAP_REQ_HEADER:
748  if (al->icap.request) {
749  sb = StringToSBuf(al->icap.request->header.getByName(fmt->data.header.header));
750  out = sb.c_str();
751  quote = 1;
752  }
753  break;
754 
756  if (al->icap.request) {
757  sb = al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
758  out = sb.c_str();
759  quote = 1;
760  }
761  break;
762 
764  if (al->icap.request) {
766  while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
767  sb.append(e->name);
768  sb.append(": ");
769  sb.append(StringToSBuf(e->value));
770  sb.append("\r\n");
771  }
772  out = sb.c_str();
773  quote = 1;
774  }
775  break;
776 
777  case LFT_ICAP_REP_HEADER:
778  if (al->icap.reply) {
779  sb = StringToSBuf(al->icap.reply->header.getByName(fmt->data.header.header));
780  out = sb.c_str();
781  quote = 1;
782  }
783  break;
784 
786  if (al->icap.reply) {
787  sb = al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
788  out = sb.c_str();
789  quote = 1;
790  }
791  break;
792 
794  if (al->icap.reply) {
796  while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
797  sb.append(e->name);
798  sb.append(": ");
799  sb.append(StringToSBuf(e->value));
800  sb.append("\r\n");
801  }
802  out = sb.c_str();
803  quote = 1;
804  }
805  break;
806 
808  outtv = al->icap.trTime;
809  doMsec = 1;
810  break;
811 
812  case LFT_ICAP_IO_TIME:
813  outtv = al->icap.ioTime;
814  doMsec = 1;
815  break;
816 
818  outint = al->icap.resStatus;
819  doint = 1;
820  break;
821 
822  case LFT_ICAP_OUTCOME:
823  out = al->icap.outcome;
824  break;
825 
826  case LFT_ICAP_TOTAL_TIME:
827  outtv = al->icap.processingTime;
828  doMsec = 1;
829  break;
830 #endif
832  if (const Http::Message *msg = actualRequestHeader(al)) {
833  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
834  out = sb.c_str();
835  quote = 1;
836  }
837  break;
838 
840  if (al->proxyProtocolHeader) {
841  sb = al->proxyProtocolHeader->getValues(fmt->data.headerId, fmt->data.header.separator);
842  out = sb.c_str();
843  quote = 1;
844  }
845  break;
846 
848  if (al->proxyProtocolHeader) {
849  sb = al->proxyProtocolHeader->toMime();
850  out = sb.c_str();
851  quote = 1;
852  }
853  break;
854 
856  if (al->proxyProtocolHeader) {
857  sb = al->proxyProtocolHeader->getElem(fmt->data.headerId, fmt->data.header.element, fmt->data.header.separator);
858  out = sb.c_str();
859  quote = 1;
860  }
861  break;
862 
864  if (al->adapted_request) {
865  sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
866  out = sb.c_str();
867  quote = 1;
868  }
869  break;
870 
872  if (const Http::Message *msg = actualReplyHeader(al)) {
873  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
874  out = sb.c_str();
875  quote = 1;
876  }
877  break;
878 
880 #if ICAP_CLIENT
882  // XXX: since AccessLogEntry::Headers lacks virgin response
883  // headers, do nothing for now
884  out = nullptr;
885  } else
886 #endif
887  {
888  // just headers without start-line and CRLF
889  // XXX: reconcile with '<h'
890  out = al->headers.request;
891  quote = 1;
892  }
893  break;
894 
896  // just headers without start-line and CRLF
897  // XXX: reconcile with '<h'
898  out = al->headers.adapted_request;
899  quote = 1;
900  break;
901 
902  case LFT_REPLY_ALL_HEADERS: {
903  MemBuf allHeaders;
904  allHeaders.init();
905  // status-line + headers + CRLF
906  // XXX: reconcile with '>h' and '>ha'
907  al->packReplyHeaders(allHeaders);
908  sb.assign(allHeaders.content(), allHeaders.contentSize());
909  out = sb.c_str();
910 #if ICAP_CLIENT
911  if (!out && al->icap.reqMethod == Adaptation::methodReqmod)
912  out = al->headers.adapted_request;
913 #endif
914  quote = 1;
915  }
916  break;
917 
918  case LFT_USER_NAME:
919 #if USE_AUTH
920  if (al->request && al->request->auth_user_request)
922 #endif
923  if (!out && al->request && al->request->extacl_user.size()) {
924  if (const char *t = al->request->extacl_user.termedBuf())
925  out = t;
926  }
927  if (!out)
928  out = strOrNull(al->getExtUser());
929 #if USE_OPENSSL
930  if (!out)
931  out = strOrNull(al->cache.ssluser);
932 #endif
933  if (!out)
934  out = strOrNull(al->getClientIdent());
935  break;
936 
937  case LFT_USER_LOGIN:
938 #if USE_AUTH
939  if (al->request && al->request->auth_user_request)
941 #endif
942  break;
943 
944  case LFT_USER_IDENT:
945  out = strOrNull(al->getClientIdent());
946  break;
947 
948  case LFT_USER_EXTERNAL:
949  out = strOrNull(al->getExtUser());
950  break;
951 
952  /* case LFT_USER_REALM: */
953  /* case LFT_USER_SCHEME: */
954 
955  // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
956  // but compiler complains if omitted
959  outint = al->http.code;
960  doint = 1;
961  break;
962 
964  if (al->hier.peer_reply_status != Http::scNone) {
965  outint = al->hier.peer_reply_status;
966  doint = 1;
967  }
968  break;
969  /* case LFT_HTTP_STATUS:
970  * out = statusline->text;
971  * quote = 1;
972  * break;
973  */
975  if (al->hier.bodyBytesRead >= 0) {
976  outoff = al->hier.bodyBytesRead;
977  dooff = 1;
978  }
979  // else if hier.bodyBytesRead < 0 we did not have any data exchange with
980  // a peer server so just print a "-" (eg requests served from cache,
981  // or internal error messages).
982  break;
983 
984  case LFT_SQUID_STATUS:
985  out = al->cache.code.c_str();
986  break;
987 
988  case LFT_SQUID_ERROR:
989  if (const auto error = al->error())
990  out = errorPageName(error->category);
991  break;
992 
994  if (const auto error = al->error()) {
995  if (const auto detail = error->detail) {
996  sb = detail->brief();
997  out = sb.c_str();
998  }
999  }
1000  break;
1001 
1002  case LFT_SQUID_HIERARCHY:
1003  if (al->hier.ping.timedout)
1004  mb.append("TIMEOUT_", 8);
1005  out = hier_code_str[al->hier.code];
1006  break;
1007 
1008  case LFT_MIME_TYPE:
1009  out = al->http.content_type;
1010  break;
1011 
1012  case LFT_CLIENT_REQ_METHOD:
1013  if (al->request) {
1014  sb = al->request->method.image();
1015  out = sb.c_str();
1016  quote = 1;
1017  }
1018  break;
1019 
1020  case LFT_CLIENT_REQ_URI:
1021  if (const auto uri = al->effectiveVirginUrl()) {
1022  sb = *uri;
1023  out = sb.c_str();
1024  quote = 1;
1025  }
1026  break;
1027 
1029  if (al->request) {
1030  sb = al->request->url.getScheme().image();
1031  out = sb.c_str();
1032  quote = 1;
1033  }
1034  break;
1035 
1037  if (al->request) {
1038  out = al->request->url.host();
1039  quote = 1;
1040  }
1041  break;
1042 
1044  if (al->request) {
1045  outint = al->request->url.port();
1046  doint = 1;
1047  }
1048  break;
1049 
1052  if (al->request) {
1053  sb = al->request->url.path();
1054  out = sb.c_str();
1055  quote = 1;
1056  }
1057  break;
1058 
1060  if (al->request) {
1061  sb.appendf("%u.%u", al->request->http_ver.major, al->request->http_ver.minor);
1062  out = sb.c_str();
1063  }
1064  break;
1065 
1066  case LFT_REQUEST_METHOD:
1067  if (al->hasLogMethod()) {
1068  sb = al->getLogMethod();
1069  out = sb.c_str();
1070  quote = 1;
1071  }
1072  break;
1073 
1074  case LFT_REQUEST_URI:
1075  if (!al->url.isEmpty()) {
1076  sb = al->url;
1077  out = sb.c_str();
1078  }
1079  break;
1080 
1082  case LFT_REQUEST_VERSION:
1083  sb.appendf("%u.%u", al->http.version.major, al->http.version.minor);
1084  out = sb.c_str();
1085  break;
1086 
1087  case LFT_SERVER_REQ_METHOD:
1088  if (al->adapted_request) {
1089  sb = al->adapted_request->method.image();
1090  out = sb.c_str();
1091  quote = 1;
1092  }
1093  break;
1094 
1095  case LFT_SERVER_REQ_URI:
1096  // adapted request URI sent to server/peer
1097  if (al->adapted_request) {
1099  out = sb.c_str();
1100  quote = 1;
1101  }
1102  break;
1103 
1105  if (al->adapted_request) {
1106  sb = al->adapted_request->url.getScheme().image();
1107  out = sb.c_str();
1108  quote = 1;
1109  }
1110  break;
1111 
1113  if (al->adapted_request) {
1114  out = al->adapted_request->url.host();
1115  quote = 1;
1116  }
1117  break;
1118 
1120  if (al->adapted_request) {
1121  outint = al->adapted_request->url.port();
1122  doint = 1;
1123  }
1124  break;
1125 
1127  if (al->adapted_request) {
1128  sb = al->adapted_request->url.path();
1129  out = sb.c_str();
1130  quote = 1;
1131  }
1132  break;
1133 
1135  if (al->adapted_request) {
1136  sb.appendf("%u.%u",
1139  out = tmp;
1140  }
1141  break;
1142 
1144  outoff = al->http.clientRequestSz.messageTotal();
1145  dooff = 1;
1146  break;
1147 
1149  outoff = al->http.clientRequestSz.header;
1150  dooff =1;
1151  break;
1152 
1153  /*case LFT_REQUEST_SIZE_BODY: */
1154  /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
1155 
1157  outoff = al->http.clientReplySz.messageTotal();
1158  dooff = 1;
1159  break;
1160 
1161  case LFT_REPLY_HIGHOFFSET:
1162  outoff = al->cache.highOffset;
1163  dooff = 1;
1164  break;
1165 
1166  case LFT_REPLY_OBJECTSIZE:
1167  outoff = al->cache.objectSize;
1168  dooff = 1;
1169  break;
1170 
1172  outint = al->http.clientReplySz.header;
1173  doint = 1;
1174  break;
1175 
1176  /*case LFT_REPLY_SIZE_BODY: */
1177  /*case LFT_REPLY_SIZE_BODY_NO_TE: */
1178 
1181  doint = 1;
1182  break;
1183  /*case LFT_SERVER_IO_SIZE_TOTAL: */
1184 
1185  case LFT_TAG:
1186  if (al->request) {
1187  out = al->request->tag.termedBuf();
1188  quote = 1;
1189  }
1190  break;
1191 
1192  case LFT_EXT_LOG:
1193  if (al->request) {
1194  out = al->request->extacl_log.termedBuf();
1195  quote = 1;
1196  }
1197  break;
1198 
1199  case LFT_SEQUENCE_NUMBER:
1200  outoff = logSequenceNumber;
1201  dooff = 1;
1202  break;
1203 
1204 #if USE_OPENSSL
1205  case LFT_SSL_BUMP_MODE: {
1206  const Ssl::BumpMode mode = static_cast<Ssl::BumpMode>(al->ssl.bumpMode);
1207  // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
1208  out = Ssl::bumpMode(mode);
1209  }
1210  break;
1211 
1213  if (al->request) {
1215  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1216  if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) {
1218  out = sb.c_str();
1219  }
1220  }
1221  }
1222  break;
1223 
1225  if (al->request) {
1227  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1228  if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) {
1230  out = sb.c_str();
1231  }
1232  }
1233  }
1234  break;
1235 
1236  case LFT_EXT_ACL_USER_CERT:
1237  if (al->request) {
1239  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1240  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1241  out = sslGetUserAttribute(ssl, fmt->data.header.header);
1242  }
1243  }
1244  break;
1245 
1247  if (al->request) {
1249  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1250  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1251  out = sslGetCAAttribute(ssl, fmt->data.header.header);
1252  }
1253  }
1254  break;
1255 
1257  if (const auto &cert = al->cache.sslClientCert) {
1258  sb = Security::SubjectName(*cert);
1259  out = sb.c_str();
1260  }
1261  break;
1262 
1264  if (const auto &cert = al->cache.sslClientCert) {
1265  sb = Security::IssuerName(*cert);
1266  out = sb.c_str();
1267  }
1268  break;
1269 
1270  case LFT_SSL_CLIENT_SNI:
1271  if (al->request && al->request->clientConnectionManager.valid()) {
1272  if (const ConnStateData *conn = al->request->clientConnectionManager.get()) {
1273  if (!conn->tlsClientSni().isEmpty()) {
1274  sb = conn->tlsClientSni();
1275  out = sb.c_str();
1276  }
1277  }
1278  }
1279  break;
1280 
1282  if (al->request && al->request->clientConnectionManager.valid()) {
1283  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1284  const char *separator = fmt->data.string ? fmt->data.string : ":";
1285  for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) {
1286  if (!sb.isEmpty())
1287  sb.append(separator);
1288  sb.append(Ssl::GetErrorName(sslError->element.code, true));
1289  if (sslError->element.depth >= 0)
1290  sb.appendf("@depth=%d", sslError->element.depth);
1291  }
1292  if (!sb.isEmpty())
1293  out = sb.c_str();
1294  }
1295  }
1296  break;
1297 
1301  if (al->request && al->request->clientConnectionManager.valid()) {
1302  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1303  if (X509 *serverCert = srvBump->serverCert.get()) {
1304  if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT)
1305  out = Ssl::GetX509UserAttribute(serverCert, "DN");
1306  else if (fmt->type == LFT_SSL_SERVER_CERT_ISSUER)
1307  out = Ssl::GetX509CAAttribute(serverCert, "DN");
1308  else {
1309  assert(fmt->type == LFT_SSL_SERVER_CERT_WHOLE);
1310  sb = Ssl::GetX509PEM(serverCert);
1311  out = sb.c_str();
1312  quote = 1;
1313  }
1314  }
1315  }
1316  }
1317  break;
1318 
1320  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1322  break;
1323 
1325  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1327  break;
1328 
1330  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1331  out = al->tcpClient->hasTlsNegotiations()->helloVersion();
1332  break;
1333 
1335  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1337  break;
1338 
1340  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1342  break;
1343 
1345  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1347  break;
1348 
1350  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1351  out = al->tcpClient->hasTlsNegotiations()->cipherName();
1352  break;
1353 
1355  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1356  out = al->hier.tcpServer->hasTlsNegotiations()->cipherName();
1357  break;
1358 #endif
1359 
1361  assert(LFT_REQUEST_URLGROUP_OLD_2X == 0); // should never happen.
1362  break;
1363 
1364  case LFT_NOTE:
1365  tmp[0] = fmt->data.header.separator;
1366  tmp[1] = '\0';
1367  if (fmt->data.header.header && *fmt->data.header.header) {
1368  const char *separator = tmp;
1369  static SBuf note;
1370 #if USE_ADAPTATION
1372  if (ah && ah->metaHeaders) {
1373  if (ah->metaHeaders->find(note, fmt->data.header.header, separator))
1374  sb.append(note);
1375  }
1376 #endif
1377  if (al->notes) {
1378  if (al->notes->find(note, fmt->data.header.header, separator)) {
1379  if (!sb.isEmpty())
1380  sb.append(separator);
1381  sb.append(note);
1382  }
1383  }
1384  out = sb.c_str();
1385  quote = 1;
1386  } else {
1387  // if no argument given use default "\r\n" as notes separator
1388  const char *separator = fmt->data.string ? tmp : "\r\n";
1389 #if USE_ADAPTATION
1391  if (ah && ah->metaHeaders && !ah->metaHeaders->empty())
1392  sb.append(ah->metaHeaders->toString(separator));
1393 #endif
1394  if (al->notes && !al->notes->empty())
1395  sb.append(al->notes->toString(separator));
1396 
1397  out = sb.c_str();
1398  quote = 1;
1399  }
1400  break;
1401 
1402  case LFT_CREDENTIALS:
1403 #if USE_AUTH
1404  if (al->request && al->request->auth_user_request)
1406 #endif
1407  break;
1408 
1409  case LFT_PERCENT:
1410  out = "%";
1411  break;
1412 
1413  case LFT_EXT_ACL_NAME:
1414  out = al->lastAclName;
1415  break;
1416 
1417  case LFT_EXT_ACL_DATA:
1418  if (!al->lastAclData.isEmpty())
1419  out = al->lastAclData.c_str();
1420  break;
1421 
1422  case LFT_MASTER_XACTION:
1423  if (al->request) {
1424  doUint64 = true;
1425  outUint64 = static_cast<uint64_t>(al->request->masterXaction->id.value);
1426  break;
1427  }
1428  }
1429 
1430  if (dooff) {
1431  sb.appendf("%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff);
1432  out = sb.c_str();
1433 
1434  } else if (doint) {
1435  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
1436  out = sb.c_str();
1437  } else if (doUint64) {
1438  sb.appendf("%0*" PRIu64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outUint64);
1439  out = sb.c_str();
1440  } else if (doMsec) {
1441  if (fmt->widthMax < 0) {
1442  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, tvToMsec(outtv));
1443  } else {
1444  int precision = fmt->widthMax;
1445  sb.appendf("%0*" PRId64 ".%0*" PRId64 "", fmt->zero && (fmt->widthMin - precision - 1 >= 0) ? fmt->widthMin - precision - 1 : 0, static_cast<int64_t>(outtv.tv_sec * 1000 + outtv.tv_usec / 1000), precision, static_cast<int64_t>((outtv.tv_usec % 1000 )* (1000 / fmt->divisor)));
1446  }
1447  out = sb.c_str();
1448  } else if (doSec) {
1449  int precision = fmt->widthMax >=0 ? fmt->widthMax :3;
1450  sb.appendf("%0*" PRId64 ".%0*d", fmt->zero && (fmt->widthMin - precision - 1 >= 0) ? fmt->widthMin - precision - 1 : 0, static_cast<int64_t>(outtv.tv_sec), precision, (int)(outtv.tv_usec / fmt->divisor));
1451  out = sb.c_str();
1452  }
1453 
1454  if (out && *out) {
1455  if (quote || fmt->quote != LOG_QUOTE_NONE) {
1456  // Do not write to the tmp buffer because it may contain the to-be-quoted value.
1457  static char quotedOut[2 * sizeof(tmp)];
1458  static_assert(sizeof(quotedOut) > 0, "quotedOut has zero length");
1459  quotedOut[0] = '\0';
1460 
1461  char *newout = NULL;
1462  int newfree = 0;
1463 
1464  switch (fmt->quote) {
1465 
1466  case LOG_QUOTE_NONE:
1467  newout = rfc1738_escape_unescaped(out);
1468  break;
1469 
1470  case LOG_QUOTE_QUOTES: {
1471  size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
1472  if (out_len >= sizeof(tmp)) {
1473  newout = (char *)xmalloc(out_len);
1474  newfree = 1;
1475  } else
1476  newout = quotedOut;
1477  log_quoted_string(out, newout);
1478  }
1479  break;
1480 
1481  case LOG_QUOTE_MIMEBLOB:
1482  newout = QuoteMimeBlob(out);
1483  newfree = 1;
1484  break;
1485 
1486  case LOG_QUOTE_URL:
1487  newout = rfc1738_escape(out);
1488  break;
1489 
1490  case LOG_QUOTE_SHELL: {
1491  MemBuf mbq;
1492  mbq.init();
1493  strwordquote(&mbq, out);
1494  newout = mbq.content();
1495  mbq.stolen = 1;
1496  newfree = 1;
1497  }
1498  break;
1499 
1500  case LOG_QUOTE_RAW:
1501  break;
1502  }
1503 
1504  if (newout) {
1505  if (dofree)
1506  safe_free(out);
1507 
1508  out = newout;
1509 
1510  dofree = newfree;
1511  }
1512  }
1513 
1514  // enforce width limits if configured
1515  const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff && !doMsec && !doSec && !doUint64;
1516  if (haveMaxWidth || fmt->widthMin) {
1517  const int minWidth = fmt->widthMin >= 0 ?
1518  fmt->widthMin :0;
1519  const int maxWidth = haveMaxWidth ?
1520  fmt->widthMax : strlen(out);
1521 
1522  if (fmt->left)
1523  mb.appendf("%-*.*s", minWidth, maxWidth, out);
1524  else
1525  mb.appendf("%*.*s", minWidth, maxWidth, out);
1526  } else
1527  mb.append(out, strlen(out));
1528  } else {
1529  mb.append("-", 1);
1530  }
1531 
1532  if (fmt->space)
1533  mb.append(" ", 1);
1534 
1535  sb.clear();
1536 
1537  if (dofree)
1538  safe_free(out);
1539  }
1540 }
1541 
const char * sslGetCAAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:860
unsigned short FindListeningPortNumber(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:881
@ LFT_ICAP_TR_RESPONSE_TIME
Definition: ByteCode.h:210
@ LFT_LOCAL_LISTENING_IP
Definition: ByteCode.h:54
@ LFT_TRANSPORT_CLIENT_CONNECTION_ID
Definition: ByteCode.h:49
@ LFT_TLS_CLIENT_NEGOTIATED_VERSION
Definition: ByteCode.h:226
@ LFT_EXT_ACL_USER_CERT_RAW
Definition: ByteCode.h:242
Value value
instance identifier
Definition: InstanceId.h:69
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:162
@ LFT_SQUID_ERROR_DETAIL
Definition: ByteCode.h:173
@ LFT_CLIENT_LOCAL_PORT
Definition: ByteCode.h:44
Token * next
Definition: Token.h:71
const char * quote
Definition: html_quote.c:21
@ LFT_ICAP_REQUEST_METHOD
Definition: ByteCode.h:197
const char * getClientIdent() const
Fetch the client IDENT string, or nil if none is available.
unsigned int major
major version number
const char * helloVersion() const
String representation of the received TLS hello message version.
@ LFT_ICAP_SERV_NAME
Definition: ByteCode.h:195
int64_t bytesRead
number of bytes read from ICAP server so far
AnyP::ProtocolVersion http_ver
Definition: Message.h:73
#define base64_encode_len(length)
Definition: base64.h:169
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
@ LFT_ICAP_BODY_BYTES_READ
Definition: ByteCode.h:200
@ LFT_CLIENT_REQ_URLSCHEME
Definition: ByteCode.h:73
@ LFT_SSL_SERVER_CERT_ERRORS
Definition: ByteCode.h:224
@ LFT_USER_NAME
Definition: ByteCode.h:149
void port(unsigned short p)
Definition: Uri.h:94
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
common parts of HttpRequest and HttpReply
Definition: Message.h:26
@ LFT_ADAPTATION_LAST_ALL_HEADERS
Definition: ByteCode.h:187
#define xmalloc
Cbc * valid() const
was set and is valid
Definition: CbcPointer.h:41
@ LOG_QUOTE_URL
Definition: ByteCode.h:263
@ LFT_ICAP_IO_TIME
Definition: ByteCode.h:211
HttpHeader allMeta
All REQMOD and RESPMOD meta headers merged. Last field wins conflicts.
Definition: History.h:63
@ LFT_ADAPTATION_LAST_HEADER
Definition: ByteCode.h:185
@ LFT_TAG
Definition: ByteCode.h:177
@ LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME
Definition: ByteCode.h:167
virtual ~Format()
Definition: Format.cc:49
@ LFT_ICAP_REQ_HEADER_ELEM
Definition: ByteCode.h:203
const char * getLogClientFqdn(char *buf, size_t bufSize) const
virtual const char * credentialsStr()=0
@ scNone
Definition: StatusCode.h:21
const Error * error() const
HttpHeader header
Definition: Message.h:75
@ LFT_CLIENT_LOCAL_IP
Definition: ByteCode.h:43
Http::StatusCode peer_reply_status
last HTTP status code received
@ LFT_PROXY_PROTOCOL_RECEIVED_HEADER
Definition: ByteCode.h:253
bool isEmpty() const
Definition: SBuf.h:424
@ LFT_CLIENT_EUI
Definition: ByteCode.h:40
@ LFT_SSL_USER_CERT_SUBJECT
Definition: ByteCode.h:219
ssize_t HttpHeaderPos
Definition: HttpHeader.h:45
@ LFT_REQUEST_VERSION
Definition: ByteCode.h:86
Eui::Eui64 remoteEui64
Definition: Connection.h:178
@ LFT_SERVER_LOCAL_IP_OLD_27
Definition: ByteCode.h:65
@ LFT_USER_LOGIN
Definition: ByteCode.h:150
@ LFT_TLS_CLIENT_SUPPORTED_VERSION
Definition: ByteCode.h:232
@ LFT_SERVER_REQ_URLDOMAIN
Definition: ByteCode.h:103
String reqUri
ICAP Request-URI.
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
Definition: base64.c:308
InstanceId< Connection, uint64_t > id
Definition: Connection.h:181
const char * GetErrorName(const Security::ErrorCode code, const bool prefixRawCode=false)
Definition: ErrorDetail.h:36
bool encode(char *buf, const int len) const
Definition: Eui48.cc:119
@ LFT_SSL_SERVER_CERT_ISSUER
Definition: ByteCode.h:223
#define HttpHeaderInitPos
Definition: HttpHeader.h:48
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:830
void error(char *format,...)
char * QuoteMimeBlob(const char *header)
Definition: Quoting.cc:43
unsigned int minor
minor version number
HttpRequest * request
ICAP request.
void init(mb_size_t szInit, mb_size_t szMax)
Definition: MemBuf.cc:93
@ LOG_QUOTE_RAW
Definition: ByteCode.h:265
int parse(const char *def, enum Quoting *quote)
Definition: Token.cc:291
@ LFT_EXT_LOG
Definition: ByteCode.h:178
Definition: SBuf.h:87
BumpMode
Definition: support.h:126
CbDataList * next
Definition: CbDataList.h:31
@ LFT_REQUEST_METHOD
Definition: ByteCode.h:81
const SBuf * effectiveVirginUrl() const
GETX509PEM GetX509PEM
Definition: support.h:115
@ LFT_SQUID_ERROR
Definition: ByteCode.h:172
#define xstrdup
ByteCode_t
Definition: ByteCode.h:30
@ LFT_CLIENT_REQ_URI
Definition: ByteCode.h:72
const char * errorPageName(int pageId)
error ID to string
Definition: errorpage.cc:663
class AccessLogEntry::SslDetails ssl
#define PRIu64
Definition: types.h:120
GETX509ATTRIBUTE GetX509CAAttribute
Definition: support.h:112
@ LFT_SERVER_LOCAL_IP
Definition: ByteCode.h:64
Auth::UserRequest::Pointer auth_user_request
Definition: HttpRequest.h:127
@ LFT_MIME_TYPE
Definition: ByteCode.h:176
HierarchyLogEntry hier
int type
Definition: errorpage.cc:152
const char * negotiatedVersion() const
String representation of TLS negotiated version.
C * getRaw() const
Definition: RefCount.h:80
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:209
@ LFT_USER_EXTERNAL
Definition: ByteCode.h:154
struct timeval start_time
The time the master transaction started.
const SBuf & image() const
int dnsWait
sum of DNS lookup delays in milliseconds, for dt
Definition: HttpRequest.h:159
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
@ LFT_REQUEST_URLGROUP_OLD_2X
Definition: ByteCode.h:87
#define strOrNull(s)
Convert a string to NULL pointer if it is "".
Definition: Format.cc:38
const char * toString(const char *sep="\r\n") const
Definition: Notes.cc:286
struct timeval trTime
The response time.
@ LFT_SQUID_STATUS
Definition: ByteCode.h:171
@ LFT_REQUEST_HEADER
Definition: ByteCode.h:90
@ LFT_SERVER_REQ_URLSCHEME
Definition: ByteCode.h:102
#define rfc1738_escape(x)
Definition: rfc1738.h:52
AnyP::ProtocolVersion version
NotePairs::Pointer notes
bool isIPv4() const
Definition: Address.cc:158
bool empty() const
Definition: Notes.h:253
@ LFT_TIME_LOCALTIME
Definition: ByteCode.h:160
Token * format
Definition: Format.h:60
@ LFT_ADAPTED_REQUEST_HEADER
Definition: ByteCode.h:95
@ LFT_SERVER_IP_ADDRESS
Definition: ByteCode.h:59
@ LFT_TIME_START
Definition: ByteCode.h:162
@ LFT_ICAP_TOTAL_TIME
Definition: ByteCode.h:192
bool parse(const char *def)
Definition: Format.cc:66
String extacl_user
Definition: HttpRequest.h:178
SBuf SubjectName(Certificate &)
The SubjectName field of the given certificate (if found) or an empty SBuf.
Definition: Certificate.cc:68
SBuf lastAclData
string for external_acl_type DATA format code
static int port
Definition: ldap_backend.cc:69
@ LOG_QUOTE_NONE
Definition: ByteCode.h:260
@ LFT_TLS_SERVER_NEGOTIATED_CIPHER
Definition: ByteCode.h:229
@ LFT_REPLY_HIGHOFFSET
Definition: ByteCode.h:140
@ LFT_CLIENT_FQDN
Definition: ByteCode.h:38
size_t AssembleOne(const char *start, MemBuf &buf, const AccessLogEntryPointer &ale)
Definition: Format.cc:99
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition: Address.cc:792
@ LFT_SERVER_LOCAL_PORT
Definition: ByteCode.h:66
class AccessLogEntry::HttpDetails http
AnyP::UriScheme const & getScheme() const
Definition: Uri.h:67
const char * c_str() const
compute the status access.log field
Definition: LogTags.cc:66
@ LFT_SSL_USER_CERT_ISSUER
Definition: ByteCode.h:220
@ LFT_ADAPTATION_LAST_HEADER_ELEM
Definition: ByteCode.h:186
@ LFT_ICAP_STATUS_CODE
Definition: ByteCode.h:213
@ LFT_PEER_RESPONSE_TIME
Definition: ByteCode.h:166
@ LFT_SERVER_REQ_VERSION
Definition: ByteCode.h:107
@ LFT_REQUEST_URLPATH_OLD_31
Definition: ByteCode.h:83
Format * next
Definition: Format.h:61
@ LFT_TIME_GMT
Definition: ByteCode.h:161
class AccessLogEntry::IcapLogEntry icap
@ LFT_TLS_CLIENT_RECEIVED_HELLO_VERSION
Definition: ByteCode.h:230
HttpRequest * request
bool encode(char *buf, const int len) const
Definition: Eui64.cc:34
@ LFT_SERVER_LOCAL_NFMARK
Definition: ByteCode.h:68
@ LOG_QUOTE_SHELL
Definition: ByteCode.h:264
@ LFT_MASTER_XACTION
Definition: ByteCode.h:238
@ LFT_CLIENT_REQUEST_SIZE_TOTAL
Definition: ByteCode.h:110
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
Definition: gadgets.cc:17
@ LFT_TLS_SERVER_NEGOTIATED_VERSION
Definition: ByteCode.h:227
#define NULL
Definition: types.h:166
char * last_meta
image of the last ICAP response header or eCAP meta received
@ LFT_ICAP_BYTES_READ
Definition: ByteCode.h:199
@ LFT_ADAPTATION_ALL_XACT_TIMES
Definition: ByteCode.h:184
@ LFT_ICAP_REP_HEADER
Definition: ByteCode.h:206
@ LFT_TLS_CLIENT_NEGOTIATED_CIPHER
Definition: ByteCode.h:228
@ LFT_HTTP_SENT_STATUS_CODE_OLD_30
Definition: ByteCode.h:122
@ LFT_REQUEST_URI
Definition: ByteCode.h:82
@ LFT_SERVER_REQ_URLPATH
Definition: ByteCode.h:105
const Security::NegotiationHistory * hasTlsNegotiations() const
Definition: Connection.h:136
@ LFT_HTTP_BODY_BYTES_READ
Definition: ByteCode.h:126
uint64_t header
Definition: MessageSizes.h:21
unsigned short port() const
Definition: Address.cc:778
Definition: MemBuf.h:24
SBuf StringToSBuf(const String &s)
create a new SBuf from a String by copying contents
Definition: StringConvert.h:17
@ LFT_TLS_SERVER_SUPPORTED_VERSION
Definition: ByteCode.h:233
Adaptation::Icap::XactOutcome outcome
final transaction status
Ip::Address local
Definition: Connection.h:144
@ LFT_DNS_WAIT_TIME
Definition: ByteCode.h:168
Format(const char *name)
Definition: Format.cc:42
const char * lastAclName
string for external_acl_type ACL format code
@ LFT_STRING
Definition: ByteCode.h:34
@ LFT_ICAP_OUTCOME
Definition: ByteCode.h:212
@ LFT_CLIENT_REQUEST_SIZE_HEADERS
Definition: ByteCode.h:111
unsigned stolen
Definition: MemBuf.h:151
@ LFT_EXT_ACL_CLIENT_EUI64
Definition: ByteCode.h:248
Comm::ConnectionPointer tcpClient
TCP/IP level details about the client connection.
@ LFT_EXT_ACL_USER_CERTCHAIN_RAW
Definition: ByteCode.h:243
int64_t bytesSent
number of bytes sent to ICAP server so far
@ LFT_CLIENT_REQ_METHOD
Definition: ByteCode.h:71
bool peerResponseTime(struct timeval &responseTime)
Definition: access_log.cc:316
struct timeval ioTime
Transaction I/O time. The timer starts when the first ICAP request byte is scheduled for sending and ...
bool find(SBuf &resultNote, const char *noteKey, const char *sep=",") const
Definition: Notes.cc:272
#define safe_free(x)
Definition: xalloc.h:73
@ LFT_CLIENT_REQ_URLPATH
Definition: ByteCode.h:76
@ LFT_REQUEST_ALL_HEADERS
Definition: ByteCode.h:92
@ LFT_REPLY_HEADER
Definition: ByteCode.h:129
Ip::Address remote
Definition: Connection.h:147
MasterXaction::Pointer masterXaction
the master transaction this request belongs to. Never nil.
Definition: HttpRequest.h:238
int conn
the current server connection FD
Definition: Transport.cc:26
#define assert(EX)
Definition: assert.h:19
char const * termedBuf() const
Definition: SquidString.h:92
@ LFT_SERVER_LOCAL_TOS
Definition: ByteCode.h:67
@ LFT_EXT_ACL_USER_CA_CERT
Definition: ByteCode.h:245
@ LFT_EXT_ACL_DATA
Definition: ByteCode.h:250
SBuf image() const
Definition: UriScheme.h:50
class AccessLogEntry::CacheDetails cache
SBuf IssuerName(Certificate &)
The Issuer field of the given certificate (if found) or an empty SBuf.
Definition: Certificate.cc:28
@ LFT_ICAP_REP_ALL_HEADERS
Definition: ByteCode.h:208
@ LFT_USER_IDENT
Definition: ByteCode.h:151
MessageSizes clientRequestSz
counters for the original request received from client
NotePairs::Pointer metaHeaders
Definition: History.h:66
HttpReply * reply
ICAP reply.
Eui::Eui48 remoteEui48
Definition: Connection.h:177
@ LFT_TIME_TO_HANDLE_REQUEST
Definition: ByteCode.h:165
@ LFT_ICAP_REQ_ALL_HEADERS
Definition: ByteCode.h:204
@ LFT_ICAP_REQ_HEADER
Definition: ByteCode.h:202
@ LFT_ICAP_REP_HEADER_ELEM
Definition: ByteCode.h:207
class AccessLogEntry::Headers headers
const char * c_str()
Definition: SBuf.cc:516
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition: base64.c:232
@ LFT_CLIENT_IP_ADDRESS
Definition: ByteCode.h:37
String serviceName
ICAP service name.
const char * methodStr(Method)
Definition: Elements.cc:15
String extacl_log
Definition: HttpRequest.h:182
time_t squid_curtime
Definition: stub_libtime.cc:20
void allLogString(const char *serviceId, SBuf &)
dump individual xaction times to a string
Definition: History.cc:67
@ LFT_REPLY_OBJECTSIZE
Definition: ByteCode.h:141
int cur
Definition: ModDevPoll.cc:74
Comm::ConnectionPointer clientConnection
Definition: Server.h:98
const char * sslGetUserAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:847
class AccessLogEntry::AdaptationDetails adapt
#define xfree
@ LFT_ADAPTED_REPLY_SIZE_TOTAL
Definition: ByteCode.h:139
@ LFT_ADAPTATION_SUM_XACT_TIMES
Definition: ByteCode.h:183
@ LFT_CLIENT_PORT
Definition: ByteCode.h:39
@ LFT_SERVER_REQ_URLPORT
Definition: ByteCode.h:104
@ LFT_EXT_ACL_NAME
Definition: ByteCode.h:249
RefCount< Adaptation::History > Pointer
Definition: History.h:27
@ LFT_ADAPTED_REPLY_SIZE_HEADERS
Definition: ByteCode.h:142
struct timeval trTime
Transaction response time. The timer starts when the ICAP transaction is created and stops when the r...
void strwordquote(MemBuf *mb, const char *str)
Definition: tools.cc:1077
@ LFT_EXT_ACL_USER_CERT
Definition: ByteCode.h:244
Adaptation::History::Pointer adaptHistory(bool createIfNone=false) const
Returns possibly nil history, creating it if requested.
Definition: HttpRequest.cc:405
SBuf preservedClientData
Definition: client_side.h:350
Security::CertPointer sslClientCert
cert received from the client
const Ip::Address * FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:872
@ LFT_TLS_SERVER_RECEIVED_HELLO_VERSION
Definition: ByteCode.h:231
@ LFT_PROXY_PROTOCOL_RECEIVED_ALL_HEADERS
Definition: ByteCode.h:255
void sumLogString(const char *serviceId, SBuf &)
dump xaction times, merging retried and retry times together
Definition: History.cc:83
#define fd_table
Definition: fde.h:189
#define rfc1738_escape_unescaped(x)
Definition: rfc1738.h:59
uint64_t messageTotal() const
total message size
Definition: MessageSizes.h:27
int64_t bodyBytesRead
number of body bytes received from the next hop or -1
Comm::ConnectionPointer tcpServer
TCP/IP level details of the last peer/server connection.
@ LFT_SEQUENCE_NUMBER
Definition: ByteCode.h:180
String getByName(const SBuf &name) const
Definition: HttpHeader.cc:902
ProxyProtocol::HeaderPointer proxyProtocolHeader
see ConnStateData::proxyProtocolHeader_
@ LFT_REPLY_ALL_HEADERS
Definition: ByteCode.h:131
HttpRequestMethod method
Definition: HttpRequest.h:114
void path(const char *p)
Definition: Uri.h:99
const char * hier_code_str[]
@ LFT_ADAPTED_REQUEST_HEADER_ELEM
Definition: ByteCode.h:96
@ LFT_SERVER_PORT
Definition: ByteCode.h:61
HttpRequest * adapted_request
@ methodRespmod
Definition: Elements.h:17
struct timeval processingTime
total ICAP processing time
@ LOG_QUOTE_QUOTES
Definition: ByteCode.h:261
Http::StatusCode resStatus
ICAP response status code.
SBuf getByNameListMember(const char *name, const char *member, const char separator) const
Definition: HttpHeader.cc:971
@ LFT_ADAPTED_REQUEST_ALL_HEADERS
Definition: ByteCode.h:97
char * content()
start of the added data
Definition: MemBuf.h:41
MessageSizes clientReplySz
counters for the response sent to client
@ LFT_CLIENT_REQ_VERSION
Definition: ByteCode.h:78
size_type size() const
Definition: SquidString.h:73
@ LOG_QUOTE_MIMEBLOB
Definition: ByteCode.h:262
GETX509ATTRIBUTE GetX509UserAttribute
Definition: support.h:109
void getLogClientIp(char *buf, size_t bufsz) const
@ LFT_PROXY_PROTOCOL_RECEIVED_HEADER_ELEM
Definition: ByteCode.h:254
@ LFT_CLIENT_REQ_URLDOMAIN
Definition: ByteCode.h:74
char const * username() const
Definition: UserRequest.cc:32
@ LFT_CLIENT_LOCAL_NFMARK
Definition: ByteCode.h:47
static void log_quoted_string(const char *str, char *out)
Definition: Format.cc:292
@ LFT_HTTP_SENT_STATUS_CODE
Definition: ByteCode.h:123
#define DBG_IMPORTANT
Definition: Stream.h:41
Ssl::ServerBump * serverBump()
Definition: client_side.h:286
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
Definition: base64.c:265
void packReplyHeaders(MemBuf &mb) const
dump all reply headers (for sending or risky logging)
@ LFT_TIME_SECONDS_SINCE_EPOCH
Definition: ByteCode.h:158
#define MYNAME
Definition: Stream.h:238
@ LFT_REQUEST_HEADER_ELEM
Definition: ByteCode.h:91
@ LFT_SSL_SERVER_CERT_WHOLE
Definition: ByteCode.h:225
bool hasLogMethod() const
whether we know what the request method is
void assemble(MemBuf &mb, const AccessLogEntryPointer &al, int logSequenceNumber) const
assemble the state information into a formatted line.
Definition: Format.cc:377
@ LFT_REQUEST_VERSION_OLD_2X
Definition: ByteCode.h:85
#define PRId64
Definition: types.h:110
@ methodReqmod
Definition: Elements.h:17
@ LFT_SERVER_REQ_METHOD
Definition: ByteCode.h:100
@ LFT_CLIENT_IO_SIZE_TOTAL
Definition: ByteCode.h:146
static const Http::Message * actualReplyHeader(const AccessLogEntry::Pointer &al)
Definition: Format.cc:350
char host[SQUIDHOSTNAMELEN]
@ LFT_SSL_BUMP_MODE
Definition: ByteCode.h:218
@ LFT_PERCENT
Definition: ByteCode.h:237
bool totalResponseTime(struct timeval &responseTime)
Definition: access_log.cc:343
@ LFT_CLIENT_REQ_URLPORT
Definition: ByteCode.h:75
long int tvToMsec(struct timeval &t)
Definition: gadgets.h:93
virtual void append(char const *, int)
Appends a c-string to existing packed data.
Definition: store.cc:778
@ LFT_REPLY_HEADER_ELEM
Definition: ByteCode.h:130
@ LFT_HTTP_RECEIVED_STATUS_CODE
Definition: ByteCode.h:124
@ LFT_NONE
Definition: ByteCode.h:31
static const Http::Message * actualRequestHeader(const AccessLogEntry::Pointer &al)
Definition: Format.cc:364
@ LFT_SSL_CLIENT_SNI
Definition: ByteCode.h:221
int bumpMode
whether and how the request was SslBumped
@ LFT_CLIENT_HANDSHAKE
Definition: ByteCode.h:51
static struct stat sb
Definition: squidclient.cc:71
@ LFT_NOTE
Definition: ByteCode.h:236
@ LFT_CREDENTIALS
Definition: ByteCode.h:215
InstanceId< MasterXaction, uint64_t > id
transaction ID.
Definition: MasterXaction.h:60
HttpHeaderEntry * getEntry(HttpHeaderPos *pos) const
Definition: HttpHeader.cc:612
Ip::Address hostAddr
ICAP server IP address.
@ LFT_SERVER_REQ_URI
Definition: ByteCode.h:101
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
Definition: HttpRequest.cc:752
@ LFT_ICAP_REQUEST_URI
Definition: ByteCode.h:196
Ip::Address client_addr
Definition: HttpRequest.h:149
@ LFT_TIME_SUBSECOND
Definition: ByteCode.h:159
@ LFT_SSL_SERVER_CERT_SUBJECT
Definition: ByteCode.h:222
void host(const char *src)
Definition: Uri.cc:99
void dump(StoreEntry *entry, const char *directiveName, bool eol=true) const
dump this whole list of formats into the provided StoreEntry
Definition: Format.cc:117
@ LFT_ICAP_ADDR
Definition: ByteCode.h:194
Adaptation::Icap::ICAP::Method reqMethod
ICAP request method.
const char * getExtUser() const
Fetch the external ACL provided 'user=' string, or nil if none is available.
const char * supportedVersion() const
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
String tag
Definition: HttpRequest.h:176
const char * bumpMode(int bm)
Definition: support.h:138
@ LFT_CLIENT_LOCAL_TOS
Definition: ByteCode.h:46
const SBuf Dash
@ LFT_SERVER_FQDN_OR_PEER_NAME
Definition: ByteCode.h:60
SBuf getLogMethod() const
Fetch the transaction method string (ICP opcode, HTCP opcode or HTTP method)
nfmark_t nfmark
Definition: Connection.h:161
@ LFT_LOCAL_LISTENING_PORT
Definition: ByteCode.h:55
SBuf sslGetUserCertificatePEM(SSL *ssl)
Definition: support.cc:880
@ LFT_EXT_ACL_CLIENT_EUI48
Definition: ByteCode.h:247
@ LFT_ICAP_BYTES_SENT
Definition: ByteCode.h:198
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:232
Quoting
Quoting style for a format output.
Definition: ByteCode.h:259
int timedout
Definition: PingData.h:42
@ LFT_SQUID_HIERARCHY
Definition: ByteCode.h:174

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors