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 void
99 Format::Format::dump(StoreEntry * entry, const char *directiveName, bool eol) const
100 {
101  debugs(46, 4, HERE);
102 
103  // loop rather than recursing to conserve stack space.
104  for (const Format *fmt = this; fmt; fmt = fmt->next) {
105  debugs(46, 3, HERE << "Dumping format definition for " << fmt->name);
106  if (directiveName)
107  storeAppendPrintf(entry, "%s %s ", directiveName, fmt->name);
108 
109  for (Token *t = fmt->format; t; t = t->next) {
110  if (t->type == LFT_STRING)
111  storeAppendPrintf(entry, "%s", t->data.string);
112  else {
113  char argbuf[256];
114  char *arg = NULL;
115  ByteCode_t type = t->type;
116 
117  switch (type) {
118  /* special cases */
119 
120  case LFT_STRING:
121  break;
122 #if USE_ADAPTATION
124 #endif
125 #if ICAP_CLIENT
128 #endif
132 
133  if (t->data.header.separator != ',')
134  snprintf(argbuf, sizeof(argbuf), "%s:%c%s", t->data.header.header, t->data.header.separator, t->data.header.element);
135  else
136  snprintf(argbuf, sizeof(argbuf), "%s:%s", t->data.header.header, t->data.header.element);
137 
138  arg = argbuf;
139 
140  switch (type) {
142  type = LFT_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
143  break;
145  type = LFT_ADAPTED_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
146  break;
148  type = LFT_REPLY_HEADER_ELEM; // XXX: remove _ELEM?
149  break;
150 #if USE_ADAPTATION
153  break;
154 #endif
155 #if ICAP_CLIENT
157  type = LFT_ICAP_REQ_HEADER;
158  break;
160  type = LFT_ICAP_REP_HEADER;
161  break;
162 #endif
163  default:
164  break;
165  }
166 
167  break;
168 
172 
173 #if USE_ADAPTATION
175 #endif
176 #if ICAP_CLIENT
179 #endif
180 
181  switch (type) {
183  type = LFT_REQUEST_HEADER;
184  break;
187  break;
189  type = LFT_REPLY_HEADER;
190  break;
191 #if USE_ADAPTATION
194  break;
195 #endif
196 #if ICAP_CLIENT
198  type = LFT_ICAP_REQ_HEADER;
199  break;
201  type = LFT_ICAP_REP_HEADER;
202  break;
203 #endif
204  default:
205  break;
206  }
207 
208  break;
209 
210  default:
211  if (t->data.string)
212  arg = t->data.string;
213 
214  break;
215  }
216 
217  entry->append("%", 1);
218 
219  switch (t->quote) {
220 
221  case LOG_QUOTE_QUOTES:
222  entry->append("\"", 1);
223  break;
224 
225  case LOG_QUOTE_MIMEBLOB:
226  entry->append("[", 1);
227  break;
228 
229  case LOG_QUOTE_URL:
230  entry->append("#", 1);
231  break;
232 
233  case LOG_QUOTE_RAW:
234  entry->append("'", 1);
235  break;
236 
237  case LOG_QUOTE_SHELL:
238  entry->append("/", 1);
239  break;
240 
241  case LOG_QUOTE_NONE:
242  break;
243  }
244 
245  if (t->left)
246  entry->append("-", 1);
247 
248  if (t->zero)
249  entry->append("0", 1);
250 
251  if (t->widthMin >= 0)
252  storeAppendPrintf(entry, "%d", t->widthMin);
253 
254  if (t->widthMax >= 0)
255  storeAppendPrintf(entry, ".%d", t->widthMax);
256 
257  if (arg)
258  storeAppendPrintf(entry, "{%s}", arg);
259 
260  storeAppendPrintf(entry, "%s", t->label);
261 
262  if (t->space)
263  entry->append(" ", 1);
264  }
265  }
266 
267  if (eol)
268  entry->append("\n", 1);
269  }
270 
271 }
272 
273 static void
274 log_quoted_string(const char *str, char *out)
275 {
276  char *p = out;
277 
278  while (*str) {
279  int l = strcspn(str, "\"\\\r\n\t");
280  memcpy(p, str, l);
281  str += l;
282  p += l;
283 
284  switch (*str) {
285 
286  case '\0':
287  break;
288 
289  case '\r':
290  *p = '\\';
291  ++p;
292  *p = 'r';
293  ++p;
294  ++str;
295  break;
296 
297  case '\n':
298  *p = '\\';
299  ++p;
300  *p = 'n';
301  ++p;
302  ++str;
303  break;
304 
305  case '\t':
306  *p = '\\';
307  ++p;
308  *p = 't';
309  ++p;
310  ++str;
311  break;
312 
313  default:
314  *p = '\\';
315  ++p;
316  *p = *str;
317  ++p;
318  ++str;
319  break;
320  }
321  }
322 
323  *p = '\0';
324 }
325 
326 #if USE_OPENSSL
327 static char *
329 {
330  snprintf(buf, size, "SSL_ERR=%d", err);
331  return buf;
332 }
333 #endif
334 
340 static const Http::Message *
342 {
343  const Http::Message *msg = al->reply;
344 #if ICAP_CLIENT
345  // al->icap.reqMethod is methodNone in access.log context
346  if (!msg && al->icap.reqMethod == Adaptation::methodReqmod)
347  msg = al->adapted_request;
348 #endif
349  return msg;
350 }
351 
354 static const Http::Message *
356 {
357 #if ICAP_CLIENT
358  // al->icap.reqMethod is methodNone in access.log context
359  if (al->icap.reqMethod == Adaptation::methodRespmod) {
360  // XXX: for now AccessLogEntry lacks virgin response headers
361  return nullptr;
362  }
363 #endif
364  return al->request;
365 }
366 
367 void
368 Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logSequenceNumber) const
369 {
370  static char tmp[1024];
371  SBuf sb;
372 
373  for (Token *fmt = format; fmt; fmt = fmt->next) { /* for each token */
374  const char *out = nullptr;
375  int quote = 0;
376  long int outint = 0;
377  int doint = 0;
378  int dofree = 0;
379  int64_t outoff = 0;
380  int dooff = 0;
381  struct timeval outtv = {0, 0};
382  int doMsec = 0;
383  int doSec = 0;
384 
385  switch (fmt->type) {
386 
387  case LFT_NONE:
388  out = "";
389  break;
390 
391  case LFT_STRING:
392  out = fmt->data.string;
393  break;
394 
396  al->getLogClientIp(tmp, sizeof(tmp));
397  out = tmp;
398  break;
399 
400  case LFT_CLIENT_FQDN:
401  if (al->cache.caddr.isAnyAddr()) // e.g., ICAP OPTIONS lack client
402  out = "-";
403  else
405 
406  if (!out) {
407  out = al->cache.caddr.toStr(tmp, sizeof(tmp));
408  }
409  break;
410 
411  case LFT_CLIENT_PORT:
412  if (al->request) {
413  outint = al->request->client_addr.port();
414  doint = 1;
415  } else if (al->tcpClient) {
416  outint = al->tcpClient->remote.port();
417  doint = 1;
418  }
419  break;
420 
421  case LFT_CLIENT_EUI:
422 #if USE_SQUID_EUI
423  // TODO make the ACL checklist have a direct link to any TCP details.
424  if (al->request && al->request->clientConnectionManager.valid() &&
427  if (conn->remote.isIPv4())
428  conn->remoteEui48.encode(tmp, sizeof(tmp));
429  else
430  conn->remoteEui64.encode(tmp, sizeof(tmp));
431  out = tmp;
432  }
433 #endif
434  break;
435 
437 #if USE_SQUID_EUI
438  if (al->request && al->request->clientConnectionManager.valid() &&
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 (al->hier.tcpServer)
460  out = al->hier.tcpServer->remote.toStr(tmp, sizeof(tmp));
461  break;
462 
464  out = al->hier.host;
465  break;
466 
467  case LFT_SERVER_PORT:
468  if (al->hier.tcpServer) {
469  outint = al->hier.tcpServer->remote.port();
470  doint = 1;
471  }
472  break;
473 
475  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw()))
476  out = addr->toStr(tmp, sizeof(tmp));
477  break;
478 
479  case LFT_CLIENT_LOCAL_IP:
480  if (al->tcpClient)
481  out = al->tcpClient->local.toStr(tmp, sizeof(tmp));
482  break;
483 
485  if (al->tcpClient) {
486  sb.appendf("0x%x", static_cast<uint32_t>(al->tcpClient->tos));
487  out = sb.c_str();
488  }
489  break;
490 
492  if (al->tcpClient) {
493  sb.appendf("0x%x", al->tcpClient->nfmark);
494  out = sb.c_str();
495  }
496  break;
497 
499  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw())) {
500  outint = addr->port();
501  doint = 1;
502  }
503  break;
504 
506  if (al->tcpClient) {
507  outint = al->tcpClient->local.port();
508  doint = 1;
509  }
510  break;
511 
513  case LFT_SERVER_LOCAL_IP:
514  if (al->hier.tcpServer)
515  out = al->hier.tcpServer->local.toStr(tmp, sizeof(tmp));
516  break;
517 
519  if (al->hier.tcpServer) {
520  outint = al->hier.tcpServer->local.port();
521  doint = 1;
522  }
523  break;
524 
526  if (al->hier.tcpServer) {
527  sb.appendf("0x%x", static_cast<uint32_t>(al->hier.tcpServer->tos));
528  out = sb.c_str();
529  }
530  break;
531 
533  if (al->hier.tcpServer) {
534  sb.appendf("0x%x", al->hier.tcpServer->nfmark);
535  out = sb.c_str();
536  }
537  break;
538 
540  if (al->request && al->request->clientConnectionManager.valid()) {
541  const auto &handshake = al->request->clientConnectionManager->preservedClientData;
542  if (const auto rawLength = handshake.length()) {
543  // add 1 byte to optimize the c_str() conversion below
544  char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1);
545 
546  struct base64_encode_ctx ctx;
547  base64_encode_init(&ctx);
548  auto encLength = base64_encode_update(&ctx, buf, rawLength, reinterpret_cast<const uint8_t*>(handshake.rawContent()));
549  encLength += base64_encode_final(&ctx, buf + encLength);
550 
551  sb.rawAppendFinish(buf, encLength);
552  out = sb.c_str();
553  }
554  }
555  break;
556 
558  // some platforms store time in 32-bit, some 64-bit...
559  outoff = static_cast<int64_t>(current_time.tv_sec);
560  dooff = 1;
561  break;
562 
563  case LFT_TIME_SUBSECOND:
564  outint = current_time.tv_usec / fmt->divisor;
565  doint = 1;
566  break;
567 
568  case LFT_TIME_LOCALTIME:
569  case LFT_TIME_GMT: {
570  const char *spec;
571  struct tm *t;
572  spec = fmt->data.string;
573 
574  if (fmt->type == LFT_TIME_LOCALTIME) {
575  if (!spec)
576  spec = "%d/%b/%Y:%H:%M:%S %z";
577  t = localtime(&squid_curtime);
578  } else {
579  if (!spec)
580  spec = "%d/%b/%Y:%H:%M:%S";
581 
582  t = gmtime(&squid_curtime);
583  }
584 
585  strftime(tmp, sizeof(tmp), spec, t);
586  out = tmp;
587  }
588  break;
589 
590  case LFT_TIME_START:
591  outtv = al->cache.start_time;
592  doSec = 1;
593  break;
594 
596  outtv = al->cache.trTime;
597  doMsec = 1;
598  break;
599 
601  struct timeval peerResponseTime;
602  if (al->hier.peerResponseTime(peerResponseTime)) {
603  outtv = peerResponseTime;
604  doMsec = 1;
605  }
606  break;
607 
609  struct timeval totalResponseTime;
610  if (al->hier.totalResponseTime(totalResponseTime)) {
611  outtv = totalResponseTime;
612  doMsec = 1;
613  }
614  }
615  break;
616 
617  case LFT_DNS_WAIT_TIME:
618  if (al->request && al->request->dnsWait >= 0) {
619  // TODO: microsecond precision for dns wait time.
620  // Convert miliseconds to timeval struct:
621  outtv.tv_sec = al->request->dnsWait / 1000;
622  outtv.tv_usec = (al->request->dnsWait % 1000) * 1000;
623  doMsec = 1;
624  }
625  break;
626 
627  case LFT_REQUEST_HEADER:
628  if (const Http::Message *msg = actualRequestHeader(al)) {
629  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
630  out = sb.c_str();
631  quote = 1;
632  }
633  break;
634 
636  if (al->adapted_request) {
637  sb = StringToSBuf(al->adapted_request->header.getByName(fmt->data.header.header));
638  out = sb.c_str();
639  quote = 1;
640  }
641  break;
642 
643  case LFT_REPLY_HEADER:
644  if (const Http::Message *msg = actualReplyHeader(al)) {
645  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
646  out = sb.c_str();
647  quote = 1;
648  }
649  break;
650 
651 #if USE_ADAPTATION
653  if (al->request) {
655  if (ah) {
656  ah->sumLogString(fmt->data.string, sb);
657  out = sb.c_str();
658  }
659  }
660  break;
661 
663  if (al->request) {
665  if (ah) {
666  ah->allLogString(fmt->data.string, sb);
667  out = sb.c_str();
668  }
669  }
670  break;
671 
673  if (al->request) {
675  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
676  sb = StringToSBuf(ah->allMeta.getByName(fmt->data.header.header));
677  out = sb.c_str();
678  quote = 1;
679  }
680  }
681  break;
682 
684  if (al->request) {
686  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
687  sb = ah->allMeta.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
688  out = sb.c_str();
689  quote = 1;
690  }
691  }
692  break;
693 
695  out = al->adapt.last_meta;
696  quote = 1;
697  break;
698 #endif
699 
700 #if ICAP_CLIENT
701  case LFT_ICAP_ADDR:
702  out = al->icap.hostAddr.toStr(tmp, sizeof(tmp));
703  break;
704 
705  case LFT_ICAP_SERV_NAME:
706  out = al->icap.serviceName.termedBuf();
707  break;
708 
710  out = al->icap.reqUri.termedBuf();
711  break;
712 
715  break;
716 
717  case LFT_ICAP_BYTES_SENT:
718  outoff = al->icap.bytesSent;
719  dooff = 1;
720  break;
721 
722  case LFT_ICAP_BYTES_READ:
723  outoff = al->icap.bytesRead;
724  dooff = 1;
725  break;
726 
728  if (al->icap.bodyBytesRead >= 0) {
729  outoff = al->icap.bodyBytesRead;
730  dooff = 1;
731  }
732  // else if icap.bodyBytesRead < 0, we do not have any http data,
733  // so just print a "-" (204 responses etc)
734  break;
735 
736  case LFT_ICAP_REQ_HEADER:
737  if (al->icap.request) {
738  sb = StringToSBuf(al->icap.request->header.getByName(fmt->data.header.header));
739  out = sb.c_str();
740  quote = 1;
741  }
742  break;
743 
745  if (al->icap.request) {
746  sb = al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
747  out = sb.c_str();
748  quote = 1;
749  }
750  break;
751 
753  if (al->icap.request) {
755  while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
756  sb.append(e->name);
757  sb.append(": ");
758  sb.append(StringToSBuf(e->value));
759  sb.append("\r\n");
760  }
761  out = sb.c_str();
762  quote = 1;
763  }
764  break;
765 
766  case LFT_ICAP_REP_HEADER:
767  if (al->icap.reply) {
768  sb = StringToSBuf(al->icap.reply->header.getByName(fmt->data.header.header));
769  out = sb.c_str();
770  quote = 1;
771  }
772  break;
773 
775  if (al->icap.reply) {
776  sb = al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
777  out = sb.c_str();
778  quote = 1;
779  }
780  break;
781 
783  if (al->icap.reply) {
785  while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
786  sb.append(e->name);
787  sb.append(": ");
788  sb.append(StringToSBuf(e->value));
789  sb.append("\r\n");
790  }
791  out = sb.c_str();
792  quote = 1;
793  }
794  break;
795 
797  outtv = al->icap.trTime;
798  doMsec = 1;
799  break;
800 
801  case LFT_ICAP_IO_TIME:
802  outtv = al->icap.ioTime;
803  doMsec = 1;
804  break;
805 
807  outint = al->icap.resStatus;
808  doint = 1;
809  break;
810 
811  case LFT_ICAP_OUTCOME:
812  out = al->icap.outcome;
813  break;
814 
815  case LFT_ICAP_TOTAL_TIME:
816  outtv = al->icap.processingTime;
817  doMsec = 1;
818  break;
819 #endif
821  if (const Http::Message *msg = actualRequestHeader(al)) {
822  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
823  out = sb.c_str();
824  quote = 1;
825  }
826  break;
827 
829  if (al->proxyProtocolHeader) {
830  sb = al->proxyProtocolHeader->getValues(fmt->data.headerId, fmt->data.header.separator);
831  out = sb.c_str();
832  quote = 1;
833  }
834  break;
835 
837  if (al->proxyProtocolHeader) {
838  sb = al->proxyProtocolHeader->toMime();
839  out = sb.c_str();
840  quote = 1;
841  }
842  break;
843 
845  if (al->proxyProtocolHeader) {
846  sb = al->proxyProtocolHeader->getElem(fmt->data.headerId, fmt->data.header.element, fmt->data.header.separator);
847  out = sb.c_str();
848  quote = 1;
849  }
850  break;
851 
853  if (al->adapted_request) {
854  sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
855  out = sb.c_str();
856  quote = 1;
857  }
858  break;
859 
861  if (const Http::Message *msg = actualReplyHeader(al)) {
862  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
863  out = sb.c_str();
864  quote = 1;
865  }
866  break;
867 
869 #if ICAP_CLIENT
871  // XXX: since AccessLogEntry::Headers lacks virgin response
872  // headers, do nothing for now
873  out = nullptr;
874  } else
875 #endif
876  {
877  out = al->headers.request;
878  quote = 1;
879  }
880  break;
881 
883  out = al->headers.adapted_request;
884  quote = 1;
885  break;
886 
888  out = al->headers.reply;
889 #if ICAP_CLIENT
890  if (!out && al->icap.reqMethod == Adaptation::methodReqmod)
891  out = al->headers.adapted_request;
892 #endif
893  quote = 1;
894  break;
895 
896  case LFT_USER_NAME:
897 #if USE_AUTH
898  if (al->request && al->request->auth_user_request)
900 #endif
901  if (!out && al->request && al->request->extacl_user.size()) {
902  if (const char *t = al->request->extacl_user.termedBuf())
903  out = t;
904  }
905  if (!out)
906  out = strOrNull(al->getExtUser());
907 #if USE_OPENSSL
908  if (!out)
909  out = strOrNull(al->cache.ssluser);
910 #endif
911  if (!out)
912  out = strOrNull(al->getClientIdent());
913  break;
914 
915  case LFT_USER_LOGIN:
916 #if USE_AUTH
917  if (al->request && al->request->auth_user_request)
919 #endif
920  break;
921 
922  case LFT_USER_IDENT:
923  out = strOrNull(al->getClientIdent());
924  break;
925 
926  case LFT_USER_EXTERNAL:
927  out = strOrNull(al->getExtUser());
928  break;
929 
930  /* case LFT_USER_REALM: */
931  /* case LFT_USER_SCHEME: */
932 
933  // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
934  // but compiler complains if ommited
937  outint = al->http.code;
938  doint = 1;
939  break;
940 
942  if (al->hier.peer_reply_status != Http::scNone) {
943  outint = al->hier.peer_reply_status;
944  doint = 1;
945  }
946  break;
947  /* case LFT_HTTP_STATUS:
948  * out = statusline->text;
949  * quote = 1;
950  * break;
951  */
953  if (al->hier.bodyBytesRead >= 0) {
954  outoff = al->hier.bodyBytesRead;
955  dooff = 1;
956  }
957  // else if hier.bodyBytesRead < 0 we did not have any data exchange with
958  // a peer server so just print a "-" (eg requests served from cache,
959  // or internal error messages).
960  break;
961 
962  case LFT_SQUID_STATUS:
963  out = al->cache.code.c_str();
964  break;
965 
966  case LFT_SQUID_ERROR:
967  if (al->request && al->request->errType != ERR_NONE)
968  out = errorPageName(al->request->errType);
969  break;
970 
972 #if USE_OPENSSL
973  if (al->request && al->request->errType == ERR_SECURE_CONNECT_FAIL) {
974  out = Ssl::GetErrorName(al->request->errDetail);
975  if (!out)
976  out = sslErrorName(al->request->errDetail, tmp, sizeof(tmp));
977  } else
978 #endif
979  if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
981  out = errorDetailName(al->request->errDetail);
982  else {
984  sb.appendf("%s=0x%X",
985  errorDetailName(al->request->errDetail), (uint32_t) al->request->errDetail);
986  else
987  sb.appendf("%s=%d",
989  out = sb.c_str();
990  }
991  }
992  break;
993 
994  case LFT_SQUID_HIERARCHY:
995  if (al->hier.ping.timedout)
996  mb.append("TIMEOUT_", 8);
997  out = hier_code_str[al->hier.code];
998  break;
999 
1000  case LFT_MIME_TYPE:
1001  out = al->http.content_type;
1002  break;
1003 
1004  case LFT_CLIENT_REQ_METHOD:
1005  if (al->request) {
1006  sb = al->request->method.image();
1007  out = sb.c_str();
1008  quote = 1;
1009  }
1010  break;
1011 
1012  case LFT_CLIENT_REQ_URI:
1013  if (const auto uri = al->effectiveVirginUrl()) {
1014  sb = *uri;
1015  out = sb.c_str();
1016  quote = 1;
1017  }
1018  break;
1019 
1021  if (al->request) {
1022  sb = al->request->url.getScheme().image();
1023  out = sb.c_str();
1024  quote = 1;
1025  }
1026  break;
1027 
1029  if (al->request) {
1030  out = al->request->url.host();
1031  quote = 1;
1032  }
1033  break;
1034 
1036  if (al->request) {
1037  outint = al->request->url.port();
1038  doint = 1;
1039  }
1040  break;
1041 
1044  if (al->request) {
1045  sb = al->request->url.path();
1046  out = sb.c_str();
1047  quote = 1;
1048  }
1049  break;
1050 
1052  if (al->request) {
1053  sb.appendf("%u.%u", al->request->http_ver.major, al->request->http_ver.minor);
1054  out = sb.c_str();
1055  }
1056  break;
1057 
1058  case LFT_REQUEST_METHOD:
1059  sb = al->getLogMethod();
1060  out = sb.c_str();
1061  quote = 1;
1062  break;
1063 
1064  case LFT_REQUEST_URI:
1065  if (!al->url.isEmpty()) {
1066  sb = al->url;
1067  out = sb.c_str();
1068  }
1069  break;
1070 
1072  case LFT_REQUEST_VERSION:
1073  sb.appendf("%u.%u", al->http.version.major, al->http.version.minor);
1074  out = sb.c_str();
1075  break;
1076 
1077  case LFT_SERVER_REQ_METHOD:
1078  if (al->adapted_request) {
1079  sb = al->adapted_request->method.image();
1080  out = sb.c_str();
1081  quote = 1;
1082  }
1083  break;
1084 
1085  case LFT_SERVER_REQ_URI:
1086  // adapted request URI sent to server/peer
1087  if (al->adapted_request) {
1089  out = sb.c_str();
1090  quote = 1;
1091  }
1092  break;
1093 
1095  if (al->adapted_request) {
1096  sb = al->adapted_request->url.getScheme().image();
1097  out = sb.c_str();
1098  quote = 1;
1099  }
1100  break;
1101 
1103  if (al->adapted_request) {
1104  out = al->adapted_request->url.host();
1105  quote = 1;
1106  }
1107  break;
1108 
1110  if (al->adapted_request) {
1111  outint = al->adapted_request->url.port();
1112  doint = 1;
1113  }
1114  break;
1115 
1117  if (al->adapted_request) {
1118  sb = al->adapted_request->url.path();
1119  out = sb.c_str();
1120  quote = 1;
1121  }
1122  break;
1123 
1125  if (al->adapted_request) {
1126  sb.appendf("%u.%u",
1129  out = tmp;
1130  }
1131  break;
1132 
1134  outoff = al->http.clientRequestSz.messageTotal();
1135  dooff = 1;
1136  break;
1137 
1139  outoff = al->http.clientRequestSz.header;
1140  dooff =1;
1141  break;
1142 
1143  /*case LFT_REQUEST_SIZE_BODY: */
1144  /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
1145 
1147  outoff = al->http.clientReplySz.messageTotal();
1148  dooff = 1;
1149  break;
1150 
1151  case LFT_REPLY_HIGHOFFSET:
1152  outoff = al->cache.highOffset;
1153  dooff = 1;
1154  break;
1155 
1156  case LFT_REPLY_OBJECTSIZE:
1157  outoff = al->cache.objectSize;
1158  dooff = 1;
1159  break;
1160 
1162  outint = al->http.clientReplySz.header;
1163  doint = 1;
1164  break;
1165 
1166  /*case LFT_REPLY_SIZE_BODY: */
1167  /*case LFT_REPLY_SIZE_BODY_NO_TE: */
1168 
1171  doint = 1;
1172  break;
1173  /*case LFT_SERVER_IO_SIZE_TOTAL: */
1174 
1175  case LFT_TAG:
1176  if (al->request) {
1177  out = al->request->tag.termedBuf();
1178  quote = 1;
1179  }
1180  break;
1181 
1182  case LFT_EXT_LOG:
1183  if (al->request) {
1184  out = al->request->extacl_log.termedBuf();
1185  quote = 1;
1186  }
1187  break;
1188 
1189  case LFT_SEQUENCE_NUMBER:
1190  outoff = logSequenceNumber;
1191  dooff = 1;
1192  break;
1193 
1194 #if USE_OPENSSL
1195  case LFT_SSL_BUMP_MODE: {
1196  const Ssl::BumpMode mode = static_cast<Ssl::BumpMode>(al->ssl.bumpMode);
1197  // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
1198  out = Ssl::bumpMode(mode);
1199  }
1200  break;
1201 
1203  if (al->request) {
1205  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1206  if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) {
1207  sb = sslGetUserCertificatePEM(ssl);
1208  out = sb.c_str();
1209  }
1210  }
1211  }
1212  break;
1213 
1215  if (al->request) {
1217  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1218  if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) {
1219  sb = sslGetUserCertificatePEM(ssl);
1220  out = sb.c_str();
1221  }
1222  }
1223  }
1224  break;
1225 
1226  case LFT_EXT_ACL_USER_CERT:
1227  if (al->request) {
1229  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1230  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1231  out = sslGetUserAttribute(ssl, fmt->data.header.header);
1232  }
1233  }
1234  break;
1235 
1237  if (al->request) {
1239  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1240  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1241  out = sslGetCAAttribute(ssl, fmt->data.header.header);
1242  }
1243  }
1244  break;
1245 
1247  if (X509 *cert = al->cache.sslClientCert.get()) {
1248  if (X509_NAME *subject = X509_get_subject_name(cert)) {
1249  X509_NAME_oneline(subject, tmp, sizeof(tmp));
1250  out = tmp;
1251  }
1252  }
1253  break;
1254 
1256  if (X509 *cert = al->cache.sslClientCert.get()) {
1257  if (X509_NAME *issuer = X509_get_issuer_name(cert)) {
1258  X509_NAME_oneline(issuer, tmp, sizeof(tmp));
1259  out = tmp;
1260  }
1261  }
1262  break;
1263 
1264  case LFT_SSL_CLIENT_SNI:
1265  if (al->request && al->request->clientConnectionManager.valid()) {
1266  if (const ConnStateData *conn = al->request->clientConnectionManager.get()) {
1267  if (!conn->tlsClientSni().isEmpty()) {
1268  sb = conn->tlsClientSni();
1269  out = sb.c_str();
1270  }
1271  }
1272  }
1273  break;
1274 
1276  if (al->request && al->request->clientConnectionManager.valid()) {
1277  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1278  const char *separator = fmt->data.string ? fmt->data.string : ":";
1279  for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) {
1280  if (!sb.isEmpty())
1281  sb.append(separator);
1282  if (const char *errorName = Ssl::GetErrorName(sslError->element.code))
1283  sb.append(errorName);
1284  else
1285  sb.append(sslErrorName(sslError->element.code, tmp, sizeof(tmp)));
1286  if (sslError->element.depth >= 0)
1287  sb.appendf("@depth=%d", sslError->element.depth);
1288  }
1289  if (!sb.isEmpty())
1290  out = sb.c_str();
1291  }
1292  }
1293  break;
1294 
1298  if (al->request && al->request->clientConnectionManager.valid()) {
1299  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1300  if (X509 *serverCert = srvBump->serverCert.get()) {
1301  if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT)
1302  out = Ssl::GetX509UserAttribute(serverCert, "DN");
1303  else if (fmt->type == LFT_SSL_SERVER_CERT_ISSUER)
1304  out = Ssl::GetX509CAAttribute(serverCert, "DN");
1305  else {
1306  assert(fmt->type == LFT_SSL_SERVER_CERT_WHOLE);
1307  sb = Ssl::GetX509PEM(serverCert);
1308  out = sb.c_str();
1309  quote = 1;
1310  }
1311  }
1312  }
1313  }
1314  break;
1315 
1317  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1319  break;
1320 
1322  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1324  break;
1325 
1327  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1328  out = al->tcpClient->hasTlsNegotiations()->helloVersion();
1329  break;
1330 
1332  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1334  break;
1335 
1337  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1339  break;
1340 
1342  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1344  break;
1345 
1347  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1348  out = al->tcpClient->hasTlsNegotiations()->cipherName();
1349  break;
1350 
1352  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1353  out = al->hier.tcpServer->hasTlsNegotiations()->cipherName();
1354  break;
1355 #endif
1356 
1358  assert(LFT_REQUEST_URLGROUP_OLD_2X == 0); // should never happen.
1359 
1360  case LFT_NOTE:
1361  tmp[0] = fmt->data.header.separator;
1362  tmp[1] = '\0';
1363  if (fmt->data.header.header && *fmt->data.header.header) {
1364  const char *separator = tmp;
1365  static SBuf note;
1366 #if USE_ADAPTATION
1368  if (ah && ah->metaHeaders) {
1369  if (ah->metaHeaders->find(note, fmt->data.header.header, separator))
1370  sb.append(note);
1371  }
1372 #endif
1373  if (al->notes) {
1374  if (al->notes->find(note, fmt->data.header.header, separator)) {
1375  if (!sb.isEmpty())
1376  sb.append(separator);
1377  sb.append(note);
1378  }
1379  }
1380  out = sb.c_str();
1381  quote = 1;
1382  } else {
1383  // if no argument given use default "\r\n" as notes separator
1384  const char *separator = fmt->data.string ? tmp : "\r\n";
1385 #if USE_ADAPTATION
1387  if (ah && ah->metaHeaders && !ah->metaHeaders->empty())
1388  sb.append(ah->metaHeaders->toString(separator));
1389 #endif
1390  if (al->notes && !al->notes->empty())
1391  sb.append(al->notes->toString(separator));
1392 
1393  out = sb.c_str();
1394  quote = 1;
1395  }
1396  break;
1397 
1398  case LFT_CREDENTIALS:
1399 #if USE_AUTH
1400  if (al->request && al->request->auth_user_request)
1402 #endif
1403  break;
1404 
1405  case LFT_PERCENT:
1406  out = "%";
1407  break;
1408 
1409  case LFT_EXT_ACL_NAME:
1410  out = al->lastAclName;
1411  break;
1412 
1413  case LFT_EXT_ACL_DATA:
1414  if (!al->lastAclData.isEmpty())
1415  out = al->lastAclData.c_str();
1416  break;
1417  }
1418 
1419  if (dooff) {
1420  sb.appendf("%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff);
1421  out = sb.c_str();
1422 
1423  } else if (doint) {
1424  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
1425  out = sb.c_str();
1426  } else if (doMsec) {
1427  if (fmt->widthMax < 0) {
1428  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, tvToMsec(outtv));
1429  } else {
1430  int precision = fmt->widthMax;
1431  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)));
1432  }
1433  out = sb.c_str();
1434  } else if (doSec) {
1435  int precision = fmt->widthMax >=0 ? fmt->widthMax :3;
1436  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));
1437  out = sb.c_str();
1438  }
1439 
1440  if (out && *out) {
1441  if (quote || fmt->quote != LOG_QUOTE_NONE) {
1442  // Do not write to the tmp buffer because it may contain the to-be-quoted value.
1443  static char quotedOut[2 * sizeof(tmp)];
1444  static_assert(sizeof(quotedOut) > 0, "quotedOut has zero length");
1445  quotedOut[0] = '\0';
1446 
1447  char *newout = NULL;
1448  int newfree = 0;
1449 
1450  switch (fmt->quote) {
1451 
1452  case LOG_QUOTE_NONE:
1453  newout = rfc1738_escape_unescaped(out);
1454  break;
1455 
1456  case LOG_QUOTE_QUOTES: {
1457  size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
1458  if (out_len >= sizeof(tmp)) {
1459  newout = (char *)xmalloc(out_len);
1460  newfree = 1;
1461  } else
1462  newout = quotedOut;
1463  log_quoted_string(out, newout);
1464  }
1465  break;
1466 
1467  case LOG_QUOTE_MIMEBLOB:
1468  newout = QuoteMimeBlob(out);
1469  newfree = 1;
1470  break;
1471 
1472  case LOG_QUOTE_URL:
1473  newout = rfc1738_escape(out);
1474  break;
1475 
1476  case LOG_QUOTE_SHELL: {
1477  MemBuf mbq;
1478  mbq.init();
1479  strwordquote(&mbq, out);
1480  newout = mbq.content();
1481  mbq.stolen = 1;
1482  newfree = 1;
1483  }
1484  break;
1485 
1486  case LOG_QUOTE_RAW:
1487  break;
1488  }
1489 
1490  if (newout) {
1491  if (dofree)
1492  safe_free(out);
1493 
1494  out = newout;
1495 
1496  dofree = newfree;
1497  }
1498  }
1499 
1500  // enforce width limits if configured
1501  const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff && !doMsec && !doSec;
1502  if (haveMaxWidth || fmt->widthMin) {
1503  const int minWidth = fmt->widthMin >= 0 ?
1504  fmt->widthMin :0;
1505  const int maxWidth = haveMaxWidth ?
1506  fmt->widthMax : strlen(out);
1507 
1508  if (fmt->left)
1509  mb.appendf("%-*.*s", minWidth, maxWidth, out);
1510  else
1511  mb.appendf("%*.*s", minWidth, maxWidth, out);
1512  } else
1513  mb.append(out, strlen(out));
1514  } else {
1515  mb.append("-", 1);
1516  }
1517 
1518  if (fmt->space)
1519  mb.append(" ", 1);
1520 
1521  sb.clear();
1522 
1523  if (dofree)
1524  safe_free(out);
1525  }
1526 }
1527 
static char * sslErrorName(Security::ErrorCode err, char *buf, size_t size)
Definition: Format.cc:328
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:368
err_type errType
Definition: HttpRequest.h:153
#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:175
class AccessLogEntry::IcapLogEntry icap
#define HttpHeaderInitPos
Definition: HttpHeader.h:48
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:154
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:78
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:823
Token * next
Definition: Token.h:71
Comm::ConnectionPointer tcpServer
TCP/IP level details of the last peer/server connection.
HttpRequestMethod method
Definition: HttpRequest.h:106
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:341
#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:70
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:414
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:274
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:355
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:687
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:141
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
SBuf getByNameListMember(const char *name, const char *member, const char separator) const
Definition: HttpHeader.cc:957
String tag
Definition: HttpRequest.h:169
const char * errorPageName(int pageId)
error ID to string
Definition: errorpage.cc:540
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:107
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:99
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:222
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:151
const Ip::Address * FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:785
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:171
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:119
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:875
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