Format.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2018 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 "client_side.h"
12 #include "comm/Connection.h"
13 #include "err_detail_type.h"
14 #include "errorpage.h"
15 #include "fde.h"
16 #include "format/Format.h"
17 #include "format/Quoting.h"
18 #include "format/Token.h"
19 #include "fqdncache.h"
20 #include "http/Stream.h"
21 #include "HttpRequest.h"
22 #include "MemBuf.h"
23 #include "rfc1738.h"
24 #include "sbuf/StringConvert.h"
25 #include "security/CertError.h"
27 #include "SquidTime.h"
28 #include "Store.h"
29 #include "tools.h"
30 #if USE_OPENSSL
31 #include "ssl/ErrorDetail.h"
32 #include "ssl/ServerBump.h"
33 #endif
34 
36 #define strOrNull(s) ((s)==NULL||(s)[0]=='\0'?NULL:(s))
37 
38 const SBuf Format::Dash("-");
39 
40 Format::Format::Format(const char *n) :
41  format(NULL),
42  next(NULL)
43 {
44  name = xstrdup(n);
45 }
46 
48 {
49  // erase the list without consuming stack space
50  while (next) {
51  // unlink the next entry for deletion
52  Format *temp = next;
53  next = temp->next;
54  temp->next = NULL;
55  delete temp;
56  }
57 
58  // remove locals
59  xfree(name);
60  delete format;
61 }
62 
63 bool
64 Format::Format::parse(const char *def)
65 {
66  const char *cur, *eos;
67  Token *new_lt, *last_lt;
69 
70  debugs(46, 2, HERE << "got definition '" << def << "'");
71 
72  if (format) {
73  debugs(46, DBG_IMPORTANT, "WARNING: existing format for '" << name << " " << def << "'");
74  return false;
75  }
76 
77  /* very inefficent parser, but who cares, this needs to be simple */
78  /* First off, let's tokenize, we'll optimize in a second pass.
79  * A token can either be a %-prefixed sequence (usually a dynamic
80  * token but it can be an escaped sequence), or a string. */
81  cur = def;
82  eos = def + strlen(def);
83  format = new_lt = last_lt = new Token;
84  cur += new_lt->parse(cur, &quote);
85 
86  while (cur < eos) {
87  new_lt = new Token;
88  last_lt->next = new_lt;
89  last_lt = new_lt;
90  cur += new_lt->parse(cur, &quote);
91  }
92 
93  return true;
94 }
95 
96 void
97 Format::Format::dump(StoreEntry * entry, const char *directiveName, bool eol) const
98 {
99  debugs(46, 4, HERE);
100 
101  // loop rather than recursing to conserve stack space.
102  for (const Format *fmt = this; fmt; fmt = fmt->next) {
103  debugs(46, 3, HERE << "Dumping format definition for " << fmt->name);
104  if (directiveName)
105  storeAppendPrintf(entry, "%s %s ", directiveName, fmt->name);
106 
107  for (Token *t = fmt->format; t; t = t->next) {
108  if (t->type == LFT_STRING)
109  storeAppendPrintf(entry, "%s", t->data.string);
110  else {
111  char argbuf[256];
112  char *arg = NULL;
113  ByteCode_t type = t->type;
114 
115  switch (type) {
116  /* special cases */
117 
118  case LFT_STRING:
119  break;
120 #if USE_ADAPTATION
122 #endif
123 #if ICAP_CLIENT
126 #endif
130 
131  if (t->data.header.separator != ',')
132  snprintf(argbuf, sizeof(argbuf), "%s:%c%s", t->data.header.header, t->data.header.separator, t->data.header.element);
133  else
134  snprintf(argbuf, sizeof(argbuf), "%s:%s", t->data.header.header, t->data.header.element);
135 
136  arg = argbuf;
137 
138  switch (type) {
140  type = LFT_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
141  break;
143  type = LFT_ADAPTED_REQUEST_HEADER_ELEM; // XXX: remove _ELEM?
144  break;
146  type = LFT_REPLY_HEADER_ELEM; // XXX: remove _ELEM?
147  break;
148 #if USE_ADAPTATION
151  break;
152 #endif
153 #if ICAP_CLIENT
155  type = LFT_ICAP_REQ_HEADER;
156  break;
158  type = LFT_ICAP_REP_HEADER;
159  break;
160 #endif
161  default:
162  break;
163  }
164 
165  break;
166 
170 
171 #if USE_ADAPTATION
173 #endif
174 #if ICAP_CLIENT
177 #endif
178 
179  switch (type) {
181  type = LFT_REQUEST_HEADER;
182  break;
185  break;
187  type = LFT_REPLY_HEADER;
188  break;
189 #if USE_ADAPTATION
192  break;
193 #endif
194 #if ICAP_CLIENT
196  type = LFT_ICAP_REQ_HEADER;
197  break;
199  type = LFT_ICAP_REP_HEADER;
200  break;
201 #endif
202  default:
203  break;
204  }
205 
206  break;
207 
208  default:
209  if (t->data.string)
210  arg = t->data.string;
211 
212  break;
213  }
214 
215  entry->append("%", 1);
216 
217  switch (t->quote) {
218 
219  case LOG_QUOTE_QUOTES:
220  entry->append("\"", 1);
221  break;
222 
223  case LOG_QUOTE_MIMEBLOB:
224  entry->append("[", 1);
225  break;
226 
227  case LOG_QUOTE_URL:
228  entry->append("#", 1);
229  break;
230 
231  case LOG_QUOTE_RAW:
232  entry->append("'", 1);
233  break;
234 
235  case LOG_QUOTE_SHELL:
236  entry->append("/", 1);
237  break;
238 
239  case LOG_QUOTE_NONE:
240  break;
241  }
242 
243  if (t->left)
244  entry->append("-", 1);
245 
246  if (t->zero)
247  entry->append("0", 1);
248 
249  if (t->widthMin >= 0)
250  storeAppendPrintf(entry, "%d", t->widthMin);
251 
252  if (t->widthMax >= 0)
253  storeAppendPrintf(entry, ".%d", t->widthMax);
254 
255  if (arg)
256  storeAppendPrintf(entry, "{%s}", arg);
257 
258  storeAppendPrintf(entry, "%s", t->label);
259 
260  if (t->space)
261  entry->append(" ", 1);
262  }
263  }
264 
265  if (eol)
266  entry->append("\n", 1);
267  }
268 
269 }
270 
271 static void
272 log_quoted_string(const char *str, char *out)
273 {
274  char *p = out;
275 
276  while (*str) {
277  int l = strcspn(str, "\"\\\r\n\t");
278  memcpy(p, str, l);
279  str += l;
280  p += l;
281 
282  switch (*str) {
283 
284  case '\0':
285  break;
286 
287  case '\r':
288  *p = '\\';
289  ++p;
290  *p = 'r';
291  ++p;
292  ++str;
293  break;
294 
295  case '\n':
296  *p = '\\';
297  ++p;
298  *p = 'n';
299  ++p;
300  ++str;
301  break;
302 
303  case '\t':
304  *p = '\\';
305  ++p;
306  *p = 't';
307  ++p;
308  ++str;
309  break;
310 
311  default:
312  *p = '\\';
313  ++p;
314  *p = *str;
315  ++p;
316  ++str;
317  break;
318  }
319  }
320 
321  *p = '\0';
322 }
323 
324 #if USE_OPENSSL
325 static char *
327 {
328  snprintf(buf, size, "SSL_ERR=%d", err);
329  return buf;
330 }
331 #endif
332 
338 static const Http::Message *
340 {
341  const Http::Message *msg = al->reply;
342 #if ICAP_CLIENT
343  // al->icap.reqMethod is methodNone in access.log context
344  if (!msg && al->icap.reqMethod == Adaptation::methodReqmod)
345  msg = al->adapted_request;
346 #endif
347  return msg;
348 }
349 
352 static const Http::Message *
354 {
355 #if ICAP_CLIENT
356  // al->icap.reqMethod is methodNone in access.log context
357  if (al->icap.reqMethod == Adaptation::methodRespmod) {
358  // XXX: for now AccessLogEntry lacks virgin response headers
359  return nullptr;
360  }
361 #endif
362  return al->request;
363 }
364 
365 void
366 Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logSequenceNumber) const
367 {
368  static char tmp[1024];
369  SBuf sb;
370 
371  for (Token *fmt = format; fmt; fmt = fmt->next) { /* for each token */
372  const char *out = nullptr;
373  int quote = 0;
374  long int outint = 0;
375  int doint = 0;
376  int dofree = 0;
377  int64_t outoff = 0;
378  int dooff = 0;
379  struct timeval outtv = {0, 0};
380  int doMsec = 0;
381  int doSec = 0;
382 
383  switch (fmt->type) {
384 
385  case LFT_NONE:
386  out = "";
387  break;
388 
389  case LFT_STRING:
390  out = fmt->data.string;
391  break;
392 
394  al->getLogClientIp(tmp, sizeof(tmp));
395  out = tmp;
396  break;
397 
398  case LFT_CLIENT_FQDN:
399  if (al->cache.caddr.isAnyAddr()) // e.g., ICAP OPTIONS lack client
400  out = "-";
401  else
403 
404  if (!out) {
405  out = al->cache.caddr.toStr(tmp, sizeof(tmp));
406  }
407  break;
408 
409  case LFT_CLIENT_PORT:
410  if (al->request) {
411  outint = al->request->client_addr.port();
412  doint = 1;
413  } else if (al->tcpClient) {
414  outint = al->tcpClient->remote.port();
415  doint = 1;
416  }
417  break;
418 
419  case LFT_CLIENT_EUI:
420 #if USE_SQUID_EUI
421  // TODO make the ACL checklist have a direct link to any TCP details.
422  if (al->request && al->request->clientConnectionManager.valid() &&
425  if (conn->remote.isIPv4())
426  conn->remoteEui48.encode(tmp, sizeof(tmp));
427  else
428  conn->remoteEui64.encode(tmp, sizeof(tmp));
429  out = tmp;
430  }
431 #endif
432  break;
433 
435 #if USE_SQUID_EUI
436  if (al->request && al->request->clientConnectionManager.valid() &&
440  out = tmp;
441  }
442 #endif
443  break;
444 
446 #if USE_SQUID_EUI
447  if (al->request && al->request->clientConnectionManager.valid() &&
451  out = tmp;
452  }
453 #endif
454  break;
455 
457  if (al->hier.tcpServer)
458  out = al->hier.tcpServer->remote.toStr(tmp, sizeof(tmp));
459  break;
460 
462  out = al->hier.host;
463  break;
464 
465  case LFT_SERVER_PORT:
466  if (al->hier.tcpServer) {
467  outint = al->hier.tcpServer->remote.port();
468  doint = 1;
469  }
470  break;
471 
473  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw()))
474  out = addr->toStr(tmp, sizeof(tmp));
475  break;
476 
477  case LFT_CLIENT_LOCAL_IP:
478  if (al->tcpClient)
479  out = al->tcpClient->local.toStr(tmp, sizeof(tmp));
480  break;
481 
483  if (al->tcpClient) {
484  sb.appendf("0x%x", static_cast<uint32_t>(al->tcpClient->tos));
485  out = sb.c_str();
486  }
487  break;
488 
490  if (al->tcpClient) {
491  sb.appendf("0x%x", al->tcpClient->nfmark);
492  out = sb.c_str();
493  }
494  break;
495 
497  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw())) {
498  outint = addr->port();
499  doint = 1;
500  }
501  break;
502 
504  if (al->tcpClient) {
505  outint = al->tcpClient->local.port();
506  doint = 1;
507  }
508  break;
509 
511  case LFT_SERVER_LOCAL_IP:
512  if (al->hier.tcpServer)
513  out = al->hier.tcpServer->local.toStr(tmp, sizeof(tmp));
514  break;
515 
517  if (al->hier.tcpServer) {
518  outint = al->hier.tcpServer->local.port();
519  doint = 1;
520  }
521  break;
522 
524  if (al->hier.tcpServer) {
525  sb.appendf("0x%x", static_cast<uint32_t>(al->hier.tcpServer->tos));
526  out = sb.c_str();
527  }
528  break;
529 
531  if (al->hier.tcpServer) {
532  sb.appendf("0x%x", al->hier.tcpServer->nfmark);
533  out = sb.c_str();
534  }
535  break;
536 
538  // some platforms store time in 32-bit, some 64-bit...
539  outoff = static_cast<int64_t>(current_time.tv_sec);
540  dooff = 1;
541  break;
542 
543  case LFT_TIME_SUBSECOND:
544  outint = current_time.tv_usec / fmt->divisor;
545  doint = 1;
546  break;
547 
548  case LFT_TIME_LOCALTIME:
549  case LFT_TIME_GMT: {
550  const char *spec;
551  struct tm *t;
552  spec = fmt->data.string;
553 
554  if (fmt->type == LFT_TIME_LOCALTIME) {
555  if (!spec)
556  spec = "%d/%b/%Y:%H:%M:%S %z";
557  t = localtime(&squid_curtime);
558  } else {
559  if (!spec)
560  spec = "%d/%b/%Y:%H:%M:%S";
561 
562  t = gmtime(&squid_curtime);
563  }
564 
565  strftime(tmp, sizeof(tmp), spec, t);
566  out = tmp;
567  }
568  break;
569 
570  case LFT_TIME_START:
571  outtv = al->cache.start_time;
572  doSec = 1;
573  break;
574 
576  outtv = al->cache.trTime;
577  doMsec = 1;
578  break;
579 
581  struct timeval peerResponseTime;
582  if (al->hier.peerResponseTime(peerResponseTime)) {
583  outtv = peerResponseTime;
584  doMsec = 1;
585  }
586  break;
587 
589  struct timeval totalResponseTime;
590  if (al->hier.totalResponseTime(totalResponseTime)) {
591  outtv = totalResponseTime;
592  doMsec = 1;
593  }
594  }
595  break;
596 
597  case LFT_DNS_WAIT_TIME:
598  if (al->request && al->request->dnsWait >= 0) {
599  // TODO: microsecond precision for dns wait time.
600  // Convert miliseconds to timeval struct:
601  outtv.tv_sec = al->request->dnsWait / 1000;
602  outtv.tv_usec = (al->request->dnsWait % 1000) * 1000;
603  doMsec = 1;
604  }
605  break;
606 
607  case LFT_REQUEST_HEADER:
608  if (const Http::Message *msg = actualRequestHeader(al)) {
609  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
610  out = sb.c_str();
611  quote = 1;
612  }
613  break;
614 
616  if (al->adapted_request) {
617  sb = StringToSBuf(al->adapted_request->header.getByName(fmt->data.header.header));
618  out = sb.c_str();
619  quote = 1;
620  }
621  break;
622 
623  case LFT_REPLY_HEADER:
624  if (const Http::Message *msg = actualReplyHeader(al)) {
625  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
626  out = sb.c_str();
627  quote = 1;
628  }
629  break;
630 
631 #if USE_ADAPTATION
633  if (al->request) {
635  if (ah) {
636  ah->sumLogString(fmt->data.string, sb);
637  out = sb.c_str();
638  }
639  }
640  break;
641 
643  if (al->request) {
645  if (ah) {
646  ah->allLogString(fmt->data.string, sb);
647  out = sb.c_str();
648  }
649  }
650  break;
651 
653  if (al->request) {
655  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
656  sb = StringToSBuf(ah->allMeta.getByName(fmt->data.header.header));
657  out = sb.c_str();
658  quote = 1;
659  }
660  }
661  break;
662 
664  if (al->request) {
666  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
667  sb = StringToSBuf(ah->allMeta.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
668  out = sb.c_str();
669  quote = 1;
670  }
671  }
672  break;
673 
675  out = al->adapt.last_meta;
676  quote = 1;
677  break;
678 #endif
679 
680 #if ICAP_CLIENT
681  case LFT_ICAP_ADDR:
682  out = al->icap.hostAddr.toStr(tmp, sizeof(tmp));
683  break;
684 
685  case LFT_ICAP_SERV_NAME:
686  out = al->icap.serviceName.termedBuf();
687  break;
688 
690  out = al->icap.reqUri.termedBuf();
691  break;
692 
695  break;
696 
697  case LFT_ICAP_BYTES_SENT:
698  outoff = al->icap.bytesSent;
699  dooff = 1;
700  break;
701 
702  case LFT_ICAP_BYTES_READ:
703  outoff = al->icap.bytesRead;
704  dooff = 1;
705  break;
706 
708  if (al->icap.bodyBytesRead >= 0) {
709  outoff = al->icap.bodyBytesRead;
710  dooff = 1;
711  }
712  // else if icap.bodyBytesRead < 0, we do not have any http data,
713  // so just print a "-" (204 responses etc)
714  break;
715 
716  case LFT_ICAP_REQ_HEADER:
717  if (al->icap.request) {
718  sb = StringToSBuf(al->icap.request->header.getByName(fmt->data.header.header));
719  out = sb.c_str();
720  quote = 1;
721  }
722  break;
723 
725  if (al->icap.request) {
726  sb = StringToSBuf(al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
727  out = sb.c_str();
728  quote = 1;
729  }
730  break;
731 
733  if (al->icap.request) {
735  while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
736  sb.append(e->name);
737  sb.append(": ");
738  sb.append(StringToSBuf(e->value));
739  sb.append("\r\n");
740  }
741  out = sb.c_str();
742  quote = 1;
743  }
744  break;
745 
746  case LFT_ICAP_REP_HEADER:
747  if (al->icap.reply) {
748  sb = StringToSBuf(al->icap.reply->header.getByName(fmt->data.header.header));
749  out = sb.c_str();
750  quote = 1;
751  }
752  break;
753 
755  if (al->icap.reply) {
756  sb = StringToSBuf(al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
757  out = sb.c_str();
758  quote = 1;
759  }
760  break;
761 
763  if (al->icap.reply) {
765  while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
766  sb.append(e->name);
767  sb.append(": ");
768  sb.append(StringToSBuf(e->value));
769  sb.append("\r\n");
770  }
771  out = sb.c_str();
772  quote = 1;
773  }
774  break;
775 
777  outtv = al->icap.trTime;
778  doMsec = 1;
779  break;
780 
781  case LFT_ICAP_IO_TIME:
782  outtv = al->icap.ioTime;
783  doMsec = 1;
784  break;
785 
787  outint = al->icap.resStatus;
788  doint = 1;
789  break;
790 
791  case LFT_ICAP_OUTCOME:
792  out = al->icap.outcome;
793  break;
794 
795  case LFT_ICAP_TOTAL_TIME:
796  outtv = al->icap.processingTime;
797  doMsec = 1;
798  break;
799 #endif
801  if (const Http::Message *msg = actualRequestHeader(al)) {
802  sb = StringToSBuf(msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
803  out = sb.c_str();
804  quote = 1;
805  }
806  break;
807 
809  if (al->adapted_request) {
810  sb = StringToSBuf(al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
811  out = sb.c_str();
812  quote = 1;
813  }
814  break;
815 
817  if (const Http::Message *msg = actualReplyHeader(al)) {
818  sb = StringToSBuf(msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
819  out = sb.c_str();
820  quote = 1;
821  }
822  break;
823 
825 #if ICAP_CLIENT
827  // XXX: since AccessLogEntry::Headers lacks virgin response
828  // headers, do nothing for now
829  out = nullptr;
830  } else
831 #endif
832  {
833  out = al->headers.request;
834  quote = 1;
835  }
836  break;
837 
839  out = al->headers.adapted_request;
840  quote = 1;
841  break;
842 
844  out = al->headers.reply;
845 #if ICAP_CLIENT
846  if (!out && al->icap.reqMethod == Adaptation::methodReqmod)
847  out = al->headers.adapted_request;
848 #endif
849  quote = 1;
850  break;
851 
852  case LFT_USER_NAME:
853 #if USE_AUTH
854  if (al->request && al->request->auth_user_request)
856 #endif
857  if (!out && al->request && al->request->extacl_user.size()) {
858  if (const char *t = al->request->extacl_user.termedBuf())
859  out = t;
860  }
861  if (!out)
862  out = strOrNull(al->getExtUser());
863 #if USE_OPENSSL
864  if (!out)
865  out = strOrNull(al->cache.ssluser);
866 #endif
867  if (!out)
868  out = strOrNull(al->getClientIdent());
869  break;
870 
871  case LFT_USER_LOGIN:
872 #if USE_AUTH
873  if (al->request && al->request->auth_user_request)
875 #endif
876  break;
877 
878  case LFT_USER_IDENT:
879  out = strOrNull(al->getClientIdent());
880  break;
881 
882  case LFT_USER_EXTERNAL:
883  out = strOrNull(al->getExtUser());
884  break;
885 
886  /* case LFT_USER_REALM: */
887  /* case LFT_USER_SCHEME: */
888 
889  // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
890  // but compiler complains if ommited
893  outint = al->http.code;
894  doint = 1;
895  break;
896 
898  if (al->hier.peer_reply_status != Http::scNone) {
899  outint = al->hier.peer_reply_status;
900  doint = 1;
901  }
902  break;
903  /* case LFT_HTTP_STATUS:
904  * out = statusline->text;
905  * quote = 1;
906  * break;
907  */
909  if (al->hier.bodyBytesRead >= 0) {
910  outoff = al->hier.bodyBytesRead;
911  dooff = 1;
912  }
913  // else if hier.bodyBytesRead < 0 we did not have any data exchange with
914  // a peer server so just print a "-" (eg requests served from cache,
915  // or internal error messages).
916  break;
917 
918  case LFT_SQUID_STATUS:
919  out = al->cache.code.c_str();
920  break;
921 
922  case LFT_SQUID_ERROR:
923  if (al->request && al->request->errType != ERR_NONE)
924  out = errorPageName(al->request->errType);
925  break;
926 
928 #if USE_OPENSSL
929  if (al->request && al->request->errType == ERR_SECURE_CONNECT_FAIL) {
930  out = Ssl::GetErrorName(al->request->errDetail);
931  if (!out)
932  out = sslErrorName(al->request->errDetail, tmp, sizeof(tmp));
933  } else
934 #endif
935  if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
937  out = errorDetailName(al->request->errDetail);
938  else {
940  sb.appendf("%s=0x%X",
941  errorDetailName(al->request->errDetail), (uint32_t) al->request->errDetail);
942  else
943  sb.appendf("%s=%d",
945  out = sb.c_str();
946  }
947  }
948  break;
949 
950  case LFT_SQUID_HIERARCHY:
951  if (al->hier.ping.timedout)
952  mb.append("TIMEOUT_", 8);
953  out = hier_code_str[al->hier.code];
954  break;
955 
956  case LFT_MIME_TYPE:
957  out = al->http.content_type;
958  break;
959 
961  if (al->request) {
962  sb = al->request->method.image();
963  out = sb.c_str();
964  quote = 1;
965  }
966  break;
967 
968  case LFT_CLIENT_REQ_URI:
969  // original client URI
970  if (al->request) {
971  sb = al->request->effectiveRequestUri();
972  out = sb.c_str();
973  quote = 1;
974  }
975  break;
976 
978  if (al->request) {
979  sb = al->request->url.getScheme().image();
980  out = sb.c_str();
981  quote = 1;
982  }
983  break;
984 
986  if (al->request) {
987  out = al->request->url.host();
988  quote = 1;
989  }
990  break;
991 
993  if (al->request) {
994  outint = al->request->url.port();
995  doint = 1;
996  }
997  break;
998 
1001  if (al->request) {
1002  sb = al->request->url.path();
1003  out = sb.c_str();
1004  quote = 1;
1005  }
1006  break;
1007 
1009  if (al->request) {
1010  sb.appendf("%u.%u", al->request->http_ver.major, al->request->http_ver.minor);
1011  out = sb.c_str();
1012  }
1013  break;
1014 
1015  case LFT_REQUEST_METHOD:
1016  sb = al->getLogMethod();
1017  out = sb.c_str();
1018  quote = 1;
1019  break;
1020 
1021  case LFT_REQUEST_URI:
1022  if (!al->url.isEmpty()) {
1023  sb = al->url;
1024  out = sb.c_str();
1025  }
1026  break;
1027 
1029  case LFT_REQUEST_VERSION:
1030  sb.appendf("%u.%u", al->http.version.major, al->http.version.minor);
1031  out = sb.c_str();
1032  break;
1033 
1034  case LFT_SERVER_REQ_METHOD:
1035  if (al->adapted_request) {
1036  sb = al->adapted_request->method.image();
1037  out = sb.c_str();
1038  quote = 1;
1039  }
1040  break;
1041 
1042  case LFT_SERVER_REQ_URI:
1043  // adapted request URI sent to server/peer
1044  if (al->adapted_request) {
1046  out = sb.c_str();
1047  quote = 1;
1048  }
1049  break;
1050 
1052  if (al->adapted_request) {
1053  sb = al->adapted_request->url.getScheme().image();
1054  out = sb.c_str();
1055  quote = 1;
1056  }
1057  break;
1058 
1060  if (al->adapted_request) {
1061  out = al->adapted_request->url.host();
1062  quote = 1;
1063  }
1064  break;
1065 
1067  if (al->adapted_request) {
1068  outint = al->adapted_request->url.port();
1069  doint = 1;
1070  }
1071  break;
1072 
1074  if (al->adapted_request) {
1075  sb = al->adapted_request->url.path();
1076  out = sb.c_str();
1077  quote = 1;
1078  }
1079  break;
1080 
1082  if (al->adapted_request) {
1083  sb.appendf("%u.%u",
1086  out = tmp;
1087  }
1088  break;
1089 
1091  outoff = al->http.clientRequestSz.messageTotal();
1092  dooff = 1;
1093  break;
1094 
1096  outoff = al->http.clientRequestSz.header;
1097  dooff =1;
1098  break;
1099 
1100  /*case LFT_REQUEST_SIZE_BODY: */
1101  /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
1102 
1104  outoff = al->http.clientReplySz.messageTotal();
1105  dooff = 1;
1106  break;
1107 
1108  case LFT_REPLY_HIGHOFFSET:
1109  outoff = al->cache.highOffset;
1110  dooff = 1;
1111  break;
1112 
1113  case LFT_REPLY_OBJECTSIZE:
1114  outoff = al->cache.objectSize;
1115  dooff = 1;
1116  break;
1117 
1119  outint = al->http.clientReplySz.header;
1120  doint = 1;
1121  break;
1122 
1123  /*case LFT_REPLY_SIZE_BODY: */
1124  /*case LFT_REPLY_SIZE_BODY_NO_TE: */
1125 
1128  doint = 1;
1129  break;
1130  /*case LFT_SERVER_IO_SIZE_TOTAL: */
1131 
1132  case LFT_TAG:
1133  if (al->request) {
1134  out = al->request->tag.termedBuf();
1135  quote = 1;
1136  }
1137  break;
1138 
1139  case LFT_EXT_LOG:
1140  if (al->request) {
1141  out = al->request->extacl_log.termedBuf();
1142  quote = 1;
1143  }
1144  break;
1145 
1146  case LFT_SEQUENCE_NUMBER:
1147  outoff = logSequenceNumber;
1148  dooff = 1;
1149  break;
1150 
1151 #if USE_OPENSSL
1152  case LFT_SSL_BUMP_MODE: {
1153  const Ssl::BumpMode mode = static_cast<Ssl::BumpMode>(al->ssl.bumpMode);
1154  // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
1155  out = Ssl::bumpMode(mode);
1156  }
1157  break;
1158 
1160  if (al->request) {
1162  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1163  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1164  out = sslGetUserCertificatePEM(ssl);
1165  }
1166  }
1167  break;
1168 
1170  if (al->request) {
1172  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1173  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1174  out = sslGetUserCertificatePEM(ssl);
1175  }
1176  }
1177  break;
1178 
1179  case LFT_EXT_ACL_USER_CERT:
1180  if (al->request) {
1182  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1183  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1184  out = sslGetUserAttribute(ssl, format->data.header.header);
1185  }
1186  }
1187  break;
1188 
1190  if (al->request) {
1192  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1193  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1194  out = sslGetCAAttribute(ssl, format->data.header.header);
1195  }
1196  }
1197  break;
1198 
1200  if (X509 *cert = al->cache.sslClientCert.get()) {
1201  if (X509_NAME *subject = X509_get_subject_name(cert)) {
1202  X509_NAME_oneline(subject, tmp, sizeof(tmp));
1203  out = tmp;
1204  }
1205  }
1206  break;
1207 
1209  if (X509 *cert = al->cache.sslClientCert.get()) {
1210  if (X509_NAME *issuer = X509_get_issuer_name(cert)) {
1211  X509_NAME_oneline(issuer, tmp, sizeof(tmp));
1212  out = tmp;
1213  }
1214  }
1215  break;
1216 
1217  case LFT_SSL_CLIENT_SNI:
1218  if (al->request && al->request->clientConnectionManager.valid()) {
1219  if (const ConnStateData *conn = al->request->clientConnectionManager.get()) {
1220  if (!conn->tlsClientSni().isEmpty()) {
1221  sb = conn->tlsClientSni();
1222  out = sb.c_str();
1223  }
1224  }
1225  }
1226  break;
1227 
1229  if (al->request && al->request->clientConnectionManager.valid()) {
1230  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1231  const char *separator = fmt->data.string ? fmt->data.string : ":";
1232  for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) {
1233  if (!sb.isEmpty())
1234  sb.append(separator);
1235  if (const char *errorName = Ssl::GetErrorName(sslError->element.code))
1236  sb.append(errorName);
1237  else
1238  sb.append(sslErrorName(sslError->element.code, tmp, sizeof(tmp)));
1239  if (sslError->element.depth >= 0)
1240  sb.appendf("@depth=%d", sslError->element.depth);
1241  }
1242  if (!sb.isEmpty())
1243  out = sb.c_str();
1244  }
1245  }
1246  break;
1247 
1250  if (al->request && al->request->clientConnectionManager.valid()) {
1251  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1252  if (X509 *serverCert = srvBump->serverCert.get()) {
1253  if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT)
1254  out = Ssl::GetX509UserAttribute(serverCert, "DN");
1255  else
1256  out = Ssl::GetX509CAAttribute(serverCert, "DN");
1257  }
1258  }
1259  }
1260  break;
1261 
1263  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1265  break;
1266 
1268  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1270  break;
1271 
1273  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1274  out = al->tcpClient->hasTlsNegotiations()->helloVersion();
1275  break;
1276 
1278  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1280  break;
1281 
1283  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1285  break;
1286 
1288  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1290  break;
1291 
1293  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1294  out = al->tcpClient->hasTlsNegotiations()->cipherName();
1295  break;
1296 
1298  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1299  out = al->hier.tcpServer->hasTlsNegotiations()->cipherName();
1300  break;
1301 #endif
1302 
1304  assert(LFT_REQUEST_URLGROUP_OLD_2X == 0); // should never happen.
1305 
1306  case LFT_NOTE:
1307  tmp[0] = fmt->data.header.separator;
1308  tmp[1] = '\0';
1309  if (fmt->data.header.header && *fmt->data.header.header) {
1310  const char *separator = tmp;
1311  static SBuf note;
1312 #if USE_ADAPTATION
1314  if (ah && ah->metaHeaders) {
1315  if (ah->metaHeaders->find(note, fmt->data.header.header, separator))
1316  sb.append(note);
1317  }
1318 #endif
1319  if (al->notes) {
1320  if (al->notes->find(note, fmt->data.header.header, separator)) {
1321  if (!sb.isEmpty())
1322  sb.append(separator);
1323  sb.append(note);
1324  }
1325  }
1326  out = sb.c_str();
1327  quote = 1;
1328  } else {
1329  // if no argument given use default "\r\n" as notes separator
1330  const char *separator = fmt->data.string ? tmp : "\r\n";
1331 #if USE_ADAPTATION
1333  if (ah && ah->metaHeaders && !ah->metaHeaders->empty())
1334  sb.append(ah->metaHeaders->toString(separator));
1335 #endif
1336  if (al->notes && !al->notes->empty())
1337  sb.append(al->notes->toString(separator));
1338 
1339  out = sb.c_str();
1340  quote = 1;
1341  }
1342  break;
1343 
1344  case LFT_CREDENTIALS:
1345 #if USE_AUTH
1346  if (al->request && al->request->auth_user_request)
1348 #endif
1349  break;
1350 
1351  case LFT_PERCENT:
1352  out = "%";
1353  break;
1354 
1355  case LFT_EXT_ACL_NAME:
1356  out = al->lastAclName;
1357  break;
1358 
1359  case LFT_EXT_ACL_DATA:
1360  if (!al->lastAclData.isEmpty())
1361  out = al->lastAclData.c_str();
1362  break;
1363  }
1364 
1365  if (dooff) {
1366  sb.appendf("%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff);
1367  out = sb.c_str();
1368 
1369  } else if (doint) {
1370  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
1371  out = sb.c_str();
1372  } else if (doMsec) {
1373  if (fmt->widthMax < 0) {
1374  sb.appendf("%0*ld", fmt->widthMin, tvToMsec(outtv));
1375  } else {
1376  int precision = fmt->widthMax;
1377  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)));
1378  }
1379  out = sb.c_str();
1380  } else if (doSec) {
1381  int precision = fmt->widthMax >=0 ? fmt->widthMax :3;
1382  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));
1383  out = sb.c_str();
1384  }
1385 
1386  if (out && *out) {
1387  if (quote || fmt->quote != LOG_QUOTE_NONE) {
1388  // Do not write to the tmp buffer because it may contain the to-be-quoted value.
1389  static char quotedOut[2 * sizeof(tmp)];
1390  static_assert(sizeof(quotedOut) > 0, "quotedOut has zero length");
1391  quotedOut[0] = '\0';
1392 
1393  char *newout = NULL;
1394  int newfree = 0;
1395 
1396  switch (fmt->quote) {
1397 
1398  case LOG_QUOTE_NONE:
1399  newout = rfc1738_escape_unescaped(out);
1400  break;
1401 
1402  case LOG_QUOTE_QUOTES: {
1403  size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
1404  if (out_len >= sizeof(tmp)) {
1405  newout = (char *)xmalloc(out_len);
1406  newfree = 1;
1407  } else
1408  newout = quotedOut;
1409  log_quoted_string(out, newout);
1410  }
1411  break;
1412 
1413  case LOG_QUOTE_MIMEBLOB:
1414  newout = QuoteMimeBlob(out);
1415  newfree = 1;
1416  break;
1417 
1418  case LOG_QUOTE_URL:
1419  newout = rfc1738_escape(out);
1420  break;
1421 
1422  case LOG_QUOTE_SHELL: {
1423  MemBuf mbq;
1424  mbq.init();
1425  strwordquote(&mbq, out);
1426  newout = mbq.content();
1427  mbq.stolen = 1;
1428  newfree = 1;
1429  }
1430  break;
1431 
1432  case LOG_QUOTE_RAW:
1433  break;
1434  }
1435 
1436  if (newout) {
1437  if (dofree)
1438  safe_free(out);
1439 
1440  out = newout;
1441 
1442  dofree = newfree;
1443  }
1444  }
1445 
1446  // enforce width limits if configured
1447  const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff && !doMsec && !doSec;
1448  if (haveMaxWidth || fmt->widthMin) {
1449  const int minWidth = fmt->widthMin >= 0 ?
1450  fmt->widthMin :0;
1451  const int maxWidth = haveMaxWidth ?
1452  fmt->widthMax : strlen(out);
1453 
1454  if (fmt->left)
1455  mb.appendf("%-*.*s", minWidth, maxWidth, out);
1456  else
1457  mb.appendf("%*.*s", minWidth, maxWidth, out);
1458  } else
1459  mb.append(out, strlen(out));
1460  } else {
1461  mb.append("-", 1);
1462  }
1463 
1464  if (fmt->space)
1465  mb.append(" ", 1);
1466 
1467  sb.clear();
1468 
1469  if (dofree)
1470  safe_free(out);
1471  }
1472 }
1473 
static char * sslErrorName(Security::ErrorCode err, char *buf, size_t size)
Definition: Format.cc:326
GETX509ATTRIBUTE GetX509UserAttribute
Definition: support.h:116
err_type errType
Definition: HttpRequest.h:149
#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
bool encode(char *buf, const int len) const
Definition: Eui64.cc:34
#define assert(EX)
Definition: assert.h:17
SBuf & appendf(const char *fmt,...)
Definition: SBuf.cc:239
int timedout
Definition: PingData.h:25
String extacl_log
Definition: HttpRequest.h:171
class AccessLogEntry::IcapLogEntry icap
#define HttpHeaderInitPos
Definition: HttpHeader.h:48
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:216
const char * supportedVersion() const
NotePairs::Pointer notes
int errDetail
errType-specific detail about the transaction error
Definition: HttpRequest.h:150
nfmark_t nfmark
Definition: Connection.h:152
const char * GetErrorName(Security::ErrorCode value)
The string representation of the TLS error "value".
Definition: ErrorDetail.cc:392
int type
Definition: errorpage.cc:78
Format(const char *name)
Definition: Format.cc:40
void path(const char *p)
Definition: Uri.h:83
Definition: SBuf.h:86
virtual void append(char const *, int)
Appends a c-string to existing packed data.
Definition: store.cc:840
Token * next
Definition: Token.h:67
SBuf image() const
Definition: UriScheme.h:50
Comm::ConnectionPointer tcpServer
TCP/IP level details of the last peer/server connection.
void getLogClientIp(char *buf, size_t bufsz) const
HttpRequestMethod method
Definition: HttpRequest.h:102
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
struct timeval start_time
The time the master transaction started.
static const Http::Message * actualReplyHeader(const AccessLogEntry::Pointer &al)
Definition: Format.cc:339
#define safe_free(x)
Definition: xalloc.h:73
const char * bumpMode(int bm)
Definition: support.h:144
bool totalResponseTime(struct timeval &responseTime)
Definition: access_log.cc:344
int parse(const char *def, enum Quoting *quote)
Definition: Token.cc:276
const char * methodStr(Method)
Definition: Elements.cc:15
#define rfc1738_escape(x)
Definition: rfc1738.h:52
static struct stat sb
Definition: squidclient.cc:70
MessageSizes clientReplySz
counters for the response sent to client
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
HttpHeaderEntry * getEntry(HttpHeaderPos *pos) const
Definition: HttpHeader.cc:589
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:272
Comm::ConnectionPointer tcpClient
TCP/IP level details about the client connection.
AnyP::ProtocolVersion http_ver
Definition: Message.h:72
bool isEmpty() const
Definition: SBuf.h:420
char * p
Definition: membanger.c:43
int conn
the current server connection FD
Definition: Transport.cc:26
String getByName(const SBuf &name) const
Definition: HttpHeader.cc:879
const char * sslGetUserAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:659
Quoting
Quoting style for a format output.
Definition: ByteCode.h:249
SBuf getLogMethod() const
Fetch the transaction method string (ICP opcode, HTCP opcode or HTTP method)
struct timeval current_time
Definition: stub_time.cc:15
const char * errorDetailName(int errDetailId)
size_type size() const
Definition: SquidString.h:72
Eui::Eui64 remoteEui64
Definition: Connection.h:169
uint64_t messageTotal() const
total message size
Definition: MessageSizes.h:27
char host[SQUIDHOSTNAMELEN]
virtual ~Format()
Definition: Format.cc:47
String reqUri
ICAP Request-URI.
time_t squid_curtime
Definition: stub_time.cc:17
const char * cipherName() const
bool isAnyAddr() const
Definition: Address.cc:163
CbDataList * next
Definition: CbDataList.h:31
static const Http::Message * actualRequestHeader(const AccessLogEntry::Pointer &al)
Definition: Format.cc:353
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
const char * sslGetCAAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:672
HttpRequest * adapted_request
const Security::NegotiationHistory * hasTlsNegotiations() const
Definition: Connection.h:124
void EVH void * arg
Definition: stub_event.cc:16
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:24
unsigned int major
major version number
void port(unsigned short p)
Definition: Uri.h:80
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
Adaptation::History::Pointer adaptHistory(bool createIfNone=false) const
Returns possibly nil history, creating it if requested.
Definition: HttpRequest.cc:413
const char * negotiatedVersion() const
String representation of TLS negotiated version.
String getByNameListMember(const char *name, const char *member, const char separator) const
Definition: HttpHeader.cc:948
#define DBG_IMPORTANT
Definition: Debug.h:46
class AccessLogEntry::AdaptationDetails adapt
bool empty() const
Definition: Notes.h:242
Ip::Address client_addr
Definition: HttpRequest.h:137
void allLogString(const char *serviceId, SBuf &)
dump individual xaction times to a string
Definition: History.cc:66
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:115
char const * termedBuf() const
Definition: SquidString.h:91
const char * getExtUser() const
Fetch the external ACL provided 'user=' string, or nil if none is available.
const char * c_str() const
compute the status access.log field
Definition: LogTags.cc:56
Cbc * valid() const
was set and is valid
Definition: CbcPointer.h:41
String tag
Definition: HttpRequest.h:165
const char * errorPageName(int pageId)
error ID to string
Definition: errorpage.cc:540
GETX509ATTRIBUTE GetX509CAAttribute
Definition: support.h:119
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
Definition: HttpRequest.cc:672
common parts of HttpRequest and HttpReply
Definition: Message.h:24
AnyP::Uri url
the request URI
Definition: HttpRequest.h:103
void * addr
Definition: membanger.c:46
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:218
class AccessLogEntry::Headers headers
HttpRequest * request
uint64_t header
Definition: MessageSizes.h:21
AnyP::UriScheme const & getScheme() const
Definition: Uri.h:64
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.
bool isIPv4() const
Definition: Address.cc:151
int64_t bytesSent
number of bytes sent to ICAP server so far
virtual const char * credentialsStr()=0
bool find(SBuf &resultNote, const char *noteKey, const char *sep=",") const
Definition: Notes.cc:240
int cur
Definition: ModDevPoll.cc:76
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...
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:64
class AccessLogEntry::CacheDetails cache
ssize_t HttpHeaderPos
Definition: HttpHeader.h:45
class AccessLogEntry::SslDetails ssl
unsigned short port() const
Definition: Address.cc:771
const char * fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
Definition: fqdncache.cc:482
HttpReply * reply
ICAP reply.
Ip::Address local
Definition: Connection.h:135
HttpHeader header
Definition: Message.h:74
unsigned stolen
Definition: MemBuf.h:151
String serviceName
ICAP service name.
const SBuf & image() const
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
const char * helloVersion() const
String representation of the received TLS hello message version.
#define xmalloc
int dnsWait
sum of DNS lookup delays in milliseconds, for dt
Definition: HttpRequest.h:147
const Ip::Address * FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:764
void assemble(MemBuf &mb, const AccessLogEntryPointer &al, int logSequenceNumber) const
assemble the state information into a formatted line.
Definition: Format.cc:366
char const * username() const
Definition: UserRequest.cc:32
String extacl_user
Definition: HttpRequest.h:167
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:115
const char * sslGetUserCertificatePEM(SSL *ssl)
Definition: support.cc:692
const char * hier_code_str[]
AnyP::ProtocolVersion version
unsigned int minor
minor version number
BumpMode
Definition: support.h:130
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.
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition: Address.cc:795
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:36
#define xfree
bool encode(char *buf, const int len) const
Definition: Eui48.cc:119
HierarchyLogEntry hier
const SBuf Dash
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:892
MessageSizes clientRequestSz
counters for the original request received from client
const char * toString(const char *sep="\r\n") const
Definition: Notes.cc:254
C * getRaw() const
Definition: RefCount.h:74
ByteCode_t
Definition: ByteCode.h:30
#define NULL
Definition: types.h:166
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:162
Http::StatusCode peer_reply_status
last HTTP status code received
int size
Definition: ModDevPoll.cc:77
const char * getClientIdent() const
Fetch the client IDENT string, or nil if none is available.
int64_t bytesRead
number of bytes read from ICAP server so far
void dump(StoreEntry *entry, const char *directiveName, bool eol=true) const
dump this whole list of formats into the provided StoreEntry
Definition: Format.cc:97
void strwordquote(MemBuf *mb, const char *str)
Definition: tools.cc:1042

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors