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 "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 "rfc1738.h"
25 #include "sbuf/StringConvert.h"
26 #include "security/CertError.h"
28 #include "SquidTime.h"
29 #include "Store.h"
30 #include "tools.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 
474  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw()))
475  out = addr->toStr(tmp, sizeof(tmp));
476  break;
477 
478  case LFT_CLIENT_LOCAL_IP:
479  if (al->tcpClient)
480  out = al->tcpClient->local.toStr(tmp, sizeof(tmp));
481  break;
482 
484  if (al->tcpClient) {
485  sb.appendf("0x%x", static_cast<uint32_t>(al->tcpClient->tos));
486  out = sb.c_str();
487  }
488  break;
489 
491  if (al->tcpClient) {
492  sb.appendf("0x%x", al->tcpClient->nfmark);
493  out = sb.c_str();
494  }
495  break;
496 
498  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw())) {
499  outint = addr->port();
500  doint = 1;
501  }
502  break;
503 
505  if (al->tcpClient) {
506  outint = al->tcpClient->local.port();
507  doint = 1;
508  }
509  break;
510 
512  case LFT_SERVER_LOCAL_IP:
513  if (al->hier.tcpServer)
514  out = al->hier.tcpServer->local.toStr(tmp, sizeof(tmp));
515  break;
516 
518  if (al->hier.tcpServer) {
519  outint = al->hier.tcpServer->local.port();
520  doint = 1;
521  }
522  break;
523 
525  if (al->hier.tcpServer) {
526  sb.appendf("0x%x", static_cast<uint32_t>(al->hier.tcpServer->tos));
527  out = sb.c_str();
528  }
529  break;
530 
532  if (al->hier.tcpServer) {
533  sb.appendf("0x%x", al->hier.tcpServer->nfmark);
534  out = sb.c_str();
535  }
536  break;
537 
539  if (al->request && al->request->clientConnectionManager.valid()) {
540  const auto &handshake = al->request->clientConnectionManager->preservedClientData;
541  if (const auto rawLength = handshake.length()) {
542  // add 1 byte to optimize the c_str() conversion below
543  char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1);
544 
545  struct base64_encode_ctx ctx;
546  base64_encode_init(&ctx);
547  auto encLength = base64_encode_update(&ctx, buf, rawLength, reinterpret_cast<const uint8_t*>(handshake.rawContent()));
548  encLength += base64_encode_final(&ctx, buf + encLength);
549 
550  sb.rawAppendFinish(buf, encLength);
551  out = sb.c_str();
552  }
553  }
554  break;
555 
557  // some platforms store time in 32-bit, some 64-bit...
558  outoff = static_cast<int64_t>(current_time.tv_sec);
559  dooff = 1;
560  break;
561 
562  case LFT_TIME_SUBSECOND:
563  outint = current_time.tv_usec / fmt->divisor;
564  doint = 1;
565  break;
566 
567  case LFT_TIME_LOCALTIME:
568  case LFT_TIME_GMT: {
569  const char *spec;
570  struct tm *t;
571  spec = fmt->data.string;
572 
573  if (fmt->type == LFT_TIME_LOCALTIME) {
574  if (!spec)
575  spec = "%d/%b/%Y:%H:%M:%S %z";
576  t = localtime(&squid_curtime);
577  } else {
578  if (!spec)
579  spec = "%d/%b/%Y:%H:%M:%S";
580 
581  t = gmtime(&squid_curtime);
582  }
583 
584  strftime(tmp, sizeof(tmp), spec, t);
585  out = tmp;
586  }
587  break;
588 
589  case LFT_TIME_START:
590  outtv = al->cache.start_time;
591  doSec = 1;
592  break;
593 
595  outtv = al->cache.trTime;
596  doMsec = 1;
597  break;
598 
600  struct timeval peerResponseTime;
601  if (al->hier.peerResponseTime(peerResponseTime)) {
602  outtv = peerResponseTime;
603  doMsec = 1;
604  }
605  break;
606 
608  struct timeval totalResponseTime;
609  if (al->hier.totalResponseTime(totalResponseTime)) {
610  outtv = totalResponseTime;
611  doMsec = 1;
612  }
613  }
614  break;
615 
616  case LFT_DNS_WAIT_TIME:
617  if (al->request && al->request->dnsWait >= 0) {
618  // TODO: microsecond precision for dns wait time.
619  // Convert miliseconds to timeval struct:
620  outtv.tv_sec = al->request->dnsWait / 1000;
621  outtv.tv_usec = (al->request->dnsWait % 1000) * 1000;
622  doMsec = 1;
623  }
624  break;
625 
626  case LFT_REQUEST_HEADER:
627  if (const Http::Message *msg = actualRequestHeader(al)) {
628  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
629  out = sb.c_str();
630  quote = 1;
631  }
632  break;
633 
635  if (al->adapted_request) {
636  sb = StringToSBuf(al->adapted_request->header.getByName(fmt->data.header.header));
637  out = sb.c_str();
638  quote = 1;
639  }
640  break;
641 
642  case LFT_REPLY_HEADER:
643  if (const Http::Message *msg = actualReplyHeader(al)) {
644  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
645  out = sb.c_str();
646  quote = 1;
647  }
648  break;
649 
650 #if USE_ADAPTATION
652  if (al->request) {
654  if (ah) {
655  ah->sumLogString(fmt->data.string, sb);
656  out = sb.c_str();
657  }
658  }
659  break;
660 
662  if (al->request) {
664  if (ah) {
665  ah->allLogString(fmt->data.string, sb);
666  out = sb.c_str();
667  }
668  }
669  break;
670 
672  if (al->request) {
674  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
675  sb = StringToSBuf(ah->allMeta.getByName(fmt->data.header.header));
676  out = sb.c_str();
677  quote = 1;
678  }
679  }
680  break;
681 
683  if (al->request) {
685  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
686  sb = StringToSBuf(ah->allMeta.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
687  out = sb.c_str();
688  quote = 1;
689  }
690  }
691  break;
692 
694  out = al->adapt.last_meta;
695  quote = 1;
696  break;
697 #endif
698 
699 #if ICAP_CLIENT
700  case LFT_ICAP_ADDR:
701  out = al->icap.hostAddr.toStr(tmp, sizeof(tmp));
702  break;
703 
704  case LFT_ICAP_SERV_NAME:
705  out = al->icap.serviceName.termedBuf();
706  break;
707 
709  out = al->icap.reqUri.termedBuf();
710  break;
711 
714  break;
715 
716  case LFT_ICAP_BYTES_SENT:
717  outoff = al->icap.bytesSent;
718  dooff = 1;
719  break;
720 
721  case LFT_ICAP_BYTES_READ:
722  outoff = al->icap.bytesRead;
723  dooff = 1;
724  break;
725 
727  if (al->icap.bodyBytesRead >= 0) {
728  outoff = al->icap.bodyBytesRead;
729  dooff = 1;
730  }
731  // else if icap.bodyBytesRead < 0, we do not have any http data,
732  // so just print a "-" (204 responses etc)
733  break;
734 
735  case LFT_ICAP_REQ_HEADER:
736  if (al->icap.request) {
737  sb = StringToSBuf(al->icap.request->header.getByName(fmt->data.header.header));
738  out = sb.c_str();
739  quote = 1;
740  }
741  break;
742 
744  if (al->icap.request) {
745  sb = StringToSBuf(al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
746  out = sb.c_str();
747  quote = 1;
748  }
749  break;
750 
752  if (al->icap.request) {
754  while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
755  sb.append(e->name);
756  sb.append(": ");
757  sb.append(StringToSBuf(e->value));
758  sb.append("\r\n");
759  }
760  out = sb.c_str();
761  quote = 1;
762  }
763  break;
764 
765  case LFT_ICAP_REP_HEADER:
766  if (al->icap.reply) {
767  sb = StringToSBuf(al->icap.reply->header.getByName(fmt->data.header.header));
768  out = sb.c_str();
769  quote = 1;
770  }
771  break;
772 
774  if (al->icap.reply) {
775  sb = StringToSBuf(al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
776  out = sb.c_str();
777  quote = 1;
778  }
779  break;
780 
782  if (al->icap.reply) {
784  while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
785  sb.append(e->name);
786  sb.append(": ");
787  sb.append(StringToSBuf(e->value));
788  sb.append("\r\n");
789  }
790  out = sb.c_str();
791  quote = 1;
792  }
793  break;
794 
796  outtv = al->icap.trTime;
797  doMsec = 1;
798  break;
799 
800  case LFT_ICAP_IO_TIME:
801  outtv = al->icap.ioTime;
802  doMsec = 1;
803  break;
804 
806  outint = al->icap.resStatus;
807  doint = 1;
808  break;
809 
810  case LFT_ICAP_OUTCOME:
811  out = al->icap.outcome;
812  break;
813 
814  case LFT_ICAP_TOTAL_TIME:
815  outtv = al->icap.processingTime;
816  doMsec = 1;
817  break;
818 #endif
820  if (const Http::Message *msg = actualRequestHeader(al)) {
821  sb = StringToSBuf(msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
822  out = sb.c_str();
823  quote = 1;
824  }
825  break;
826 
828  if (al->adapted_request) {
829  sb = StringToSBuf(al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
830  out = sb.c_str();
831  quote = 1;
832  }
833  break;
834 
836  if (const Http::Message *msg = actualReplyHeader(al)) {
837  sb = StringToSBuf(msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator));
838  out = sb.c_str();
839  quote = 1;
840  }
841  break;
842 
844 #if ICAP_CLIENT
846  // XXX: since AccessLogEntry::Headers lacks virgin response
847  // headers, do nothing for now
848  out = nullptr;
849  } else
850 #endif
851  {
852  out = al->headers.request;
853  quote = 1;
854  }
855  break;
856 
858  out = al->headers.adapted_request;
859  quote = 1;
860  break;
861 
863  out = al->headers.reply;
864 #if ICAP_CLIENT
865  if (!out && al->icap.reqMethod == Adaptation::methodReqmod)
866  out = al->headers.adapted_request;
867 #endif
868  quote = 1;
869  break;
870 
871  case LFT_USER_NAME:
872 #if USE_AUTH
873  if (al->request && al->request->auth_user_request)
875 #endif
876  if (!out && al->request && al->request->extacl_user.size()) {
877  if (const char *t = al->request->extacl_user.termedBuf())
878  out = t;
879  }
880  if (!out)
881  out = strOrNull(al->getExtUser());
882 #if USE_OPENSSL
883  if (!out)
884  out = strOrNull(al->cache.ssluser);
885 #endif
886  if (!out)
887  out = strOrNull(al->getClientIdent());
888  break;
889 
890  case LFT_USER_LOGIN:
891 #if USE_AUTH
892  if (al->request && al->request->auth_user_request)
894 #endif
895  break;
896 
897  case LFT_USER_IDENT:
898  out = strOrNull(al->getClientIdent());
899  break;
900 
901  case LFT_USER_EXTERNAL:
902  out = strOrNull(al->getExtUser());
903  break;
904 
905  /* case LFT_USER_REALM: */
906  /* case LFT_USER_SCHEME: */
907 
908  // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
909  // but compiler complains if ommited
912  outint = al->http.code;
913  doint = 1;
914  break;
915 
917  if (al->hier.peer_reply_status != Http::scNone) {
918  outint = al->hier.peer_reply_status;
919  doint = 1;
920  }
921  break;
922  /* case LFT_HTTP_STATUS:
923  * out = statusline->text;
924  * quote = 1;
925  * break;
926  */
928  if (al->hier.bodyBytesRead >= 0) {
929  outoff = al->hier.bodyBytesRead;
930  dooff = 1;
931  }
932  // else if hier.bodyBytesRead < 0 we did not have any data exchange with
933  // a peer server so just print a "-" (eg requests served from cache,
934  // or internal error messages).
935  break;
936 
937  case LFT_SQUID_STATUS:
938  out = al->cache.code.c_str();
939  break;
940 
941  case LFT_SQUID_ERROR:
942  if (al->request && al->request->errType != ERR_NONE)
943  out = errorPageName(al->request->errType);
944  break;
945 
947 #if USE_OPENSSL
948  if (al->request && al->request->errType == ERR_SECURE_CONNECT_FAIL) {
949  out = Ssl::GetErrorName(al->request->errDetail);
950  if (!out)
951  out = sslErrorName(al->request->errDetail, tmp, sizeof(tmp));
952  } else
953 #endif
954  if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
956  out = errorDetailName(al->request->errDetail);
957  else {
959  sb.appendf("%s=0x%X",
960  errorDetailName(al->request->errDetail), (uint32_t) al->request->errDetail);
961  else
962  sb.appendf("%s=%d",
964  out = sb.c_str();
965  }
966  }
967  break;
968 
969  case LFT_SQUID_HIERARCHY:
970  if (al->hier.ping.timedout)
971  mb.append("TIMEOUT_", 8);
972  out = hier_code_str[al->hier.code];
973  break;
974 
975  case LFT_MIME_TYPE:
976  out = al->http.content_type;
977  break;
978 
980  if (al->request) {
981  sb = al->request->method.image();
982  out = sb.c_str();
983  quote = 1;
984  }
985  break;
986 
987  case LFT_CLIENT_REQ_URI:
988  if (const auto uri = al->effectiveVirginUrl()) {
989  sb = *uri;
990  out = sb.c_str();
991  quote = 1;
992  }
993  break;
994 
996  if (al->request) {
997  sb = al->request->url.getScheme().image();
998  out = sb.c_str();
999  quote = 1;
1000  }
1001  break;
1002 
1004  if (al->request) {
1005  out = al->request->url.host();
1006  quote = 1;
1007  }
1008  break;
1009 
1011  if (al->request) {
1012  outint = al->request->url.port();
1013  doint = 1;
1014  }
1015  break;
1016 
1019  if (al->request) {
1020  sb = al->request->url.path();
1021  out = sb.c_str();
1022  quote = 1;
1023  }
1024  break;
1025 
1027  if (al->request) {
1028  sb.appendf("%u.%u", al->request->http_ver.major, al->request->http_ver.minor);
1029  out = sb.c_str();
1030  }
1031  break;
1032 
1033  case LFT_REQUEST_METHOD:
1034  sb = al->getLogMethod();
1035  out = sb.c_str();
1036  quote = 1;
1037  break;
1038 
1039  case LFT_REQUEST_URI:
1040  if (!al->url.isEmpty()) {
1041  sb = al->url;
1042  out = sb.c_str();
1043  }
1044  break;
1045 
1047  case LFT_REQUEST_VERSION:
1048  sb.appendf("%u.%u", al->http.version.major, al->http.version.minor);
1049  out = sb.c_str();
1050  break;
1051 
1052  case LFT_SERVER_REQ_METHOD:
1053  if (al->adapted_request) {
1054  sb = al->adapted_request->method.image();
1055  out = sb.c_str();
1056  quote = 1;
1057  }
1058  break;
1059 
1060  case LFT_SERVER_REQ_URI:
1061  // adapted request URI sent to server/peer
1062  if (al->adapted_request) {
1064  out = sb.c_str();
1065  quote = 1;
1066  }
1067  break;
1068 
1070  if (al->adapted_request) {
1071  sb = al->adapted_request->url.getScheme().image();
1072  out = sb.c_str();
1073  quote = 1;
1074  }
1075  break;
1076 
1078  if (al->adapted_request) {
1079  out = al->adapted_request->url.host();
1080  quote = 1;
1081  }
1082  break;
1083 
1085  if (al->adapted_request) {
1086  outint = al->adapted_request->url.port();
1087  doint = 1;
1088  }
1089  break;
1090 
1092  if (al->adapted_request) {
1093  sb = al->adapted_request->url.path();
1094  out = sb.c_str();
1095  quote = 1;
1096  }
1097  break;
1098 
1100  if (al->adapted_request) {
1101  sb.appendf("%u.%u",
1104  out = tmp;
1105  }
1106  break;
1107 
1109  outoff = al->http.clientRequestSz.messageTotal();
1110  dooff = 1;
1111  break;
1112 
1114  outoff = al->http.clientRequestSz.header;
1115  dooff =1;
1116  break;
1117 
1118  /*case LFT_REQUEST_SIZE_BODY: */
1119  /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
1120 
1122  outoff = al->http.clientReplySz.messageTotal();
1123  dooff = 1;
1124  break;
1125 
1126  case LFT_REPLY_HIGHOFFSET:
1127  outoff = al->cache.highOffset;
1128  dooff = 1;
1129  break;
1130 
1131  case LFT_REPLY_OBJECTSIZE:
1132  outoff = al->cache.objectSize;
1133  dooff = 1;
1134  break;
1135 
1137  outint = al->http.clientReplySz.header;
1138  doint = 1;
1139  break;
1140 
1141  /*case LFT_REPLY_SIZE_BODY: */
1142  /*case LFT_REPLY_SIZE_BODY_NO_TE: */
1143 
1146  doint = 1;
1147  break;
1148  /*case LFT_SERVER_IO_SIZE_TOTAL: */
1149 
1150  case LFT_TAG:
1151  if (al->request) {
1152  out = al->request->tag.termedBuf();
1153  quote = 1;
1154  }
1155  break;
1156 
1157  case LFT_EXT_LOG:
1158  if (al->request) {
1159  out = al->request->extacl_log.termedBuf();
1160  quote = 1;
1161  }
1162  break;
1163 
1164  case LFT_SEQUENCE_NUMBER:
1165  outoff = logSequenceNumber;
1166  dooff = 1;
1167  break;
1168 
1169 #if USE_OPENSSL
1170  case LFT_SSL_BUMP_MODE: {
1171  const Ssl::BumpMode mode = static_cast<Ssl::BumpMode>(al->ssl.bumpMode);
1172  // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
1173  out = Ssl::bumpMode(mode);
1174  }
1175  break;
1176 
1178  if (al->request) {
1180  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1181  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1182  out = sslGetUserCertificatePEM(ssl);
1183  }
1184  }
1185  break;
1186 
1188  if (al->request) {
1190  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1191  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1192  out = sslGetUserCertificatePEM(ssl);
1193  }
1194  }
1195  break;
1196 
1197  case LFT_EXT_ACL_USER_CERT:
1198  if (al->request) {
1200  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1201  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1202  out = sslGetUserAttribute(ssl, format->data.header.header);
1203  }
1204  }
1205  break;
1206 
1208  if (al->request) {
1210  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1211  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1212  out = sslGetCAAttribute(ssl, format->data.header.header);
1213  }
1214  }
1215  break;
1216 
1218  if (X509 *cert = al->cache.sslClientCert.get()) {
1219  if (X509_NAME *subject = X509_get_subject_name(cert)) {
1220  X509_NAME_oneline(subject, tmp, sizeof(tmp));
1221  out = tmp;
1222  }
1223  }
1224  break;
1225 
1227  if (X509 *cert = al->cache.sslClientCert.get()) {
1228  if (X509_NAME *issuer = X509_get_issuer_name(cert)) {
1229  X509_NAME_oneline(issuer, tmp, sizeof(tmp));
1230  out = tmp;
1231  }
1232  }
1233  break;
1234 
1235  case LFT_SSL_CLIENT_SNI:
1236  if (al->request && al->request->clientConnectionManager.valid()) {
1237  if (const ConnStateData *conn = al->request->clientConnectionManager.get()) {
1238  if (!conn->tlsClientSni().isEmpty()) {
1239  sb = conn->tlsClientSni();
1240  out = sb.c_str();
1241  }
1242  }
1243  }
1244  break;
1245 
1247  if (al->request && al->request->clientConnectionManager.valid()) {
1248  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1249  const char *separator = fmt->data.string ? fmt->data.string : ":";
1250  for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) {
1251  if (!sb.isEmpty())
1252  sb.append(separator);
1253  if (const char *errorName = Ssl::GetErrorName(sslError->element.code))
1254  sb.append(errorName);
1255  else
1256  sb.append(sslErrorName(sslError->element.code, tmp, sizeof(tmp)));
1257  if (sslError->element.depth >= 0)
1258  sb.appendf("@depth=%d", sslError->element.depth);
1259  }
1260  if (!sb.isEmpty())
1261  out = sb.c_str();
1262  }
1263  }
1264  break;
1265 
1268  if (al->request && al->request->clientConnectionManager.valid()) {
1269  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1270  if (X509 *serverCert = srvBump->serverCert.get()) {
1271  if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT)
1272  out = Ssl::GetX509UserAttribute(serverCert, "DN");
1273  else
1274  out = Ssl::GetX509CAAttribute(serverCert, "DN");
1275  }
1276  }
1277  }
1278  break;
1279 
1281  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1283  break;
1284 
1286  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1288  break;
1289 
1291  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1292  out = al->tcpClient->hasTlsNegotiations()->helloVersion();
1293  break;
1294 
1296  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1298  break;
1299 
1301  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1303  break;
1304 
1306  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1308  break;
1309 
1311  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1312  out = al->tcpClient->hasTlsNegotiations()->cipherName();
1313  break;
1314 
1316  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1317  out = al->hier.tcpServer->hasTlsNegotiations()->cipherName();
1318  break;
1319 #endif
1320 
1322  assert(LFT_REQUEST_URLGROUP_OLD_2X == 0); // should never happen.
1323 
1324  case LFT_NOTE:
1325  tmp[0] = fmt->data.header.separator;
1326  tmp[1] = '\0';
1327  if (fmt->data.header.header && *fmt->data.header.header) {
1328  const char *separator = tmp;
1329  static SBuf note;
1330 #if USE_ADAPTATION
1332  if (ah && ah->metaHeaders) {
1333  if (ah->metaHeaders->find(note, fmt->data.header.header, separator))
1334  sb.append(note);
1335  }
1336 #endif
1337  if (al->notes) {
1338  if (al->notes->find(note, fmt->data.header.header, separator)) {
1339  if (!sb.isEmpty())
1340  sb.append(separator);
1341  sb.append(note);
1342  }
1343  }
1344  out = sb.c_str();
1345  quote = 1;
1346  } else {
1347  // if no argument given use default "\r\n" as notes separator
1348  const char *separator = fmt->data.string ? tmp : "\r\n";
1349 #if USE_ADAPTATION
1351  if (ah && ah->metaHeaders && !ah->metaHeaders->empty())
1352  sb.append(ah->metaHeaders->toString(separator));
1353 #endif
1354  if (al->notes && !al->notes->empty())
1355  sb.append(al->notes->toString(separator));
1356 
1357  out = sb.c_str();
1358  quote = 1;
1359  }
1360  break;
1361 
1362  case LFT_CREDENTIALS:
1363 #if USE_AUTH
1364  if (al->request && al->request->auth_user_request)
1366 #endif
1367  break;
1368 
1369  case LFT_PERCENT:
1370  out = "%";
1371  break;
1372 
1373  case LFT_EXT_ACL_NAME:
1374  out = al->lastAclName;
1375  break;
1376 
1377  case LFT_EXT_ACL_DATA:
1378  if (!al->lastAclData.isEmpty())
1379  out = al->lastAclData.c_str();
1380  break;
1381  }
1382 
1383  if (dooff) {
1384  sb.appendf("%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff);
1385  out = sb.c_str();
1386 
1387  } else if (doint) {
1388  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
1389  out = sb.c_str();
1390  } else if (doMsec) {
1391  if (fmt->widthMax < 0) {
1392  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, tvToMsec(outtv));
1393  } else {
1394  int precision = fmt->widthMax;
1395  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)));
1396  }
1397  out = sb.c_str();
1398  } else if (doSec) {
1399  int precision = fmt->widthMax >=0 ? fmt->widthMax :3;
1400  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));
1401  out = sb.c_str();
1402  }
1403 
1404  if (out && *out) {
1405  if (quote || fmt->quote != LOG_QUOTE_NONE) {
1406  // Do not write to the tmp buffer because it may contain the to-be-quoted value.
1407  static char quotedOut[2 * sizeof(tmp)];
1408  static_assert(sizeof(quotedOut) > 0, "quotedOut has zero length");
1409  quotedOut[0] = '\0';
1410 
1411  char *newout = NULL;
1412  int newfree = 0;
1413 
1414  switch (fmt->quote) {
1415 
1416  case LOG_QUOTE_NONE:
1417  newout = rfc1738_escape_unescaped(out);
1418  break;
1419 
1420  case LOG_QUOTE_QUOTES: {
1421  size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
1422  if (out_len >= sizeof(tmp)) {
1423  newout = (char *)xmalloc(out_len);
1424  newfree = 1;
1425  } else
1426  newout = quotedOut;
1427  log_quoted_string(out, newout);
1428  }
1429  break;
1430 
1431  case LOG_QUOTE_MIMEBLOB:
1432  newout = QuoteMimeBlob(out);
1433  newfree = 1;
1434  break;
1435 
1436  case LOG_QUOTE_URL:
1437  newout = rfc1738_escape(out);
1438  break;
1439 
1440  case LOG_QUOTE_SHELL: {
1441  MemBuf mbq;
1442  mbq.init();
1443  strwordquote(&mbq, out);
1444  newout = mbq.content();
1445  mbq.stolen = 1;
1446  newfree = 1;
1447  }
1448  break;
1449 
1450  case LOG_QUOTE_RAW:
1451  break;
1452  }
1453 
1454  if (newout) {
1455  if (dofree)
1456  safe_free(out);
1457 
1458  out = newout;
1459 
1460  dofree = newfree;
1461  }
1462  }
1463 
1464  // enforce width limits if configured
1465  const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff && !doMsec && !doSec;
1466  if (haveMaxWidth || fmt->widthMin) {
1467  const int minWidth = fmt->widthMin >= 0 ?
1468  fmt->widthMin :0;
1469  const int maxWidth = haveMaxWidth ?
1470  fmt->widthMax : strlen(out);
1471 
1472  if (fmt->left)
1473  mb.appendf("%-*.*s", minWidth, maxWidth, out);
1474  else
1475  mb.appendf("%*.*s", minWidth, maxWidth, out);
1476  } else
1477  mb.append(out, strlen(out));
1478  } else {
1479  mb.append("-", 1);
1480  }
1481 
1482  if (fmt->space)
1483  mb.append(" ", 1);
1484 
1485  sb.clear();
1486 
1487  if (dofree)
1488  safe_free(out);
1489  }
1490 }
1491 
static char * sslErrorName(Security::ErrorCode err, char *buf, size_t size)
Definition: Format.cc:327
GETX509ATTRIBUTE GetX509UserAttribute
Definition: support.h:116
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
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:175
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:154
nfmark_t nfmark
Definition: Connection.h:152
const char * GetErrorName(Security::ErrorCode value)
The string representation of the TLS error &quot;value&quot;.
Definition: ErrorDetail.cc:392
int type
Definition: errorpage.cc:78
Format(const char *name)
Definition: Format.cc:41
void path(const char *p)
Definition: Uri.h:86
Definition: SBuf.h:86
virtual void append(char const *, int)
Appends a c-string to existing packed data.
Definition: store.cc:823
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: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:311
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:144
bool totalResponseTime(struct timeval &responseTime)
Definition: access_log.cc:344
int parse(const char *def, enum Quoting *quote)
Definition: Token.cc:277
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
const SBuf * effectiveVirginUrl() const
HttpHeaderEntry * getEntry(HttpHeaderPos *pos) const
Definition: HttpHeader.cc:598
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: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:888
const char * sslGetUserAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:659
Quoting
Quoting style for a format output.
Definition: ByteCode.h:251
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: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
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
void rawAppendFinish(const char *start, size_type actualSize)
Definition: SBuf.cc:144
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:83
char * rawAppendStart(size_type anticipatedSize)
Definition: SBuf.cc:136
#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: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:957
#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:141
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 (&lt;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 &#39;user=&#39; 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:169
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:687
common parts of HttpRequest and HttpReply
Definition: Message.h:24
AnyP::Uri url
the request URI
Definition: HttpRequest.h:107
void * addr
Definition: membanger.c:46
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:222
class AccessLogEntry::Headers headers
HttpRequest * request
uint64_t header
Definition: MessageSizes.h:21
AnyP::UriScheme const & getScheme() const
Definition: Uri.h:67
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition: base64.c:232
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:65
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
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.
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: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
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:171
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 * 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 &quot;&quot;.
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:875
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.
#define base64_encode_len(length)
Definition: base64.h:169
int64_t bytesRead
number of bytes read from ICAP server so far
char * name
Definition: Format.h:59
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