Format.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2019 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/StringConvert.h"
27 #include "security/CertError.h"
29 #include "SquidTime.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, HERE << "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 inefficent 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  return static_cast<size_t>(tokenSize);
113 }
114 
115 void
116 Format::Format::dump(StoreEntry * entry, const char *directiveName, bool eol) const
117 {
118  debugs(46, 4, HERE);
119 
120  // loop rather than recursing to conserve stack space.
121  for (const Format *fmt = this; fmt; fmt = fmt->next) {
122  debugs(46, 3, HERE << "Dumping format definition for " << fmt->name);
123  if (directiveName)
124  storeAppendPrintf(entry, "%s %s ", directiveName, fmt->name);
125 
126  for (Token *t = fmt->format; t; t = t->next) {
127  if (t->type == LFT_STRING)
128  storeAppendPrintf(entry, "%s", t->data.string);
129  else {
130  char argbuf[256];
131  char *arg = NULL;
132  ByteCode_t type = t->type;
133 
134  switch (type) {
135  /* special cases */
136 
137  case LFT_STRING:
138  break;
139 #if USE_ADAPTATION
141 #endif
142 #if ICAP_CLIENT
145 #endif
149 
150  if (t->data.header.separator != ',')
151  snprintf(argbuf, sizeof(argbuf), "%s:%c%s", t->data.header.header, t->data.header.separator, t->data.header.element);
152  else
153  snprintf(argbuf, sizeof(argbuf), "%s:%s", t->data.header.header, t->data.header.element);
154 
155  arg = argbuf;
156 
157  switch (type) {
159  type = LFT_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
160  break;
162  type = LFT_ADAPTED_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
163  break;
165  type = LFT_REPLY_HEADER_ELEM; // XXX: remove _ELEM?
166  break;
167 #if USE_ADAPTATION
170  break;
171 #endif
172 #if ICAP_CLIENT
174  type = LFT_ICAP_REQ_HEADER;
175  break;
177  type = LFT_ICAP_REP_HEADER;
178  break;
179 #endif
180  default:
181  break;
182  }
183 
184  break;
185 
189 
190 #if USE_ADAPTATION
192 #endif
193 #if ICAP_CLIENT
196 #endif
197 
198  switch (type) {
200  type = LFT_REQUEST_HEADER;
201  break;
204  break;
206  type = LFT_REPLY_HEADER;
207  break;
208 #if USE_ADAPTATION
211  break;
212 #endif
213 #if ICAP_CLIENT
215  type = LFT_ICAP_REQ_HEADER;
216  break;
218  type = LFT_ICAP_REP_HEADER;
219  break;
220 #endif
221  default:
222  break;
223  }
224 
225  break;
226 
227  default:
228  if (t->data.string)
229  arg = t->data.string;
230 
231  break;
232  }
233 
234  entry->append("%", 1);
235 
236  switch (t->quote) {
237 
238  case LOG_QUOTE_QUOTES:
239  entry->append("\"", 1);
240  break;
241 
242  case LOG_QUOTE_MIMEBLOB:
243  entry->append("[", 1);
244  break;
245 
246  case LOG_QUOTE_URL:
247  entry->append("#", 1);
248  break;
249 
250  case LOG_QUOTE_RAW:
251  entry->append("'", 1);
252  break;
253 
254  case LOG_QUOTE_SHELL:
255  entry->append("/", 1);
256  break;
257 
258  case LOG_QUOTE_NONE:
259  break;
260  }
261 
262  if (t->left)
263  entry->append("-", 1);
264 
265  if (t->zero)
266  entry->append("0", 1);
267 
268  if (t->widthMin >= 0)
269  storeAppendPrintf(entry, "%d", t->widthMin);
270 
271  if (t->widthMax >= 0)
272  storeAppendPrintf(entry, ".%d", t->widthMax);
273 
274  if (arg)
275  storeAppendPrintf(entry, "{%s}", arg);
276 
277  storeAppendPrintf(entry, "%s", t->label);
278 
279  if (t->space)
280  entry->append(" ", 1);
281  }
282  }
283 
284  if (eol)
285  entry->append("\n", 1);
286  }
287 
288 }
289 
290 static void
291 log_quoted_string(const char *str, char *out)
292 {
293  char *p = out;
294 
295  while (*str) {
296  int l = strcspn(str, "\"\\\r\n\t");
297  memcpy(p, str, l);
298  str += l;
299  p += l;
300 
301  switch (*str) {
302 
303  case '\0':
304  break;
305 
306  case '\r':
307  *p = '\\';
308  ++p;
309  *p = 'r';
310  ++p;
311  ++str;
312  break;
313 
314  case '\n':
315  *p = '\\';
316  ++p;
317  *p = 'n';
318  ++p;
319  ++str;
320  break;
321 
322  case '\t':
323  *p = '\\';
324  ++p;
325  *p = 't';
326  ++p;
327  ++str;
328  break;
329 
330  default:
331  *p = '\\';
332  ++p;
333  *p = *str;
334  ++p;
335  ++str;
336  break;
337  }
338  }
339 
340  *p = '\0';
341 }
342 
343 #if USE_OPENSSL
344 static char *
346 {
347  snprintf(buf, size, "SSL_ERR=%d", err);
348  return buf;
349 }
350 #endif
351 
357 static const Http::Message *
359 {
360  const Http::Message *msg = al->reply;
361 #if ICAP_CLIENT
362  // al->icap.reqMethod is methodNone in access.log context
363  if (!msg && al->icap.reqMethod == Adaptation::methodReqmod)
364  msg = al->adapted_request;
365 #endif
366  return msg;
367 }
368 
371 static const Http::Message *
373 {
374 #if ICAP_CLIENT
375  // al->icap.reqMethod is methodNone in access.log context
376  if (al->icap.reqMethod == Adaptation::methodRespmod) {
377  // XXX: for now AccessLogEntry lacks virgin response headers
378  return nullptr;
379  }
380 #endif
381  return al->request;
382 }
383 
384 void
385 Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logSequenceNumber) const
386 {
387  static char tmp[1024];
388  SBuf sb;
389 
390  for (Token *fmt = format; fmt; fmt = fmt->next) { /* for each token */
391  const char *out = nullptr;
392  int quote = 0;
393  long int outint = 0;
394  int doint = 0;
395  int dofree = 0;
396  int64_t outoff = 0;
397  int dooff = 0;
398  struct timeval outtv = {0, 0};
399  int doMsec = 0;
400  int doSec = 0;
401 
402  switch (fmt->type) {
403 
404  case LFT_NONE:
405  out = "";
406  break;
407 
408  case LFT_STRING:
409  out = fmt->data.string;
410  break;
411 
413  al->getLogClientIp(tmp, sizeof(tmp));
414  out = tmp;
415  break;
416 
417  case LFT_CLIENT_FQDN:
418  if (al->cache.caddr.isAnyAddr()) // e.g., ICAP OPTIONS lack client
419  out = "-";
420  else
422 
423  if (!out) {
424  out = al->cache.caddr.toStr(tmp, sizeof(tmp));
425  }
426  break;
427 
428  case LFT_CLIENT_PORT:
429  if (al->request) {
430  outint = al->request->client_addr.port();
431  doint = 1;
432  } else if (al->tcpClient) {
433  outint = al->tcpClient->remote.port();
434  doint = 1;
435  }
436  break;
437 
438  case LFT_CLIENT_EUI:
439 #if USE_SQUID_EUI
440  // TODO make the ACL checklist have a direct link to any TCP details.
441  if (al->request && al->request->clientConnectionManager.valid() &&
444  if (conn->remote.isIPv4())
445  conn->remoteEui48.encode(tmp, sizeof(tmp));
446  else
447  conn->remoteEui64.encode(tmp, sizeof(tmp));
448  out = tmp;
449  }
450 #endif
451  break;
452 
454 #if USE_SQUID_EUI
455  if (al->request && al->request->clientConnectionManager.valid() &&
459  out = tmp;
460  }
461 #endif
462  break;
463 
465 #if USE_SQUID_EUI
466  if (al->request && al->request->clientConnectionManager.valid() &&
470  out = tmp;
471  }
472 #endif
473  break;
474 
476  if (al->hier.tcpServer)
477  out = al->hier.tcpServer->remote.toStr(tmp, sizeof(tmp));
478  break;
479 
481  out = al->hier.host;
482  break;
483 
484  case LFT_SERVER_PORT:
485  if (al->hier.tcpServer) {
486  outint = al->hier.tcpServer->remote.port();
487  doint = 1;
488  }
489  break;
490 
492  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw()))
493  out = addr->toStr(tmp, sizeof(tmp));
494  break;
495 
496  case LFT_CLIENT_LOCAL_IP:
497  if (al->tcpClient)
498  out = al->tcpClient->local.toStr(tmp, sizeof(tmp));
499  break;
500 
502  if (al->tcpClient) {
503  sb.appendf("0x%x", static_cast<uint32_t>(al->tcpClient->tos));
504  out = sb.c_str();
505  }
506  break;
507 
509  if (al->tcpClient) {
510  sb.appendf("0x%x", al->tcpClient->nfmark);
511  out = sb.c_str();
512  }
513  break;
514 
516  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw())) {
517  outint = addr->port();
518  doint = 1;
519  }
520  break;
521 
523  if (al->tcpClient) {
524  outint = al->tcpClient->local.port();
525  doint = 1;
526  }
527  break;
528 
530  case LFT_SERVER_LOCAL_IP:
531  if (al->hier.tcpServer)
532  out = al->hier.tcpServer->local.toStr(tmp, sizeof(tmp));
533  break;
534 
536  if (al->hier.tcpServer) {
537  outint = al->hier.tcpServer->local.port();
538  doint = 1;
539  }
540  break;
541 
543  if (al->hier.tcpServer) {
544  sb.appendf("0x%x", static_cast<uint32_t>(al->hier.tcpServer->tos));
545  out = sb.c_str();
546  }
547  break;
548 
550  if (al->hier.tcpServer) {
551  sb.appendf("0x%x", al->hier.tcpServer->nfmark);
552  out = sb.c_str();
553  }
554  break;
555 
557  if (al->request && al->request->clientConnectionManager.valid()) {
558  const auto &handshake = al->request->clientConnectionManager->preservedClientData;
559  if (const auto rawLength = handshake.length()) {
560  // add 1 byte to optimize the c_str() conversion below
561  char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1);
562 
563  struct base64_encode_ctx ctx;
564  base64_encode_init(&ctx);
565  auto encLength = base64_encode_update(&ctx, buf, rawLength, reinterpret_cast<const uint8_t*>(handshake.rawContent()));
566  encLength += base64_encode_final(&ctx, buf + encLength);
567 
568  sb.rawAppendFinish(buf, encLength);
569  out = sb.c_str();
570  }
571  }
572  break;
573 
575  // some platforms store time in 32-bit, some 64-bit...
576  outoff = static_cast<int64_t>(current_time.tv_sec);
577  dooff = 1;
578  break;
579 
580  case LFT_TIME_SUBSECOND:
581  outint = current_time.tv_usec / fmt->divisor;
582  doint = 1;
583  break;
584 
585  case LFT_TIME_LOCALTIME:
586  case LFT_TIME_GMT: {
587  const char *spec;
588  struct tm *t;
589  spec = fmt->data.string;
590 
591  if (fmt->type == LFT_TIME_LOCALTIME) {
592  if (!spec)
593  spec = "%d/%b/%Y:%H:%M:%S %z";
594  t = localtime(&squid_curtime);
595  } else {
596  if (!spec)
597  spec = "%d/%b/%Y:%H:%M:%S";
598 
599  t = gmtime(&squid_curtime);
600  }
601 
602  strftime(tmp, sizeof(tmp), spec, t);
603  out = tmp;
604  }
605  break;
606 
607  case LFT_TIME_START:
608  outtv = al->cache.start_time;
609  doSec = 1;
610  break;
611 
613  outtv = al->cache.trTime;
614  doMsec = 1;
615  break;
616 
618  struct timeval peerResponseTime;
619  if (al->hier.peerResponseTime(peerResponseTime)) {
620  outtv = peerResponseTime;
621  doMsec = 1;
622  }
623  break;
624 
626  struct timeval totalResponseTime;
627  if (al->hier.totalResponseTime(totalResponseTime)) {
628  outtv = totalResponseTime;
629  doMsec = 1;
630  }
631  }
632  break;
633 
634  case LFT_DNS_WAIT_TIME:
635  if (al->request && al->request->dnsWait >= 0) {
636  // TODO: microsecond precision for dns wait time.
637  // Convert miliseconds to timeval struct:
638  outtv.tv_sec = al->request->dnsWait / 1000;
639  outtv.tv_usec = (al->request->dnsWait % 1000) * 1000;
640  doMsec = 1;
641  }
642  break;
643 
644  case LFT_REQUEST_HEADER:
645  if (const Http::Message *msg = actualRequestHeader(al)) {
646  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
647  out = sb.c_str();
648  quote = 1;
649  }
650  break;
651 
653  if (al->adapted_request) {
654  sb = StringToSBuf(al->adapted_request->header.getByName(fmt->data.header.header));
655  out = sb.c_str();
656  quote = 1;
657  }
658  break;
659 
660  case LFT_REPLY_HEADER:
661  if (const Http::Message *msg = actualReplyHeader(al)) {
662  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
663  out = sb.c_str();
664  quote = 1;
665  }
666  break;
667 
668 #if USE_ADAPTATION
670  if (al->request) {
672  if (ah) {
673  ah->sumLogString(fmt->data.string, sb);
674  out = sb.c_str();
675  }
676  }
677  break;
678 
680  if (al->request) {
682  if (ah) {
683  ah->allLogString(fmt->data.string, sb);
684  out = sb.c_str();
685  }
686  }
687  break;
688 
690  if (al->request) {
692  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
693  sb = StringToSBuf(ah->allMeta.getByName(fmt->data.header.header));
694  out = sb.c_str();
695  quote = 1;
696  }
697  }
698  break;
699 
701  if (al->request) {
703  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
704  sb = ah->allMeta.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
705  out = sb.c_str();
706  quote = 1;
707  }
708  }
709  break;
710 
712  out = al->adapt.last_meta;
713  quote = 1;
714  break;
715 #endif
716 
717 #if ICAP_CLIENT
718  case LFT_ICAP_ADDR:
719  out = al->icap.hostAddr.toStr(tmp, sizeof(tmp));
720  break;
721 
722  case LFT_ICAP_SERV_NAME:
723  out = al->icap.serviceName.termedBuf();
724  break;
725 
727  out = al->icap.reqUri.termedBuf();
728  break;
729 
732  break;
733 
734  case LFT_ICAP_BYTES_SENT:
735  outoff = al->icap.bytesSent;
736  dooff = 1;
737  break;
738 
739  case LFT_ICAP_BYTES_READ:
740  outoff = al->icap.bytesRead;
741  dooff = 1;
742  break;
743 
745  if (al->icap.bodyBytesRead >= 0) {
746  outoff = al->icap.bodyBytesRead;
747  dooff = 1;
748  }
749  // else if icap.bodyBytesRead < 0, we do not have any http data,
750  // so just print a "-" (204 responses etc)
751  break;
752 
753  case LFT_ICAP_REQ_HEADER:
754  if (al->icap.request) {
755  sb = StringToSBuf(al->icap.request->header.getByName(fmt->data.header.header));
756  out = sb.c_str();
757  quote = 1;
758  }
759  break;
760 
762  if (al->icap.request) {
763  sb = al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
764  out = sb.c_str();
765  quote = 1;
766  }
767  break;
768 
770  if (al->icap.request) {
772  while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
773  sb.append(e->name);
774  sb.append(": ");
775  sb.append(StringToSBuf(e->value));
776  sb.append("\r\n");
777  }
778  out = sb.c_str();
779  quote = 1;
780  }
781  break;
782 
783  case LFT_ICAP_REP_HEADER:
784  if (al->icap.reply) {
785  sb = StringToSBuf(al->icap.reply->header.getByName(fmt->data.header.header));
786  out = sb.c_str();
787  quote = 1;
788  }
789  break;
790 
792  if (al->icap.reply) {
793  sb = al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
794  out = sb.c_str();
795  quote = 1;
796  }
797  break;
798 
800  if (al->icap.reply) {
802  while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
803  sb.append(e->name);
804  sb.append(": ");
805  sb.append(StringToSBuf(e->value));
806  sb.append("\r\n");
807  }
808  out = sb.c_str();
809  quote = 1;
810  }
811  break;
812 
814  outtv = al->icap.trTime;
815  doMsec = 1;
816  break;
817 
818  case LFT_ICAP_IO_TIME:
819  outtv = al->icap.ioTime;
820  doMsec = 1;
821  break;
822 
824  outint = al->icap.resStatus;
825  doint = 1;
826  break;
827 
828  case LFT_ICAP_OUTCOME:
829  out = al->icap.outcome;
830  break;
831 
832  case LFT_ICAP_TOTAL_TIME:
833  outtv = al->icap.processingTime;
834  doMsec = 1;
835  break;
836 #endif
838  if (const Http::Message *msg = actualRequestHeader(al)) {
839  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
840  out = sb.c_str();
841  quote = 1;
842  }
843  break;
844 
846  if (al->proxyProtocolHeader) {
847  sb = al->proxyProtocolHeader->getValues(fmt->data.headerId, fmt->data.header.separator);
848  out = sb.c_str();
849  quote = 1;
850  }
851  break;
852 
854  if (al->proxyProtocolHeader) {
855  sb = al->proxyProtocolHeader->toMime();
856  out = sb.c_str();
857  quote = 1;
858  }
859  break;
860 
862  if (al->proxyProtocolHeader) {
863  sb = al->proxyProtocolHeader->getElem(fmt->data.headerId, fmt->data.header.element, fmt->data.header.separator);
864  out = sb.c_str();
865  quote = 1;
866  }
867  break;
868 
870  if (al->adapted_request) {
871  sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
872  out = sb.c_str();
873  quote = 1;
874  }
875  break;
876 
878  if (const Http::Message *msg = actualReplyHeader(al)) {
879  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
880  out = sb.c_str();
881  quote = 1;
882  }
883  break;
884 
886 #if ICAP_CLIENT
888  // XXX: since AccessLogEntry::Headers lacks virgin response
889  // headers, do nothing for now
890  out = nullptr;
891  } else
892 #endif
893  {
894  out = al->headers.request;
895  quote = 1;
896  }
897  break;
898 
900  out = al->headers.adapted_request;
901  quote = 1;
902  break;
903 
905  out = al->headers.reply;
906 #if ICAP_CLIENT
907  if (!out && al->icap.reqMethod == Adaptation::methodReqmod)
908  out = al->headers.adapted_request;
909 #endif
910  quote = 1;
911  break;
912 
913  case LFT_USER_NAME:
914 #if USE_AUTH
915  if (al->request && al->request->auth_user_request)
917 #endif
918  if (!out && al->request && al->request->extacl_user.size()) {
919  if (const char *t = al->request->extacl_user.termedBuf())
920  out = t;
921  }
922  if (!out)
923  out = strOrNull(al->getExtUser());
924 #if USE_OPENSSL
925  if (!out)
926  out = strOrNull(al->cache.ssluser);
927 #endif
928  if (!out)
929  out = strOrNull(al->getClientIdent());
930  break;
931 
932  case LFT_USER_LOGIN:
933 #if USE_AUTH
934  if (al->request && al->request->auth_user_request)
936 #endif
937  break;
938 
939  case LFT_USER_IDENT:
940  out = strOrNull(al->getClientIdent());
941  break;
942 
943  case LFT_USER_EXTERNAL:
944  out = strOrNull(al->getExtUser());
945  break;
946 
947  /* case LFT_USER_REALM: */
948  /* case LFT_USER_SCHEME: */
949 
950  // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
951  // but compiler complains if ommited
954  outint = al->http.code;
955  doint = 1;
956  break;
957 
959  if (al->hier.peer_reply_status != Http::scNone) {
960  outint = al->hier.peer_reply_status;
961  doint = 1;
962  }
963  break;
964  /* case LFT_HTTP_STATUS:
965  * out = statusline->text;
966  * quote = 1;
967  * break;
968  */
970  if (al->hier.bodyBytesRead >= 0) {
971  outoff = al->hier.bodyBytesRead;
972  dooff = 1;
973  }
974  // else if hier.bodyBytesRead < 0 we did not have any data exchange with
975  // a peer server so just print a "-" (eg requests served from cache,
976  // or internal error messages).
977  break;
978 
979  case LFT_SQUID_STATUS:
980  out = al->cache.code.c_str();
981  break;
982 
983  case LFT_SQUID_ERROR:
984  if (al->request && al->request->errType != ERR_NONE)
985  out = errorPageName(al->request->errType);
986  break;
987 
989 #if USE_OPENSSL
990  if (al->request && al->request->errType == ERR_SECURE_CONNECT_FAIL) {
991  out = Ssl::GetErrorName(al->request->errDetail);
992  if (!out)
993  out = sslErrorName(al->request->errDetail, tmp, sizeof(tmp));
994  } else
995 #endif
996  if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
998  out = errorDetailName(al->request->errDetail);
999  else {
1001  sb.appendf("%s=0x%X",
1002  errorDetailName(al->request->errDetail), (uint32_t) al->request->errDetail);
1003  else
1004  sb.appendf("%s=%d",
1006  out = sb.c_str();
1007  }
1008  }
1009  break;
1010 
1011  case LFT_SQUID_HIERARCHY:
1012  if (al->hier.ping.timedout)
1013  mb.append("TIMEOUT_", 8);
1014  out = hier_code_str[al->hier.code];
1015  break;
1016 
1017  case LFT_MIME_TYPE:
1018  out = al->http.content_type;
1019  break;
1020 
1021  case LFT_CLIENT_REQ_METHOD:
1022  if (al->request) {
1023  sb = al->request->method.image();
1024  out = sb.c_str();
1025  quote = 1;
1026  }
1027  break;
1028 
1029  case LFT_CLIENT_REQ_URI:
1030  if (const auto uri = al->effectiveVirginUrl()) {
1031  sb = *uri;
1032  out = sb.c_str();
1033  quote = 1;
1034  }
1035  break;
1036 
1038  if (al->request) {
1039  sb = al->request->url.getScheme().image();
1040  out = sb.c_str();
1041  quote = 1;
1042  }
1043  break;
1044 
1046  if (al->request) {
1047  out = al->request->url.host();
1048  quote = 1;
1049  }
1050  break;
1051 
1053  if (al->request) {
1054  outint = al->request->url.port();
1055  doint = 1;
1056  }
1057  break;
1058 
1061  if (al->request) {
1062  sb = al->request->url.path();
1063  out = sb.c_str();
1064  quote = 1;
1065  }
1066  break;
1067 
1069  if (al->request) {
1070  sb.appendf("%u.%u", al->request->http_ver.major, al->request->http_ver.minor);
1071  out = sb.c_str();
1072  }
1073  break;
1074 
1075  case LFT_REQUEST_METHOD:
1076  sb = al->getLogMethod();
1077  out = sb.c_str();
1078  quote = 1;
1079  break;
1080 
1081  case LFT_REQUEST_URI:
1082  if (!al->url.isEmpty()) {
1083  sb = al->url;
1084  out = sb.c_str();
1085  }
1086  break;
1087 
1089  case LFT_REQUEST_VERSION:
1090  sb.appendf("%u.%u", al->http.version.major, al->http.version.minor);
1091  out = sb.c_str();
1092  break;
1093 
1094  case LFT_SERVER_REQ_METHOD:
1095  if (al->adapted_request) {
1096  sb = al->adapted_request->method.image();
1097  out = sb.c_str();
1098  quote = 1;
1099  }
1100  break;
1101 
1102  case LFT_SERVER_REQ_URI:
1103  // adapted request URI sent to server/peer
1104  if (al->adapted_request) {
1106  out = sb.c_str();
1107  quote = 1;
1108  }
1109  break;
1110 
1112  if (al->adapted_request) {
1113  sb = al->adapted_request->url.getScheme().image();
1114  out = sb.c_str();
1115  quote = 1;
1116  }
1117  break;
1118 
1120  if (al->adapted_request) {
1121  out = al->adapted_request->url.host();
1122  quote = 1;
1123  }
1124  break;
1125 
1127  if (al->adapted_request) {
1128  outint = al->adapted_request->url.port();
1129  doint = 1;
1130  }
1131  break;
1132 
1134  if (al->adapted_request) {
1135  sb = al->adapted_request->url.path();
1136  out = sb.c_str();
1137  quote = 1;
1138  }
1139  break;
1140 
1142  if (al->adapted_request) {
1143  sb.appendf("%u.%u",
1146  out = tmp;
1147  }
1148  break;
1149 
1151  outoff = al->http.clientRequestSz.messageTotal();
1152  dooff = 1;
1153  break;
1154 
1156  outoff = al->http.clientRequestSz.header;
1157  dooff =1;
1158  break;
1159 
1160  /*case LFT_REQUEST_SIZE_BODY: */
1161  /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
1162 
1164  outoff = al->http.clientReplySz.messageTotal();
1165  dooff = 1;
1166  break;
1167 
1168  case LFT_REPLY_HIGHOFFSET:
1169  outoff = al->cache.highOffset;
1170  dooff = 1;
1171  break;
1172 
1173  case LFT_REPLY_OBJECTSIZE:
1174  outoff = al->cache.objectSize;
1175  dooff = 1;
1176  break;
1177 
1179  outint = al->http.clientReplySz.header;
1180  doint = 1;
1181  break;
1182 
1183  /*case LFT_REPLY_SIZE_BODY: */
1184  /*case LFT_REPLY_SIZE_BODY_NO_TE: */
1185 
1188  doint = 1;
1189  break;
1190  /*case LFT_SERVER_IO_SIZE_TOTAL: */
1191 
1192  case LFT_TAG:
1193  if (al->request) {
1194  out = al->request->tag.termedBuf();
1195  quote = 1;
1196  }
1197  break;
1198 
1199  case LFT_EXT_LOG:
1200  if (al->request) {
1201  out = al->request->extacl_log.termedBuf();
1202  quote = 1;
1203  }
1204  break;
1205 
1206  case LFT_SEQUENCE_NUMBER:
1207  outoff = logSequenceNumber;
1208  dooff = 1;
1209  break;
1210 
1211 #if USE_OPENSSL
1212  case LFT_SSL_BUMP_MODE: {
1213  const Ssl::BumpMode mode = static_cast<Ssl::BumpMode>(al->ssl.bumpMode);
1214  // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
1215  out = Ssl::bumpMode(mode);
1216  }
1217  break;
1218 
1220  if (al->request) {
1222  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1223  if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) {
1224  sb = sslGetUserCertificatePEM(ssl);
1225  out = sb.c_str();
1226  }
1227  }
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()) {
1236  sb = sslGetUserCertificatePEM(ssl);
1237  out = sb.c_str();
1238  }
1239  }
1240  }
1241  break;
1242 
1243  case LFT_EXT_ACL_USER_CERT:
1244  if (al->request) {
1246  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1247  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1248  out = sslGetUserAttribute(ssl, fmt->data.header.header);
1249  }
1250  }
1251  break;
1252 
1254  if (al->request) {
1256  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1257  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1258  out = sslGetCAAttribute(ssl, fmt->data.header.header);
1259  }
1260  }
1261  break;
1262 
1264  if (X509 *cert = al->cache.sslClientCert.get()) {
1265  if (X509_NAME *subject = X509_get_subject_name(cert)) {
1266  X509_NAME_oneline(subject, tmp, sizeof(tmp));
1267  out = tmp;
1268  }
1269  }
1270  break;
1271 
1273  if (X509 *cert = al->cache.sslClientCert.get()) {
1274  if (X509_NAME *issuer = X509_get_issuer_name(cert)) {
1275  X509_NAME_oneline(issuer, tmp, sizeof(tmp));
1276  out = tmp;
1277  }
1278  }
1279  break;
1280 
1281  case LFT_SSL_CLIENT_SNI:
1282  if (al->request && al->request->clientConnectionManager.valid()) {
1283  if (const ConnStateData *conn = al->request->clientConnectionManager.get()) {
1284  if (!conn->tlsClientSni().isEmpty()) {
1285  sb = conn->tlsClientSni();
1286  out = sb.c_str();
1287  }
1288  }
1289  }
1290  break;
1291 
1293  if (al->request && al->request->clientConnectionManager.valid()) {
1294  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1295  const char *separator = fmt->data.string ? fmt->data.string : ":";
1296  for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) {
1297  if (!sb.isEmpty())
1298  sb.append(separator);
1299  if (const char *errorName = Ssl::GetErrorName(sslError->element.code))
1300  sb.append(errorName);
1301  else
1302  sb.append(sslErrorName(sslError->element.code, tmp, sizeof(tmp)));
1303  if (sslError->element.depth >= 0)
1304  sb.appendf("@depth=%d", sslError->element.depth);
1305  }
1306  if (!sb.isEmpty())
1307  out = sb.c_str();
1308  }
1309  }
1310  break;
1311 
1315  if (al->request && al->request->clientConnectionManager.valid()) {
1316  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1317  if (X509 *serverCert = srvBump->serverCert.get()) {
1318  if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT)
1319  out = Ssl::GetX509UserAttribute(serverCert, "DN");
1320  else if (fmt->type == LFT_SSL_SERVER_CERT_ISSUER)
1321  out = Ssl::GetX509CAAttribute(serverCert, "DN");
1322  else {
1323  assert(fmt->type == LFT_SSL_SERVER_CERT_WHOLE);
1324  sb = Ssl::GetX509PEM(serverCert);
1325  out = sb.c_str();
1326  quote = 1;
1327  }
1328  }
1329  }
1330  }
1331  break;
1332 
1334  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1336  break;
1337 
1339  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1341  break;
1342 
1344  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1345  out = al->tcpClient->hasTlsNegotiations()->helloVersion();
1346  break;
1347 
1349  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1351  break;
1352 
1354  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1356  break;
1357 
1359  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1361  break;
1362 
1364  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1365  out = al->tcpClient->hasTlsNegotiations()->cipherName();
1366  break;
1367 
1369  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1370  out = al->hier.tcpServer->hasTlsNegotiations()->cipherName();
1371  break;
1372 #endif
1373 
1375  assert(LFT_REQUEST_URLGROUP_OLD_2X == 0); // should never happen.
1376 
1377  case LFT_NOTE:
1378  tmp[0] = fmt->data.header.separator;
1379  tmp[1] = '\0';
1380  if (fmt->data.header.header && *fmt->data.header.header) {
1381  const char *separator = tmp;
1382  static SBuf note;
1383 #if USE_ADAPTATION
1385  if (ah && ah->metaHeaders) {
1386  if (ah->metaHeaders->find(note, fmt->data.header.header, separator))
1387  sb.append(note);
1388  }
1389 #endif
1390  if (al->notes) {
1391  if (al->notes->find(note, fmt->data.header.header, separator)) {
1392  if (!sb.isEmpty())
1393  sb.append(separator);
1394  sb.append(note);
1395  }
1396  }
1397  out = sb.c_str();
1398  quote = 1;
1399  } else {
1400  // if no argument given use default "\r\n" as notes separator
1401  const char *separator = fmt->data.string ? tmp : "\r\n";
1402 #if USE_ADAPTATION
1404  if (ah && ah->metaHeaders && !ah->metaHeaders->empty())
1405  sb.append(ah->metaHeaders->toString(separator));
1406 #endif
1407  if (al->notes && !al->notes->empty())
1408  sb.append(al->notes->toString(separator));
1409 
1410  out = sb.c_str();
1411  quote = 1;
1412  }
1413  break;
1414 
1415  case LFT_CREDENTIALS:
1416 #if USE_AUTH
1417  if (al->request && al->request->auth_user_request)
1419 #endif
1420  break;
1421 
1422  case LFT_PERCENT:
1423  out = "%";
1424  break;
1425 
1426  case LFT_EXT_ACL_NAME:
1427  out = al->lastAclName;
1428  break;
1429 
1430  case LFT_EXT_ACL_DATA:
1431  if (!al->lastAclData.isEmpty())
1432  out = al->lastAclData.c_str();
1433  break;
1434  }
1435 
1436  if (dooff) {
1437  sb.appendf("%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff);
1438  out = sb.c_str();
1439 
1440  } else if (doint) {
1441  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
1442  out = sb.c_str();
1443  } else if (doMsec) {
1444  if (fmt->widthMax < 0) {
1445  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, tvToMsec(outtv));
1446  } else {
1447  int precision = fmt->widthMax;
1448  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)));
1449  }
1450  out = sb.c_str();
1451  } else if (doSec) {
1452  int precision = fmt->widthMax >=0 ? fmt->widthMax :3;
1453  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));
1454  out = sb.c_str();
1455  }
1456 
1457  if (out && *out) {
1458  if (quote || fmt->quote != LOG_QUOTE_NONE) {
1459  // Do not write to the tmp buffer because it may contain the to-be-quoted value.
1460  static char quotedOut[2 * sizeof(tmp)];
1461  static_assert(sizeof(quotedOut) > 0, "quotedOut has zero length");
1462  quotedOut[0] = '\0';
1463 
1464  char *newout = NULL;
1465  int newfree = 0;
1466 
1467  switch (fmt->quote) {
1468 
1469  case LOG_QUOTE_NONE:
1470  newout = rfc1738_escape_unescaped(out);
1471  break;
1472 
1473  case LOG_QUOTE_QUOTES: {
1474  size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
1475  if (out_len >= sizeof(tmp)) {
1476  newout = (char *)xmalloc(out_len);
1477  newfree = 1;
1478  } else
1479  newout = quotedOut;
1480  log_quoted_string(out, newout);
1481  }
1482  break;
1483 
1484  case LOG_QUOTE_MIMEBLOB:
1485  newout = QuoteMimeBlob(out);
1486  newfree = 1;
1487  break;
1488 
1489  case LOG_QUOTE_URL:
1490  newout = rfc1738_escape(out);
1491  break;
1492 
1493  case LOG_QUOTE_SHELL: {
1494  MemBuf mbq;
1495  mbq.init();
1496  strwordquote(&mbq, out);
1497  newout = mbq.content();
1498  mbq.stolen = 1;
1499  newfree = 1;
1500  }
1501  break;
1502 
1503  case LOG_QUOTE_RAW:
1504  break;
1505  }
1506 
1507  if (newout) {
1508  if (dofree)
1509  safe_free(out);
1510 
1511  out = newout;
1512 
1513  dofree = newfree;
1514  }
1515  }
1516 
1517  // enforce width limits if configured
1518  const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff && !doMsec && !doSec;
1519  if (haveMaxWidth || fmt->widthMin) {
1520  const int minWidth = fmt->widthMin >= 0 ?
1521  fmt->widthMin :0;
1522  const int maxWidth = haveMaxWidth ?
1523  fmt->widthMax : strlen(out);
1524 
1525  if (fmt->left)
1526  mb.appendf("%-*.*s", minWidth, maxWidth, out);
1527  else
1528  mb.appendf("%*.*s", minWidth, maxWidth, out);
1529  } else
1530  mb.append(out, strlen(out));
1531  } else {
1532  mb.append("-", 1);
1533  }
1534 
1535  if (fmt->space)
1536  mb.append(" ", 1);
1537 
1538  sb.clear();
1539 
1540  if (dofree)
1541  safe_free(out);
1542  }
1543 }
1544 
static char * sslErrorName(Security::ErrorCode err, char *buf, size_t size)
Definition: Format.cc:345
GETX509ATTRIBUTE GetX509UserAttribute
Definition: support.h:118
void assemble(MemBuf &mb, const AccessLogEntryPointer &al, int logSequenceNumber) const
assemble the state information into a formatted line.
Definition: Format.cc:385
err_type errType
Definition: HttpRequest.h:161
#define rfc1738_escape_unescaped(x)
Definition: rfc1738.h:59
#define fd_table
Definition: fde.h:157
Ssl::ServerBump * serverBump()
Definition: client_side.h:253
RefCount< Adaptation::History > Pointer
Definition: History.h:26
unsigned short port() const
Definition: Address.cc:778
#define assert(EX)
Definition: assert.h:17
SBuf & appendf(const char *fmt,...)
Definition: SBuf.cc:239
int timedout
Definition: PingData.h:25
const char * toString(const char *sep="\") const
Definition: Notes.cc:254
const char * getClientIdent() const
Fetch the client IDENT string, or nil if none is available.
String extacl_log
Definition: HttpRequest.h:183
class AccessLogEntry::IcapLogEntry icap
#define HttpHeaderInitPos
Definition: HttpHeader.h:48
Token * format
Definition: Format.h:60
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:216
SBuf image() const
Definition: UriScheme.h:50
NotePairs::Pointer notes
int errDetail
errType-specific detail about the transaction error
Definition: HttpRequest.h:162
nfmark_t nfmark
Definition: Connection.h:152
const char * GetErrorName(Security::ErrorCode value)
The string representation of the TLS error "value".
Definition: ErrorDetail.cc:393
int type
Definition: errorpage.cc:152
Format(const char *name)
Definition: Format.cc:42
void path(const char *p)
Definition: Uri.h:86
Definition: SBuf.h:86
String getByName(const SBuf &name) const
Definition: HttpHeader.cc:888
virtual void append(char const *, int)
Appends a c-string to existing packed data.
Definition: store.cc:829
Token * next
Definition: Token.h:71
Comm::ConnectionPointer tcpServer
TCP/IP level details of the last peer/server connection.
HttpRequestMethod method
Definition: HttpRequest.h:114
int bumpMode
whether and how the request was SslBumped
#define xstrdup
#define PRId64
Definition: types.h:110
SBuf & append(const SBuf &S)
Definition: SBuf.cc:195
SBuf preservedClientData
Definition: client_side.h:312
T * get() const
Returns raw and possibly nullptr pointer.
struct timeval start_time
The time the master transaction started.
static const Http::Message * actualReplyHeader(const AccessLogEntry::Pointer &al)
Definition: Format.cc:358
#define safe_free(x)
Definition: xalloc.h:73
const char * bumpMode(int bm)
Definition: support.h:149
const char * getExtUser() const
Fetch the external ACL provided &#39;user=&#39; string, or nil if none is available.
bool totalResponseTime(struct timeval &responseTime)
Definition: access_log.cc:344
void getLogClientIp(char *buf, size_t bufsz) const
int parse(const char *def, enum Quoting *quote)
Definition: Token.cc:285
const char * methodStr(Method)
Definition: Elements.cc:15
#define rfc1738_escape(x)
Definition: rfc1738.h:52
bool encode(char *buf, const int len) const
Definition: Eui48.cc:119
static struct stat sb
Definition: squidclient.cc:71
MessageSizes clientReplySz
counters for the response sent to client
Adaptation::History::Pointer adaptHistory(bool createIfNone=false) const
Returns possibly nil history, creating it if requested.
Definition: HttpRequest.cc:415
struct timeval trTime
The response time.
char * QuoteMimeBlob(const char *header)
Definition: Quoting.cc:43
HttpRequest * request
ICAP request.
void clear()
Definition: SBuf.cc:178
bool isEmpty() const
Definition: SBuf.h:420
char * last_meta
image of the last ICAP response header or eCAP meta received
static void log_quoted_string(const char *str, char *out)
Definition: Format.cc:291
Comm::ConnectionPointer tcpClient
TCP/IP level details about the client connection.
AnyP::ProtocolVersion http_ver
Definition: Message.h:73
HttpHeaderEntry * getEntry(HttpHeaderPos *pos) const
Definition: HttpHeader.cc:598
char * p
Definition: membanger.c:43
int conn
the current server connection FD
Definition: Transport.cc:26
const char * sslGetUserAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:685
Quoting
Quoting style for a format output.
Definition: ByteCode.h:256
struct timeval current_time
Definition: stub_time.cc:15
const char * errorDetailName(int errDetailId)
const char * helloVersion() const
String representation of the received TLS hello message version.
Eui::Eui64 remoteEui64
Definition: Connection.h:169
char host[SQUIDHOSTNAMELEN]
virtual ~Format()
Definition: Format.cc:49
String reqUri
ICAP Request-URI.
time_t squid_curtime
Definition: stub_time.cc:17
const Security::NegotiationHistory * hasTlsNegotiations() const
Definition: Connection.h:124
SBuf getLogMethod() const
Fetch the transaction method string (ICP opcode, HTCP opcode or HTTP method)
CbDataList * next
Definition: CbDataList.h:31
static const Http::Message * actualRequestHeader(const AccessLogEntry::Pointer &al)
Definition: Format.cc:372
NotePairs::Pointer metaHeaders
Definition: History.h:65
const char * lastAclName
string for external_acl_type ACL format code
Eui::Eui48 remoteEui48
Definition: Connection.h:168
int64_t bodyBytesRead
number of body bytes received from the next hop or -1
void init(mb_size_t szInit, mb_size_t szMax)
Definition: MemBuf.cc:96
bool isIPv4() const
Definition: Address.cc:158
char const * username() const
Definition: UserRequest.cc:32
const char * sslGetCAAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:698
void rawAppendFinish(const char *start, size_type actualSize)
Definition: SBuf.cc:144
const char * cipherName() const
HttpRequest * adapted_request
void EVH void * arg
Definition: stub_event.cc:16
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
Definition: HttpRequest.cc:707
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:24
unsigned int major
major version number
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition: Address.cc:802
const char * c_str() const
compute the status access.log field
Definition: LogTags.cc:56
void port(unsigned short p)
Definition: Uri.h:83
char * rawAppendStart(size_type anticipatedSize)
Definition: SBuf.cc:136
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
const SBuf * effectiveVirginUrl() const
#define DBG_IMPORTANT
Definition: Debug.h:46
class AccessLogEntry::AdaptationDetails adapt
Cbc * valid() const
was set and is valid
Definition: CbcPointer.h:41
Ip::Address client_addr
Definition: HttpRequest.h:149
void allLogString(const char *serviceId, SBuf &)
dump individual xaction times to a string
Definition: History.cc:66
GETX509PEM GetX509PEM
Definition: support.h:124
HttpHeader allMeta
All REQMOD and RESPMOD meta headers merged. Last field wins conflicts.
Definition: History.h:62
int ErrorCode
Squid defined error code (<0), an error code returned by X.509 API, or SSL_ERROR_NONE.
Definition: forward.h:91
size_t AssembleOne(const char *start, MemBuf &buf, const AccessLogEntryPointer &ale)
Definition: Format.cc:99
SBuf getByNameListMember(const char *name, const char *member, const char separator) const
Definition: HttpHeader.cc:957
String tag
Definition: HttpRequest.h:177
const char * errorPageName(int pageId)
error ID to string
Definition: errorpage.cc:655
GETX509ATTRIBUTE GetX509CAAttribute
Definition: support.h:121
common parts of HttpRequest and HttpReply
Definition: Message.h:25
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
void * addr
Definition: membanger.c:46
void dump(StoreEntry *entry, const char *directiveName, bool eol=true) const
dump this whole list of formats into the provided StoreEntry
Definition: Format.cc:116
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:230
class AccessLogEntry::Headers headers
HttpRequest * request
bool find(SBuf &resultNote, const char *noteKey, const char *sep=",") const
Definition: Notes.cc:240
uint64_t header
Definition: MessageSizes.h:21
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition: base64.c:232
bool encode(char *buf, const int len) const
Definition: Eui64.cc:34
const char * c_str()
Definition: SBuf.cc:526
Adaptation::Icap::XactOutcome outcome
final transaction status
#define FQDN_LOOKUP_IF_MISS
Definition: defines.h:48
Format * next
Definition: Format.h:61
struct timeval processingTime
total ICAP processing time
class AccessLogEntry::HttpDetails http
void host(const char *src)
Definition: Uri.cc:47
Http::StatusCode resStatus
ICAP response status code.
int64_t bytesSent
number of bytes sent to ICAP server so far
virtual const char * credentialsStr()=0
bool isAnyAddr() const
Definition: Address.cc:170
int cur
Definition: ModDevPoll.cc:76
char const * termedBuf() const
Definition: SquidString.h:91
const char * negotiatedVersion() const
String representation of TLS negotiated version.
Security::CertPointer sslClientCert
cert received from the client
char * content()
start of the added data
Definition: MemBuf.h:41
struct timeval trTime
Transaction response time. The timer starts when the ICAP transaction is created and stops when the r...
SBuf sslGetUserCertificatePEM(SSL *ssl)
Definition: support.cc:718
void const char * buf
Definition: stub_helper.cc:16
std::ostream & HERE(std::ostream &s)
Definition: Debug.h:153
bool parse(const char *def)
Definition: Format.cc:66
class AccessLogEntry::CacheDetails cache
ssize_t HttpHeaderPos
Definition: HttpHeader.h:45
const SBuf & image() const
class AccessLogEntry::SslDetails ssl
const char * fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
Definition: fqdncache.cc:480
HttpReply * reply
ICAP reply.
Ip::Address local
Definition: Connection.h:135
HttpHeader header
Definition: Message.h:75
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
Definition: base64.c:308
unsigned stolen
Definition: MemBuf.h:151
String serviceName
ICAP service name.
long int tvToMsec(struct timeval &t)
Convert timeval to milliseconds.
Definition: SquidTime.h:43
struct timeval ioTime
Transaction I/O time. The timer starts when the first ICAP request byte is scheduled for sending and ...
Ip::Address remote
Definition: Connection.h:138
#define xmalloc
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:162
int dnsWait
sum of DNS lookup delays in milliseconds, for dt
Definition: HttpRequest.h:159
const Ip::Address * FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:805
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
Definition: base64.c:265
String extacl_user
Definition: HttpRequest.h:179
C * getRaw() const
Definition: RefCount.h:74
SBuf lastAclData
string for external_acl_type DATA format code
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
const char * quote
Definition: html_quote.c:21
Definition: MemBuf.h:23
bool peerResponseTime(struct timeval &responseTime)
Definition: access_log.cc:317
Comm::ConnectionPointer clientConnection
Definition: Server.h:97
Auth::UserRequest::Pointer auth_user_request
Definition: HttpRequest.h:127
const char * supportedVersion() const
const char * hier_code_str[]
AnyP::ProtocolVersion version
unsigned int minor
minor version number
BumpMode
Definition: support.h:135
SBuf StringToSBuf(const String &s)
create a new SBuf from a String by copying contents
Definition: StringConvert.h:17
Ip::Address hostAddr
ICAP server IP address.
AnyP::UriScheme const & getScheme() const
Definition: Uri.h:67
uint64_t messageTotal() const
total message size
Definition: MessageSizes.h:27
void sumLogString(const char *serviceId, SBuf &)
dump xaction times, merging retried and retry times together
Definition: History.cc:82
Adaptation::Icap::ICAP::Method reqMethod
ICAP request method.
#define strOrNull(s)
Convert a string to NULL pointer if it is "".
Definition: Format.cc:38
#define xfree
HierarchyLogEntry hier
const SBuf Dash
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:881
size_type size() const
Definition: SquidString.h:72
MessageSizes clientRequestSz
counters for the original request received from client
bool empty() const
Definition: Notes.h:242
ByteCode_t
Definition: ByteCode.h:30
#define NULL
Definition: types.h:166
Http::StatusCode peer_reply_status
last HTTP status code received
int size
Definition: ModDevPoll.cc:77
ProxyProtocol::HeaderPointer proxyProtocolHeader
see ConnStateData::proxyProtocolHeader_
#define base64_encode_len(length)
Definition: base64.h:169
int64_t bytesRead
number of bytes read from ICAP server so far
void strwordquote(MemBuf *mb, const char *str)
Definition: tools.cc:1042

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors