Format.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2020 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 "err_detail_type.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 "fqdncache.h"
21 #include "http/Stream.h"
22 #include "HttpRequest.h"
23 #include "MemBuf.h"
24 #include "proxyp/Header.h"
25 #include "rfc1738.h"
26 #include "sbuf/Stream.h"
27 #include "sbuf/StringConvert.h"
28 #include "security/CertError.h"
30 #include "SquidTime.h"
31 #include "Store.h"
32 #include "tools.h"
33 #if USE_OPENSSL
34 #include "ssl/ErrorDetail.h"
35 #include "ssl/ServerBump.h"
36 #endif
37 
39 #define strOrNull(s) ((s)==NULL||(s)[0]=='\0'?NULL:(s))
40 
41 const SBuf Format::Dash("-");
42 
43 Format::Format::Format(const char *n) :
44  format(NULL),
45  next(NULL)
46 {
47  name = xstrdup(n);
48 }
49 
51 {
52  // erase the list without consuming stack space
53  while (next) {
54  // unlink the next entry for deletion
55  Format *temp = next;
56  next = temp->next;
57  temp->next = NULL;
58  delete temp;
59  }
60 
61  // remove locals
62  xfree(name);
63  delete format;
64 }
65 
66 bool
67 Format::Format::parse(const char *def)
68 {
69  const char *cur, *eos;
70  Token *new_lt, *last_lt;
72 
73  debugs(46, 2, HERE << "got definition '" << def << "'");
74 
75  if (format) {
76  debugs(46, DBG_IMPORTANT, "WARNING: existing format for '" << name << " " << def << "'");
77  return false;
78  }
79 
80  /* very inefficient parser, but who cares, this needs to be simple */
81  /* First off, let's tokenize, we'll optimize in a second pass.
82  * A token can either be a %-prefixed sequence (usually a dynamic
83  * token but it can be an escaped sequence), or a string. */
84  cur = def;
85  eos = def + strlen(def);
86  format = new_lt = last_lt = new Token;
87  cur += new_lt->parse(cur, &quote);
88 
89  while (cur < eos) {
90  new_lt = new Token;
91  last_lt->next = new_lt;
92  last_lt = new_lt;
93  cur += new_lt->parse(cur, &quote);
94  }
95 
96  return true;
97 }
98 
99 size_t
100 Format::AssembleOne(const char *token, MemBuf &mb, const AccessLogEntryPointer &ale)
101 {
102  Token tkn;
104  const auto tokenSize = tkn.parse(token, &quote);
105  assert(tokenSize > 0);
106  if (ale != nullptr) {
107  Format fmt("SimpleToken");
108  fmt.format = &tkn;
109  fmt.assemble(mb, ale, 0);
110  fmt.format = nullptr;
111  } else
112  mb.append("-", 1);
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, HERE);
120 
121  // loop rather than recursing to conserve stack space.
122  for (const Format *fmt = this; fmt; fmt = fmt->next) {
123  debugs(46, 3, HERE << "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
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 = {0, 0};
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  if (al->cache.caddr.isAnyAddr()) // e.g., ICAP OPTIONS lack client
413  out = "-";
414  else
416 
417  if (!out) {
418  out = al->cache.caddr.toStr(tmp, sizeof(tmp));
419  }
420  break;
421 
422  case LFT_CLIENT_PORT:
423  if (al->request) {
424  outint = al->request->client_addr.port();
425  doint = 1;
426  } else if (al->tcpClient) {
427  outint = al->tcpClient->remote.port();
428  doint = 1;
429  }
430  break;
431 
432  case LFT_CLIENT_EUI:
433 #if USE_SQUID_EUI
434  // TODO make the ACL checklist have a direct link to any TCP details.
435  if (al->request && al->request->clientConnectionManager.valid() &&
438  if (conn->remote.isIPv4())
439  conn->remoteEui48.encode(tmp, sizeof(tmp));
440  else
441  conn->remoteEui64.encode(tmp, sizeof(tmp));
442  out = tmp;
443  }
444 #endif
445  break;
446 
448 #if USE_SQUID_EUI
449  if (al->request && al->request->clientConnectionManager.valid() &&
453  out = tmp;
454  }
455 #endif
456  break;
457 
459 #if USE_SQUID_EUI
460  if (al->request && al->request->clientConnectionManager.valid() &&
464  out = tmp;
465  }
466 #endif
467  break;
468 
470  if (al->hier.tcpServer)
471  out = al->hier.tcpServer->remote.toStr(tmp, sizeof(tmp));
472  break;
473 
475  out = al->hier.host;
476  break;
477 
478  case LFT_SERVER_PORT:
479  if (al->hier.tcpServer) {
480  outint = al->hier.tcpServer->remote.port();
481  doint = 1;
482  }
483  break;
484 
486  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw()))
487  out = addr->toStr(tmp, sizeof(tmp));
488  break;
489 
490  case LFT_CLIENT_LOCAL_IP:
491  if (al->tcpClient)
492  out = al->tcpClient->local.toStr(tmp, sizeof(tmp));
493  break;
494 
496  if (al->tcpClient) {
497  sb.appendf("0x%x", static_cast<uint32_t>(al->tcpClient->tos));
498  out = sb.c_str();
499  }
500  break;
501 
503  if (al->tcpClient) {
504  outUint64 = al->tcpClient->id.value;
505  doUint64 = true;
506  }
507  break;
508 
510  if (al->tcpClient) {
511  sb.appendf("0x%x", al->tcpClient->nfmark);
512  out = sb.c_str();
513  }
514  break;
515 
517  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw())) {
518  outint = addr->port();
519  doint = 1;
520  }
521  break;
522 
524  if (al->tcpClient) {
525  outint = al->tcpClient->local.port();
526  doint = 1;
527  }
528  break;
529 
531  case LFT_SERVER_LOCAL_IP:
532  if (al->hier.tcpServer)
533  out = al->hier.tcpServer->local.toStr(tmp, sizeof(tmp));
534  break;
535 
537  if (al->hier.tcpServer) {
538  outint = al->hier.tcpServer->local.port();
539  doint = 1;
540  }
541  break;
542 
544  if (al->hier.tcpServer) {
545  sb.appendf("0x%x", static_cast<uint32_t>(al->hier.tcpServer->tos));
546  out = sb.c_str();
547  }
548  break;
549 
551  if (al->hier.tcpServer) {
552  sb.appendf("0x%x", al->hier.tcpServer->nfmark);
553  out = sb.c_str();
554  }
555  break;
556 
558  if (al->request && al->request->clientConnectionManager.valid()) {
559  const auto &handshake = al->request->clientConnectionManager->preservedClientData;
560  if (const auto rawLength = handshake.length()) {
561  // add 1 byte to optimize the c_str() conversion below
562  char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1);
563 
564  struct base64_encode_ctx ctx;
565  base64_encode_init(&ctx);
566  auto encLength = base64_encode_update(&ctx, buf, rawLength, reinterpret_cast<const uint8_t*>(handshake.rawContent()));
567  encLength += base64_encode_final(&ctx, buf + encLength);
568 
569  sb.rawAppendFinish(buf, encLength);
570  out = sb.c_str();
571  }
572  }
573  break;
574 
576  // some platforms store time in 32-bit, some 64-bit...
577  outoff = static_cast<int64_t>(current_time.tv_sec);
578  dooff = 1;
579  break;
580 
581  case LFT_TIME_SUBSECOND:
582  outint = current_time.tv_usec / fmt->divisor;
583  doint = 1;
584  break;
585 
586  case LFT_TIME_LOCALTIME:
587  case LFT_TIME_GMT: {
588  const char *spec;
589  struct tm *t;
590  spec = fmt->data.string;
591 
592  if (fmt->type == LFT_TIME_LOCALTIME) {
593  if (!spec)
594  spec = "%d/%b/%Y:%H:%M:%S %z";
595  t = localtime(&squid_curtime);
596  } else {
597  if (!spec)
598  spec = "%d/%b/%Y:%H:%M:%S";
599 
600  t = gmtime(&squid_curtime);
601  }
602 
603  strftime(tmp, sizeof(tmp), spec, t);
604  out = tmp;
605  }
606  break;
607 
608  case LFT_TIME_START:
609  outtv = al->cache.start_time;
610  doSec = 1;
611  break;
612 
614  outtv = al->cache.trTime;
615  doMsec = 1;
616  break;
617 
619  struct timeval peerResponseTime;
620  if (al->hier.peerResponseTime(peerResponseTime)) {
621  outtv = peerResponseTime;
622  doMsec = 1;
623  }
624  break;
625 
627  struct timeval totalResponseTime;
628  if (al->hier.totalResponseTime(totalResponseTime)) {
629  outtv = totalResponseTime;
630  doMsec = 1;
631  }
632  }
633  break;
634 
635  case LFT_DNS_WAIT_TIME:
636  if (al->request && al->request->dnsWait >= 0) {
637  // TODO: microsecond precision for dns wait time.
638  // Convert milliseconds to timeval struct:
639  outtv.tv_sec = al->request->dnsWait / 1000;
640  outtv.tv_usec = (al->request->dnsWait % 1000) * 1000;
641  doMsec = 1;
642  }
643  break;
644 
645  case LFT_REQUEST_HEADER:
646  if (const Http::Message *msg = actualRequestHeader(al)) {
647  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
648  out = sb.c_str();
649  quote = 1;
650  }
651  break;
652 
654  if (al->adapted_request) {
655  sb = StringToSBuf(al->adapted_request->header.getByName(fmt->data.header.header));
656  out = sb.c_str();
657  quote = 1;
658  }
659  break;
660 
661  case LFT_REPLY_HEADER:
662  if (const Http::Message *msg = actualReplyHeader(al)) {
663  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
664  out = sb.c_str();
665  quote = 1;
666  }
667  break;
668 
669 #if USE_ADAPTATION
671  if (al->request) {
673  if (ah) {
674  ah->sumLogString(fmt->data.string, sb);
675  out = sb.c_str();
676  }
677  }
678  break;
679 
681  if (al->request) {
683  if (ah) {
684  ah->allLogString(fmt->data.string, sb);
685  out = sb.c_str();
686  }
687  }
688  break;
689 
691  if (al->request) {
693  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
694  sb = StringToSBuf(ah->allMeta.getByName(fmt->data.header.header));
695  out = sb.c_str();
696  quote = 1;
697  }
698  }
699  break;
700 
702  if (al->request) {
704  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
705  sb = ah->allMeta.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
706  out = sb.c_str();
707  quote = 1;
708  }
709  }
710  break;
711 
713  out = al->adapt.last_meta;
714  quote = 1;
715  break;
716 #endif
717 
718 #if ICAP_CLIENT
719  case LFT_ICAP_ADDR:
720  out = al->icap.hostAddr.toStr(tmp, sizeof(tmp));
721  break;
722 
723  case LFT_ICAP_SERV_NAME:
724  out = al->icap.serviceName.termedBuf();
725  break;
726 
728  out = al->icap.reqUri.termedBuf();
729  break;
730 
733  break;
734 
735  case LFT_ICAP_BYTES_SENT:
736  outoff = al->icap.bytesSent;
737  dooff = 1;
738  break;
739 
740  case LFT_ICAP_BYTES_READ:
741  outoff = al->icap.bytesRead;
742  dooff = 1;
743  break;
744 
746  if (al->icap.bodyBytesRead >= 0) {
747  outoff = al->icap.bodyBytesRead;
748  dooff = 1;
749  }
750  // else if icap.bodyBytesRead < 0, we do not have any http data,
751  // so just print a "-" (204 responses etc)
752  break;
753 
754  case LFT_ICAP_REQ_HEADER:
755  if (al->icap.request) {
756  sb = StringToSBuf(al->icap.request->header.getByName(fmt->data.header.header));
757  out = sb.c_str();
758  quote = 1;
759  }
760  break;
761 
763  if (al->icap.request) {
764  sb = al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
765  out = sb.c_str();
766  quote = 1;
767  }
768  break;
769 
771  if (al->icap.request) {
773  while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
774  sb.append(e->name);
775  sb.append(": ");
776  sb.append(StringToSBuf(e->value));
777  sb.append("\r\n");
778  }
779  out = sb.c_str();
780  quote = 1;
781  }
782  break;
783 
784  case LFT_ICAP_REP_HEADER:
785  if (al->icap.reply) {
786  sb = StringToSBuf(al->icap.reply->header.getByName(fmt->data.header.header));
787  out = sb.c_str();
788  quote = 1;
789  }
790  break;
791 
793  if (al->icap.reply) {
794  sb = al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
795  out = sb.c_str();
796  quote = 1;
797  }
798  break;
799 
801  if (al->icap.reply) {
803  while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
804  sb.append(e->name);
805  sb.append(": ");
806  sb.append(StringToSBuf(e->value));
807  sb.append("\r\n");
808  }
809  out = sb.c_str();
810  quote = 1;
811  }
812  break;
813 
815  outtv = al->icap.trTime;
816  doMsec = 1;
817  break;
818 
819  case LFT_ICAP_IO_TIME:
820  outtv = al->icap.ioTime;
821  doMsec = 1;
822  break;
823 
825  outint = al->icap.resStatus;
826  doint = 1;
827  break;
828 
829  case LFT_ICAP_OUTCOME:
830  out = al->icap.outcome;
831  break;
832 
833  case LFT_ICAP_TOTAL_TIME:
834  outtv = al->icap.processingTime;
835  doMsec = 1;
836  break;
837 #endif
839  if (const Http::Message *msg = actualRequestHeader(al)) {
840  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
841  out = sb.c_str();
842  quote = 1;
843  }
844  break;
845 
847  if (al->proxyProtocolHeader) {
848  sb = al->proxyProtocolHeader->getValues(fmt->data.headerId, fmt->data.header.separator);
849  out = sb.c_str();
850  quote = 1;
851  }
852  break;
853 
855  if (al->proxyProtocolHeader) {
856  sb = al->proxyProtocolHeader->toMime();
857  out = sb.c_str();
858  quote = 1;
859  }
860  break;
861 
863  if (al->proxyProtocolHeader) {
864  sb = al->proxyProtocolHeader->getElem(fmt->data.headerId, fmt->data.header.element, fmt->data.header.separator);
865  out = sb.c_str();
866  quote = 1;
867  }
868  break;
869 
871  if (al->adapted_request) {
872  sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
873  out = sb.c_str();
874  quote = 1;
875  }
876  break;
877 
879  if (const Http::Message *msg = actualReplyHeader(al)) {
880  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
881  out = sb.c_str();
882  quote = 1;
883  }
884  break;
885 
887 #if ICAP_CLIENT
889  // XXX: since AccessLogEntry::Headers lacks virgin response
890  // headers, do nothing for now
891  out = nullptr;
892  } else
893 #endif
894  {
895  // just headers without start-line and CRLF
896  // XXX: reconcile with '<h'
897  out = al->headers.request;
898  quote = 1;
899  }
900  break;
901 
903  // just headers without start-line and CRLF
904  // XXX: reconcile with '<h'
905  out = al->headers.adapted_request;
906  quote = 1;
907  break;
908 
909  case LFT_REPLY_ALL_HEADERS: {
910  MemBuf allHeaders;
911  allHeaders.init();
912  // status-line + headers + CRLF
913  // XXX: reconcile with '>h' and '>ha'
914  al->packReplyHeaders(allHeaders);
915  sb.assign(allHeaders.content(), allHeaders.contentSize());
916  out = sb.c_str();
917 #if ICAP_CLIENT
918  if (!out && al->icap.reqMethod == Adaptation::methodReqmod)
919  out = al->headers.adapted_request;
920 #endif
921  quote = 1;
922  }
923  break;
924 
925  case LFT_USER_NAME:
926 #if USE_AUTH
927  if (al->request && al->request->auth_user_request)
929 #endif
930  if (!out && al->request && al->request->extacl_user.size()) {
931  if (const char *t = al->request->extacl_user.termedBuf())
932  out = t;
933  }
934  if (!out)
935  out = strOrNull(al->getExtUser());
936 #if USE_OPENSSL
937  if (!out)
938  out = strOrNull(al->cache.ssluser);
939 #endif
940  if (!out)
941  out = strOrNull(al->getClientIdent());
942  break;
943 
944  case LFT_USER_LOGIN:
945 #if USE_AUTH
946  if (al->request && al->request->auth_user_request)
948 #endif
949  break;
950 
951  case LFT_USER_IDENT:
952  out = strOrNull(al->getClientIdent());
953  break;
954 
955  case LFT_USER_EXTERNAL:
956  out = strOrNull(al->getExtUser());
957  break;
958 
959  /* case LFT_USER_REALM: */
960  /* case LFT_USER_SCHEME: */
961 
962  // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
963  // but compiler complains if omitted
966  outint = al->http.code;
967  doint = 1;
968  break;
969 
971  if (al->hier.peer_reply_status != Http::scNone) {
972  outint = al->hier.peer_reply_status;
973  doint = 1;
974  }
975  break;
976  /* case LFT_HTTP_STATUS:
977  * out = statusline->text;
978  * quote = 1;
979  * break;
980  */
982  if (al->hier.bodyBytesRead >= 0) {
983  outoff = al->hier.bodyBytesRead;
984  dooff = 1;
985  }
986  // else if hier.bodyBytesRead < 0 we did not have any data exchange with
987  // a peer server so just print a "-" (eg requests served from cache,
988  // or internal error messages).
989  break;
990 
991  case LFT_SQUID_STATUS:
992  out = al->cache.code.c_str();
993  break;
994 
995  case LFT_SQUID_ERROR:
996  if (al->request && al->request->errType != ERR_NONE)
997  out = errorPageName(al->request->errType);
998  break;
999 
1001 #if USE_OPENSSL
1002  if (al->request && al->request->errType == ERR_SECURE_CONNECT_FAIL) {
1003  out = Ssl::GetErrorName(al->request->errDetail, true);
1004  } else
1005 #endif
1006  if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
1008  out = errorDetailName(al->request->errDetail);
1009  else {
1011  sb.appendf("%s=0x%X",
1012  errorDetailName(al->request->errDetail), (uint32_t) al->request->errDetail);
1013  else
1014  sb.appendf("%s=%d",
1016  out = sb.c_str();
1017  }
1018  }
1019  break;
1020 
1021  case LFT_SQUID_HIERARCHY:
1022  if (al->hier.ping.timedout)
1023  mb.append("TIMEOUT_", 8);
1024  out = hier_code_str[al->hier.code];
1025  break;
1026 
1027  case LFT_MIME_TYPE:
1028  out = al->http.content_type;
1029  break;
1030 
1031  case LFT_CLIENT_REQ_METHOD:
1032  if (al->request) {
1033  sb = al->request->method.image();
1034  out = sb.c_str();
1035  quote = 1;
1036  }
1037  break;
1038 
1039  case LFT_CLIENT_REQ_URI:
1040  if (const auto uri = al->effectiveVirginUrl()) {
1041  sb = *uri;
1042  out = sb.c_str();
1043  quote = 1;
1044  }
1045  break;
1046 
1048  if (al->request) {
1049  sb = al->request->url.getScheme().image();
1050  out = sb.c_str();
1051  quote = 1;
1052  }
1053  break;
1054 
1056  if (al->request) {
1057  out = al->request->url.host();
1058  quote = 1;
1059  }
1060  break;
1061 
1063  if (al->request) {
1064  outint = al->request->url.port();
1065  doint = 1;
1066  }
1067  break;
1068 
1071  if (al->request) {
1072  sb = al->request->url.path();
1073  out = sb.c_str();
1074  quote = 1;
1075  }
1076  break;
1077 
1079  if (al->request) {
1080  sb.appendf("%u.%u", al->request->http_ver.major, al->request->http_ver.minor);
1081  out = sb.c_str();
1082  }
1083  break;
1084 
1085  case LFT_REQUEST_METHOD:
1086  if (al->hasLogMethod()) {
1087  sb = al->getLogMethod();
1088  out = sb.c_str();
1089  quote = 1;
1090  }
1091  break;
1092 
1093  case LFT_REQUEST_URI:
1094  if (!al->url.isEmpty()) {
1095  sb = al->url;
1096  out = sb.c_str();
1097  }
1098  break;
1099 
1101  case LFT_REQUEST_VERSION:
1102  sb.appendf("%u.%u", al->http.version.major, al->http.version.minor);
1103  out = sb.c_str();
1104  break;
1105 
1106  case LFT_SERVER_REQ_METHOD:
1107  if (al->adapted_request) {
1108  sb = al->adapted_request->method.image();
1109  out = sb.c_str();
1110  quote = 1;
1111  }
1112  break;
1113 
1114  case LFT_SERVER_REQ_URI:
1115  // adapted request URI sent to server/peer
1116  if (al->adapted_request) {
1118  out = sb.c_str();
1119  quote = 1;
1120  }
1121  break;
1122 
1124  if (al->adapted_request) {
1125  sb = al->adapted_request->url.getScheme().image();
1126  out = sb.c_str();
1127  quote = 1;
1128  }
1129  break;
1130 
1132  if (al->adapted_request) {
1133  out = al->adapted_request->url.host();
1134  quote = 1;
1135  }
1136  break;
1137 
1139  if (al->adapted_request) {
1140  outint = al->adapted_request->url.port();
1141  doint = 1;
1142  }
1143  break;
1144 
1146  if (al->adapted_request) {
1147  sb = al->adapted_request->url.path();
1148  out = sb.c_str();
1149  quote = 1;
1150  }
1151  break;
1152 
1154  if (al->adapted_request) {
1155  sb.appendf("%u.%u",
1158  out = tmp;
1159  }
1160  break;
1161 
1163  outoff = al->http.clientRequestSz.messageTotal();
1164  dooff = 1;
1165  break;
1166 
1168  outoff = al->http.clientRequestSz.header;
1169  dooff =1;
1170  break;
1171 
1172  /*case LFT_REQUEST_SIZE_BODY: */
1173  /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
1174 
1176  outoff = al->http.clientReplySz.messageTotal();
1177  dooff = 1;
1178  break;
1179 
1180  case LFT_REPLY_HIGHOFFSET:
1181  outoff = al->cache.highOffset;
1182  dooff = 1;
1183  break;
1184 
1185  case LFT_REPLY_OBJECTSIZE:
1186  outoff = al->cache.objectSize;
1187  dooff = 1;
1188  break;
1189 
1191  outint = al->http.clientReplySz.header;
1192  doint = 1;
1193  break;
1194 
1195  /*case LFT_REPLY_SIZE_BODY: */
1196  /*case LFT_REPLY_SIZE_BODY_NO_TE: */
1197 
1200  doint = 1;
1201  break;
1202  /*case LFT_SERVER_IO_SIZE_TOTAL: */
1203 
1204  case LFT_TAG:
1205  if (al->request) {
1206  out = al->request->tag.termedBuf();
1207  quote = 1;
1208  }
1209  break;
1210 
1211  case LFT_EXT_LOG:
1212  if (al->request) {
1213  out = al->request->extacl_log.termedBuf();
1214  quote = 1;
1215  }
1216  break;
1217 
1218  case LFT_SEQUENCE_NUMBER:
1219  outoff = logSequenceNumber;
1220  dooff = 1;
1221  break;
1222 
1223 #if USE_OPENSSL
1224  case LFT_SSL_BUMP_MODE: {
1225  const Ssl::BumpMode mode = static_cast<Ssl::BumpMode>(al->ssl.bumpMode);
1226  // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
1227  out = Ssl::bumpMode(mode);
1228  }
1229  break;
1230 
1232  if (al->request) {
1234  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1235  if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) {
1237  out = sb.c_str();
1238  }
1239  }
1240  }
1241  break;
1242 
1244  if (al->request) {
1246  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1247  if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) {
1249  out = sb.c_str();
1250  }
1251  }
1252  }
1253  break;
1254 
1255  case LFT_EXT_ACL_USER_CERT:
1256  if (al->request) {
1258  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1259  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1260  out = sslGetUserAttribute(ssl, fmt->data.header.header);
1261  }
1262  }
1263  break;
1264 
1266  if (al->request) {
1268  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1269  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1270  out = sslGetCAAttribute(ssl, fmt->data.header.header);
1271  }
1272  }
1273  break;
1274 
1276  if (X509 *cert = al->cache.sslClientCert.get()) {
1277  if (X509_NAME *subject = X509_get_subject_name(cert)) {
1278  X509_NAME_oneline(subject, tmp, sizeof(tmp));
1279  out = tmp;
1280  }
1281  }
1282  break;
1283 
1285  if (X509 *cert = al->cache.sslClientCert.get()) {
1286  if (X509_NAME *issuer = X509_get_issuer_name(cert)) {
1287  X509_NAME_oneline(issuer, tmp, sizeof(tmp));
1288  out = tmp;
1289  }
1290  }
1291  break;
1292 
1293  case LFT_SSL_CLIENT_SNI:
1294  if (al->request && al->request->clientConnectionManager.valid()) {
1295  if (const ConnStateData *conn = al->request->clientConnectionManager.get()) {
1296  if (!conn->tlsClientSni().isEmpty()) {
1297  sb = conn->tlsClientSni();
1298  out = sb.c_str();
1299  }
1300  }
1301  }
1302  break;
1303 
1305  if (al->request && al->request->clientConnectionManager.valid()) {
1306  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1307  const char *separator = fmt->data.string ? fmt->data.string : ":";
1308  for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) {
1309  if (!sb.isEmpty())
1310  sb.append(separator);
1311  sb.append(Ssl::GetErrorName(sslError->element.code, true));
1312  if (sslError->element.depth >= 0)
1313  sb.appendf("@depth=%d", sslError->element.depth);
1314  }
1315  if (!sb.isEmpty())
1316  out = sb.c_str();
1317  }
1318  }
1319  break;
1320 
1324  if (al->request && al->request->clientConnectionManager.valid()) {
1325  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1326  if (X509 *serverCert = srvBump->serverCert.get()) {
1327  if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT)
1328  out = Ssl::GetX509UserAttribute(serverCert, "DN");
1329  else if (fmt->type == LFT_SSL_SERVER_CERT_ISSUER)
1330  out = Ssl::GetX509CAAttribute(serverCert, "DN");
1331  else {
1332  assert(fmt->type == LFT_SSL_SERVER_CERT_WHOLE);
1333  sb = Ssl::GetX509PEM(serverCert);
1334  out = sb.c_str();
1335  quote = 1;
1336  }
1337  }
1338  }
1339  }
1340  break;
1341 
1343  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1345  break;
1346 
1348  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1350  break;
1351 
1353  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1354  out = al->tcpClient->hasTlsNegotiations()->helloVersion();
1355  break;
1356 
1358  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1360  break;
1361 
1363  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1365  break;
1366 
1368  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1370  break;
1371 
1373  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1374  out = al->tcpClient->hasTlsNegotiations()->cipherName();
1375  break;
1376 
1378  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1379  out = al->hier.tcpServer->hasTlsNegotiations()->cipherName();
1380  break;
1381 #endif
1382 
1384  assert(LFT_REQUEST_URLGROUP_OLD_2X == 0); // should never happen.
1385 
1386  case LFT_NOTE:
1387  tmp[0] = fmt->data.header.separator;
1388  tmp[1] = '\0';
1389  if (fmt->data.header.header && *fmt->data.header.header) {
1390  const char *separator = tmp;
1391  static SBuf note;
1392 #if USE_ADAPTATION
1394  if (ah && ah->metaHeaders) {
1395  if (ah->metaHeaders->find(note, fmt->data.header.header, separator))
1396  sb.append(note);
1397  }
1398 #endif
1399  if (al->notes) {
1400  if (al->notes->find(note, fmt->data.header.header, separator)) {
1401  if (!sb.isEmpty())
1402  sb.append(separator);
1403  sb.append(note);
1404  }
1405  }
1406  out = sb.c_str();
1407  quote = 1;
1408  } else {
1409  // if no argument given use default "\r\n" as notes separator
1410  const char *separator = fmt->data.string ? tmp : "\r\n";
1411 #if USE_ADAPTATION
1413  if (ah && ah->metaHeaders && !ah->metaHeaders->empty())
1414  sb.append(ah->metaHeaders->toString(separator));
1415 #endif
1416  if (al->notes && !al->notes->empty())
1417  sb.append(al->notes->toString(separator));
1418 
1419  out = sb.c_str();
1420  quote = 1;
1421  }
1422  break;
1423 
1424  case LFT_CREDENTIALS:
1425 #if USE_AUTH
1426  if (al->request && al->request->auth_user_request)
1428 #endif
1429  break;
1430 
1431  case LFT_PERCENT:
1432  out = "%";
1433  break;
1434 
1435  case LFT_EXT_ACL_NAME:
1436  out = al->lastAclName;
1437  break;
1438 
1439  case LFT_EXT_ACL_DATA:
1440  if (!al->lastAclData.isEmpty())
1441  out = al->lastAclData.c_str();
1442  break;
1443 
1444  case LFT_MASTER_XACTION:
1445  if (al->request) {
1446  doUint64 = true;
1447  outUint64 = static_cast<uint64_t>(al->request->masterXaction->id.value);
1448  break;
1449  }
1450  }
1451 
1452  if (dooff) {
1453  sb.appendf("%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff);
1454  out = sb.c_str();
1455 
1456  } else if (doint) {
1457  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
1458  out = sb.c_str();
1459  } else if (doUint64) {
1460  sb.appendf("%0*" PRIu64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outUint64);
1461  out = sb.c_str();
1462  } else if (doMsec) {
1463  if (fmt->widthMax < 0) {
1464  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, tvToMsec(outtv));
1465  } else {
1466  int precision = fmt->widthMax;
1467  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)));
1468  }
1469  out = sb.c_str();
1470  } else if (doSec) {
1471  int precision = fmt->widthMax >=0 ? fmt->widthMax :3;
1472  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));
1473  out = sb.c_str();
1474  }
1475 
1476  if (out && *out) {
1477  if (quote || fmt->quote != LOG_QUOTE_NONE) {
1478  // Do not write to the tmp buffer because it may contain the to-be-quoted value.
1479  static char quotedOut[2 * sizeof(tmp)];
1480  static_assert(sizeof(quotedOut) > 0, "quotedOut has zero length");
1481  quotedOut[0] = '\0';
1482 
1483  char *newout = NULL;
1484  int newfree = 0;
1485 
1486  switch (fmt->quote) {
1487 
1488  case LOG_QUOTE_NONE:
1489  newout = rfc1738_escape_unescaped(out);
1490  break;
1491 
1492  case LOG_QUOTE_QUOTES: {
1493  size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
1494  if (out_len >= sizeof(tmp)) {
1495  newout = (char *)xmalloc(out_len);
1496  newfree = 1;
1497  } else
1498  newout = quotedOut;
1499  log_quoted_string(out, newout);
1500  }
1501  break;
1502 
1503  case LOG_QUOTE_MIMEBLOB:
1504  newout = QuoteMimeBlob(out);
1505  newfree = 1;
1506  break;
1507 
1508  case LOG_QUOTE_URL:
1509  newout = rfc1738_escape(out);
1510  break;
1511 
1512  case LOG_QUOTE_SHELL: {
1513  MemBuf mbq;
1514  mbq.init();
1515  strwordquote(&mbq, out);
1516  newout = mbq.content();
1517  mbq.stolen = 1;
1518  newfree = 1;
1519  }
1520  break;
1521 
1522  case LOG_QUOTE_RAW:
1523  break;
1524  }
1525 
1526  if (newout) {
1527  if (dofree)
1528  safe_free(out);
1529 
1530  out = newout;
1531 
1532  dofree = newfree;
1533  }
1534  }
1535 
1536  // enforce width limits if configured
1537  const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff && !doMsec && !doSec && !doUint64;
1538  if (haveMaxWidth || fmt->widthMin) {
1539  const int minWidth = fmt->widthMin >= 0 ?
1540  fmt->widthMin :0;
1541  const int maxWidth = haveMaxWidth ?
1542  fmt->widthMax : strlen(out);
1543 
1544  if (fmt->left)
1545  mb.appendf("%-*.*s", minWidth, maxWidth, out);
1546  else
1547  mb.appendf("%*.*s", minWidth, maxWidth, out);
1548  } else
1549  mb.append(out, strlen(out));
1550  } else {
1551  mb.append("-", 1);
1552  }
1553 
1554  if (fmt->space)
1555  mb.append(" ", 1);
1556 
1557  sb.clear();
1558 
1559  if (dofree)
1560  safe_free(out);
1561  }
1562 }
1563 
const char * sslGetCAAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:698
@ 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
@ ERR_DETAIL_MAX
@ LFT_EXT_ACL_USER_CERT_RAW
Definition: ByteCode.h:242
#define FQDN_LOOKUP_IF_MISS
Definition: defines.h:48
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:25
@ LFT_ADAPTATION_LAST_ALL_HEADERS
Definition: ByteCode.h:187
#define xmalloc
@ 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:62
@ 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:50
@ LFT_ICAP_REQ_HEADER_ELEM
Definition: ByteCode.h:203
virtual const char * credentialsStr()=0
@ scNone
Definition: StatusCode.h:21
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:420
@ 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:176
@ 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
bool isAnyAddr() const
Definition: Address.cc:170
InstanceId< Connection, uint64_t > id
Definition: Connection.h:179
bool encode(char *buf, const int len) const
Definition: Eui48.cc:119
@ ERR_NONE
Definition: err_type.h:13
@ 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:881
char * QuoteMimeBlob(const char *header)
Definition: Quoting.cc:43
unsigned int minor
minor version number
HttpRequest * request
ICAP request.
HttpReplyPointer reply
void init(mb_size_t szInit, mb_size_t szMax)
Definition: MemBuf.cc:96
@ 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:86
BumpMode
Definition: support.h:135
CbDataList * next
Definition: CbDataList.h:31
@ LFT_REQUEST_METHOD
Definition: ByteCode.h:81
const SBuf * effectiveVirginUrl() const
GETX509PEM GetX509PEM
Definition: support.h:124
@ 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:655
class AccessLogEntry::SslDetails ssl
#define PRIu64
Definition: types.h:120
GETX509ATTRIBUTE GetX509CAAttribute
Definition: support.h:121
@ 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:216
@ LFT_USER_EXTERNAL
Definition: ByteCode.h:154
struct timeval start_time
The time the master transaction started.
long int tvToMsec(struct timeval &t)
Convert timeval to milliseconds.
Definition: SquidTime.h:43
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:26
@ LFT_REQUEST_URLGROUP_OLD_2X
Definition: ByteCode.h:87
#define strOrNull(s)
Convert a string to NULL pointer if it is "".
Definition: Format.cc:39
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
@ ERR_SECURE_CONNECT_FAIL
Definition: err_type.h:29
AnyP::ProtocolVersion version
NotePairs::Pointer notes
bool isIPv4() const
Definition: Address.cc:158
bool empty() const
Definition: Notes.h:253
const char * cipherName() const
@ 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:67
#define DBG_IMPORTANT
Definition: Debug.h:46
String extacl_user
Definition: HttpRequest.h:179
SBuf lastAclData
string for external_acl_type DATA format code
@ 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:100
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition: Address.cc:802
@ LFT_SERVER_LOCAL_PORT
Definition: ByteCode.h:66
class AccessLogEntry::HttpDetails http
const char * c_str() const
compute the status access.log field
Definition: LogTags.cc:56
@ 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
@ LFT_TLS_SERVER_NEGOTIATED_VERSION
Definition: ByteCode.h:227
const char * fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
Definition: fqdncache.cc:480
#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
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:128
@ 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:127
@ LFT_HTTP_BODY_BYTES_READ
Definition: ByteCode.h:126
const char * errorDetailName(int errDetailId)
const char * username() const
Definition: UserRequest.cc:32
uint64_t header
Definition: MessageSizes.h:21
@ ERR_DETAIL_EXCEPTION_START
unsigned short port() const
Definition: Address.cc:778
Definition: MemBuf.h:23
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
err_type errType
Definition: HttpRequest.h:161
Ip::Address local
Definition: Connection.h:142
@ LFT_DNS_WAIT_TIME
Definition: ByteCode.h:168
Format(const char *name)
Definition: Format.cc:43
const char * lastAclName
string for external_acl_type ACL format code
@ LFT_STRING
Definition: ByteCode.h:34
std::ostream & HERE(std::ostream &s)
Definition: Debug.h:157
@ 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:317
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:145
MasterXaction::Pointer masterXaction
the master transaction this request belongs to. Never nil.
Definition: HttpRequest.h:239
int conn
the current server connection FD
Definition: Transport.cc:26
#define assert(EX)
Definition: assert.h:19
@ 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
int errDetail
errType-specific detail about the transaction error
Definition: HttpRequest.h:162
@ 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:65
HttpReply * reply
ICAP reply.
const AnyP::UriScheme & getScheme() const
Definition: Uri.h:67
Eui::Eui48 remoteEui48
Definition: Connection.h:175
@ 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:526
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:183
time_t squid_curtime
Definition: stub_time.cc:17
void allLogString(const char *serviceId, SBuf &)
dump individual xaction times to a string
Definition: History.cc:66
@ LFT_REPLY_OBJECTSIZE
Definition: ByteCode.h:141
int cur
Definition: ModDevPoll.cc:76
Comm::ConnectionPointer clientConnection
Definition: Server.h:97
const char * sslGetUserAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:685
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:26
@ 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:1042
@ 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:407
SBuf preservedClientData
Definition: client_side.h:314
Security::CertPointer sslClientCert
cert received from the client
const Ip::Address * FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:803
@ 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:82
#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:891
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
const char * termedBuf() const
Definition: SquidString.h:91
struct timeval current_time
Definition: stub_time.cc:15
HttpRequest * adapted_request
@ methodRespmod
Definition: Elements.h:17
struct timeval processingTime
total ICAP processing time
@ ERR_DETAIL_START
@ 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:960
@ 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:72
@ LOG_QUOTE_MIMEBLOB
Definition: ByteCode.h:262
GETX509ATTRIBUTE GetX509UserAttribute
Definition: support.h:118
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
@ 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
void EVH void * arg
Definition: stub_event.cc:16
Ssl::ServerBump * serverBump()
Definition: client_side.h:250
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
@ 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
@ ERR_DETAIL_NONE
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:344
@ LFT_CLIENT_REQ_URLPORT
Definition: ByteCode.h:75
virtual void append(char const *, int)
Appends a c-string to existing packed data.
Definition: store.cc:829
@ 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:44
HttpHeaderEntry * getEntry(HttpHeaderPos *pos) const
Definition: HttpHeader.cc:601
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:705
@ 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:98
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
String tag
Definition: HttpRequest.h:177
const char * bumpMode(int bm)
Definition: support.h:147
@ 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:159
void const char * buf
Definition: stub_helper.cc:16
@ LFT_LOCAL_LISTENING_PORT
Definition: ByteCode.h:55
SBuf sslGetUserCertificatePEM(SSL *ssl)
Definition: support.cc:718
const char * GetErrorName(Security::ErrorCode value, const bool prefixRawCode=false)
Definition: ErrorDetail.cc:540
@ LFT_EXT_ACL_CLIENT_EUI48
Definition: ByteCode.h:247
@ LFT_ICAP_BYTES_SENT
Definition: ByteCode.h:198
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:233
T * get() const
Returns raw and possibly nullptr pointer.
Quoting
Quoting style for a format output.
Definition: ByteCode.h:259
int timedout
Definition: PingData.h:25
@ LFT_SQUID_HIERARCHY
Definition: ByteCode.h:174

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors