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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors