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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors