Format.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 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 "error/Detail.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 "http/Stream.h"
21 #include "HttpRequest.h"
22 #include "MemBuf.h"
23 #include "proxyp/Header.h"
24 #include "rfc1738.h"
25 #include "sbuf/Stream.h"
26 #include "sbuf/StringConvert.h"
27 #include "security/CertError.h"
28 #include "security/Certificate.h"
30 #include "Store.h"
31 #include "tools.h"
32 #if USE_OPENSSL
33 #include "ssl/ErrorDetail.h"
34 #include "ssl/ServerBump.h"
35 #endif
36 
38 #define strOrNull(s) ((s)==NULL||(s)[0]=='\0'?NULL:(s))
39 
40 const SBuf Format::Dash("-");
41 
42 Format::Format::Format(const char *n) :
43  format(nullptr),
44  next(nullptr)
45 {
46  name = xstrdup(n);
47 }
48 
50 {
51  // erase the list without consuming stack space
52  while (next) {
53  // unlink the next entry for deletion
54  Format *temp = next;
55  next = temp->next;
56  temp->next = nullptr;
57  delete temp;
58  }
59 
60  // remove locals
61  xfree(name);
62  delete format;
63 }
64 
65 bool
66 Format::Format::parse(const char *def)
67 {
68  const char *cur, *eos;
69  Token *new_lt, *last_lt;
71 
72  debugs(46, 2, "got definition '" << def << "'");
73 
74  if (format) {
75  debugs(46, DBG_IMPORTANT, "WARNING: existing format for '" << name << " " << def << "'");
76  return false;
77  }
78 
79  /* very inefficient parser, but who cares, this needs to be simple */
80  /* First off, let's tokenize, we'll optimize in a second pass.
81  * A token can either be a %-prefixed sequence (usually a dynamic
82  * token but it can be an escaped sequence), or a string. */
83  cur = def;
84  eos = def + strlen(def);
85  format = new_lt = last_lt = new Token;
86  cur += new_lt->parse(cur, &quote);
87 
88  while (cur < eos) {
89  new_lt = new Token;
90  last_lt->next = new_lt;
91  last_lt = new_lt;
92  cur += new_lt->parse(cur, &quote);
93  }
94 
95  return true;
96 }
97 
98 size_t
99 Format::AssembleOne(const char *token, MemBuf &mb, const AccessLogEntryPointer &ale)
100 {
101  Token tkn;
103  const auto tokenSize = tkn.parse(token, &quote);
104  assert(tokenSize > 0);
105  if (ale != nullptr) {
106  Format fmt("SimpleToken");
107  fmt.format = &tkn;
108  fmt.assemble(mb, ale, 0);
109  fmt.format = nullptr;
110  } else {
111  mb.append("-", 1);
112  }
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, MYNAME);
120 
121  // loop rather than recursing to conserve stack space.
122  for (const Format *fmt = this; fmt; fmt = fmt->next) {
123  debugs(46, 3, "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 = nullptr;
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
176  break;
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) {
202  break;
205  break;
208  break;
209 #if USE_ADAPTATION
212  break;
213 #endif
214 #if ICAP_CLIENT
217  break;
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 
349 static const Http::Message *
351 {
352  const Http::Message *msg = al->reply.getRaw();
353 #if ICAP_CLIENT
354  // al->icap.reqMethod is methodNone in access.log context
355  if (!msg && al->icap.reqMethod == Adaptation::methodReqmod)
356  msg = al->adapted_request;
357 #endif
358  return msg;
359 }
360 
363 static const Http::Message *
365 {
366 #if ICAP_CLIENT
367  // al->icap.reqMethod is methodNone in access.log context
369  // XXX: for now AccessLogEntry lacks virgin response headers
370  return nullptr;
371  }
372 #endif
373  return al->request;
374 }
375 
376 void
377 Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logSequenceNumber) const
378 {
379  static char tmp[1024];
380  SBuf sb;
381 
382  for (Token *fmt = format; fmt; fmt = fmt->next) { /* for each token */
383  const char *out = nullptr;
384  int quote = 0;
385  long int outint = 0;
386  int doint = 0;
387  int dofree = 0;
388  int64_t outoff = 0;
389  int dooff = 0;
390  struct timeval outtv = {};
391  int doMsec = 0;
392  int doSec = 0;
393  bool doUint64 = false;
394  uint64_t outUint64 = 0;
395 
396  switch (fmt->type) {
397 
398  case LFT_NONE:
399  out = "";
400  break;
401 
402  case LFT_STRING:
403  out = fmt->data.string;
404  break;
405 
407  al->getLogClientIp(tmp, sizeof(tmp));
408  out = tmp;
409  break;
410 
411  case LFT_CLIENT_FQDN:
412  out = al->getLogClientFqdn(tmp, sizeof(tmp));
413  break;
414 
415  case LFT_CLIENT_PORT:
416  if (al->request) {
417  outint = al->request->client_addr.port();
418  doint = 1;
419  } else if (al->tcpClient) {
420  outint = al->tcpClient->remote.port();
421  doint = 1;
422  }
423  break;
424 
425  case LFT_CLIENT_EUI:
426 #if USE_SQUID_EUI
427  // TODO make the ACL checklist have a direct link to any TCP details.
428  if (al->request && al->request->clientConnectionManager.valid() &&
431  if (conn->remote.isIPv4())
432  conn->remoteEui48.encode(tmp, sizeof(tmp));
433  else
434  conn->remoteEui64.encode(tmp, sizeof(tmp));
435  out = tmp;
436  }
437 #endif
438  break;
439 
441 #if USE_SQUID_EUI
442  if (al->request && al->request->clientConnectionManager.valid() &&
446  out = tmp;
447  }
448 #endif
449  break;
450 
452 #if USE_SQUID_EUI
453  if (al->request && al->request->clientConnectionManager.valid() &&
457  out = tmp;
458  }
459 #endif
460  break;
461 
463  if (al->hier.tcpServer)
464  out = al->hier.tcpServer->remote.toStr(tmp, sizeof(tmp));
465  break;
466 
468  out = al->hier.host;
469  break;
470 
471  case LFT_SERVER_PORT:
472  if (al->hier.tcpServer) {
473  outint = al->hier.tcpServer->remote.port();
474  doint = 1;
475  }
476  break;
477 
479  if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw()))
480  out = addr->toStr(tmp, sizeof(tmp));
481  break;
482 
483  case LFT_CLIENT_LOCAL_IP:
484  if (al->tcpClient)
485  out = al->tcpClient->local.toStr(tmp, sizeof(tmp));
486  break;
487 
489  if (al->tcpClient) {
490  sb.appendf("0x%x", static_cast<uint32_t>(al->tcpClient->tos));
491  out = sb.c_str();
492  }
493  break;
494 
496  if (al->tcpClient) {
497  outUint64 = al->tcpClient->id.value;
498  doUint64 = true;
499  }
500  break;
501 
503  if (al->tcpClient) {
504  sb.appendf("0x%x", al->tcpClient->nfmark);
505  out = sb.c_str();
506  }
507  break;
508 
510  if (const auto port = FindListeningPortNumber(nullptr, al.getRaw())) {
511  outint = port;
512  doint = 1;
513  }
514  break;
515 
517  if (al->tcpClient) {
518  outint = al->tcpClient->local.port();
519  doint = 1;
520  }
521  break;
522 
524  case LFT_SERVER_LOCAL_IP:
525  if (al->hier.tcpServer)
526  out = al->hier.tcpServer->local.toStr(tmp, sizeof(tmp));
527  break;
528 
530  if (al->hier.tcpServer) {
531  outint = al->hier.tcpServer->local.port();
532  doint = 1;
533  }
534  break;
535 
537  if (al->hier.tcpServer) {
538  sb.appendf("0x%x", static_cast<uint32_t>(al->hier.tcpServer->tos));
539  out = sb.c_str();
540  }
541  break;
542 
544  if (al->hier.tcpServer) {
545  sb.appendf("0x%x", al->hier.tcpServer->nfmark);
546  out = sb.c_str();
547  }
548  break;
549 
551  if (al->request && al->request->clientConnectionManager.valid()) {
552  const auto &handshake = al->request->clientConnectionManager->preservedClientData;
553  if (const auto rawLength = handshake.length()) {
554  // add 1 byte to optimize the c_str() conversion below
555  char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1);
556 
557  struct base64_encode_ctx ctx;
558  base64_encode_init(&ctx);
559  auto encLength = base64_encode_update(&ctx, buf, rawLength, reinterpret_cast<const uint8_t*>(handshake.rawContent()));
560  encLength += base64_encode_final(&ctx, buf + encLength);
561 
562  sb.rawAppendFinish(buf, encLength);
563  out = sb.c_str();
564  }
565  }
566  break;
567 
569  // some platforms store time in 32-bit, some 64-bit...
570  outoff = static_cast<int64_t>(current_time.tv_sec);
571  dooff = 1;
572  break;
573 
574  case LFT_TIME_SUBSECOND:
575  outint = current_time.tv_usec / fmt->divisor;
576  doint = 1;
577  break;
578 
579  case LFT_TIME_LOCALTIME:
580  case LFT_TIME_GMT: {
581  const char *spec;
582  struct tm *t;
583  spec = fmt->data.string;
584 
585  if (fmt->type == LFT_TIME_LOCALTIME) {
586  if (!spec)
587  spec = "%d/%b/%Y:%H:%M:%S %z";
588  t = localtime(&squid_curtime);
589  } else {
590  if (!spec)
591  spec = "%d/%b/%Y:%H:%M:%S";
592 
593  t = gmtime(&squid_curtime);
594  }
595 
596  strftime(tmp, sizeof(tmp), spec, t);
597  out = tmp;
598  }
599  break;
600 
601  case LFT_TIME_START:
602  outtv = al->cache.start_time;
603  doSec = 1;
604  break;
605 
607  outtv = al->cache.trTime;
608  doMsec = 1;
609  break;
610 
612  struct timeval peerResponseTime;
613  if (al->hier.peerResponseTime(peerResponseTime)) {
614  outtv = peerResponseTime;
615  doMsec = 1;
616  }
617  break;
618 
620  struct timeval totalResponseTime;
621  if (al->hier.totalResponseTime(totalResponseTime)) {
622  outtv = totalResponseTime;
623  doMsec = 1;
624  }
625  }
626  break;
627 
628  case LFT_DNS_WAIT_TIME:
629  if (al->request && al->request->dnsWait >= 0) {
630  // TODO: microsecond precision for dns wait time.
631  // Convert milliseconds to timeval struct:
632  outtv.tv_sec = al->request->dnsWait / 1000;
633  outtv.tv_usec = (al->request->dnsWait % 1000) * 1000;
634  doMsec = 1;
635  }
636  break;
637 
638  case LFT_REQUEST_HEADER:
639  if (const Http::Message *msg = actualRequestHeader(al)) {
640  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
641  out = sb.c_str();
642  quote = 1;
643  }
644  break;
645 
647  if (al->adapted_request) {
648  sb = StringToSBuf(al->adapted_request->header.getByName(fmt->data.header.header));
649  out = sb.c_str();
650  quote = 1;
651  }
652  break;
653 
654  case LFT_REPLY_HEADER:
655  if (const Http::Message *msg = actualReplyHeader(al)) {
656  sb = StringToSBuf(msg->header.getByName(fmt->data.header.header));
657  out = sb.c_str();
658  quote = 1;
659  }
660  break;
661 
662 #if USE_ADAPTATION
664  if (al->request) {
666  if (ah) {
667  ah->sumLogString(fmt->data.string, sb);
668  out = sb.c_str();
669  }
670  }
671  break;
672 
674  if (al->request) {
676  if (ah) {
677  ah->allLogString(fmt->data.string, sb);
678  out = sb.c_str();
679  }
680  }
681  break;
682 
684  if (al->request) {
686  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
687  sb = StringToSBuf(ah->allMeta.getByName(fmt->data.header.header));
688  out = sb.c_str();
689  quote = 1;
690  }
691  }
692  break;
693 
695  if (al->request) {
697  if (ah) { // XXX: add adapt::<all_h but use lastMeta here
698  sb = ah->allMeta.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
699  out = sb.c_str();
700  quote = 1;
701  }
702  }
703  break;
704 
706  out = al->adapt.last_meta;
707  quote = 1;
708  break;
709 #endif
710 
711 #if ICAP_CLIENT
712  case LFT_ICAP_ADDR:
713  out = al->icap.hostAddr.toStr(tmp, sizeof(tmp));
714  break;
715 
716  case LFT_ICAP_SERV_NAME:
717  out = al->icap.serviceName.termedBuf();
718  break;
719 
721  out = al->icap.reqUri.termedBuf();
722  break;
723 
726  break;
727 
728  case LFT_ICAP_BYTES_SENT:
729  outoff = al->icap.bytesSent;
730  dooff = 1;
731  break;
732 
733  case LFT_ICAP_BYTES_READ:
734  outoff = al->icap.bytesRead;
735  dooff = 1;
736  break;
737 
739  if (al->icap.bodyBytesRead >= 0) {
740  outoff = al->icap.bodyBytesRead;
741  dooff = 1;
742  }
743  // else if icap.bodyBytesRead < 0, we do not have any http data,
744  // so just print a "-" (204 responses etc)
745  break;
746 
747  case LFT_ICAP_REQ_HEADER:
748  if (al->icap.request) {
749  sb = StringToSBuf(al->icap.request->header.getByName(fmt->data.header.header));
750  out = sb.c_str();
751  quote = 1;
752  }
753  break;
754 
756  if (al->icap.request) {
757  sb = al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
758  out = sb.c_str();
759  quote = 1;
760  }
761  break;
762 
764  if (al->icap.request) {
766  while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
767  sb.append(e->name);
768  sb.append(": ");
769  sb.append(StringToSBuf(e->value));
770  sb.append("\r\n");
771  }
772  out = sb.c_str();
773  quote = 1;
774  }
775  break;
776 
777  case LFT_ICAP_REP_HEADER:
778  if (al->icap.reply) {
779  sb = StringToSBuf(al->icap.reply->header.getByName(fmt->data.header.header));
780  out = sb.c_str();
781  quote = 1;
782  }
783  break;
784 
786  if (al->icap.reply) {
787  sb = al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
788  out = sb.c_str();
789  quote = 1;
790  }
791  break;
792 
794  if (al->icap.reply) {
796  while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
797  sb.append(e->name);
798  sb.append(": ");
799  sb.append(StringToSBuf(e->value));
800  sb.append("\r\n");
801  }
802  out = sb.c_str();
803  quote = 1;
804  }
805  break;
806 
808  outtv = al->icap.trTime;
809  doMsec = 1;
810  break;
811 
812  case LFT_ICAP_IO_TIME:
813  outtv = al->icap.ioTime;
814  doMsec = 1;
815  break;
816 
818  outint = al->icap.resStatus;
819  doint = 1;
820  break;
821 
822  case LFT_ICAP_OUTCOME:
823  out = al->icap.outcome;
824  break;
825 
826  case LFT_ICAP_TOTAL_TIME:
827  outtv = al->icap.processingTime;
828  doMsec = 1;
829  break;
830 #endif
832  if (const Http::Message *msg = actualRequestHeader(al)) {
833  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
834  out = sb.c_str();
835  quote = 1;
836  }
837  break;
838 
840  if (al->proxyProtocolHeader) {
841  sb = al->proxyProtocolHeader->getValues(fmt->data.headerId, fmt->data.header.separator);
842  out = sb.c_str();
843  quote = 1;
844  }
845  break;
846 
848  if (al->proxyProtocolHeader) {
849  sb = al->proxyProtocolHeader->toMime();
850  out = sb.c_str();
851  quote = 1;
852  }
853  break;
854 
856  if (al->proxyProtocolHeader) {
857  sb = al->proxyProtocolHeader->getElem(fmt->data.headerId, fmt->data.header.element, fmt->data.header.separator);
858  out = sb.c_str();
859  quote = 1;
860  }
861  break;
862 
864  if (al->adapted_request) {
865  sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
866  out = sb.c_str();
867  quote = 1;
868  }
869  break;
870 
872  if (const Http::Message *msg = actualReplyHeader(al)) {
873  sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
874  out = sb.c_str();
875  quote = 1;
876  }
877  break;
878 
880 #if ICAP_CLIENT
882  // XXX: since AccessLogEntry::Headers lacks virgin response
883  // headers, do nothing for now
884  out = nullptr;
885  } else
886 #endif
887  {
888  // just headers without start-line and CRLF
889  // XXX: reconcile with '<h'
890  out = al->headers.request;
891  quote = 1;
892  }
893  break;
894 
896  // just headers without start-line and CRLF
897  // XXX: reconcile with '<h'
898  out = al->headers.adapted_request;
899  quote = 1;
900  break;
901 
902  case LFT_REPLY_ALL_HEADERS: {
903  MemBuf allHeaders;
904  allHeaders.init();
905  // status-line + headers + CRLF
906  // XXX: reconcile with '>h' and '>ha'
907  al->packReplyHeaders(allHeaders);
908  sb.assign(allHeaders.content(), allHeaders.contentSize());
909  out = sb.c_str();
910 #if ICAP_CLIENT
911  if (!out && al->icap.reqMethod == Adaptation::methodReqmod)
912  out = al->headers.adapted_request;
913 #endif
914  quote = 1;
915  }
916  break;
917 
918  case LFT_USER_NAME:
919 #if USE_AUTH
920  if (al->request && al->request->auth_user_request)
922 #endif
923  if (!out && al->request && al->request->extacl_user.size()) {
924  if (const char *t = al->request->extacl_user.termedBuf())
925  out = t;
926  }
927  if (!out)
928  out = strOrNull(al->getExtUser());
929 #if USE_OPENSSL
930  if (!out)
931  out = strOrNull(al->cache.ssluser);
932 #endif
933  if (!out)
934  out = strOrNull(al->getClientIdent());
935  break;
936 
937  case LFT_USER_LOGIN:
938 #if USE_AUTH
939  if (al->request && al->request->auth_user_request)
941 #endif
942  break;
943 
944  case LFT_USER_IDENT:
945  out = strOrNull(al->getClientIdent());
946  break;
947 
948  case LFT_USER_EXTERNAL:
949  out = strOrNull(al->getExtUser());
950  break;
951 
952  /* case LFT_USER_REALM: */
953  /* case LFT_USER_SCHEME: */
954 
955  // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
956  // but compiler complains if omitted
959  outint = al->http.code;
960  doint = 1;
961  break;
962 
964  if (al->hier.peer_reply_status != Http::scNone) {
965  outint = al->hier.peer_reply_status;
966  doint = 1;
967  }
968  break;
969  /* case LFT_HTTP_STATUS:
970  * out = statusline->text;
971  * quote = 1;
972  * break;
973  */
975  if (al->hier.bodyBytesRead >= 0) {
976  outoff = al->hier.bodyBytesRead;
977  dooff = 1;
978  }
979  // else if hier.bodyBytesRead < 0 we did not have any data exchange with
980  // a peer server so just print a "-" (eg requests served from cache,
981  // or internal error messages).
982  break;
983 
984  case LFT_SQUID_STATUS:
985  out = al->cache.code.c_str();
986  break;
987 
988  case LFT_SQUID_ERROR:
989  if (const auto error = al->error())
990  out = errorPageName(error->category);
991  break;
992 
994  if (const auto error = al->error()) {
995  if (const auto detail = error->detail) {
996  sb = detail->brief();
997  out = sb.c_str();
998  }
999  }
1000  break;
1001 
1002  case LFT_SQUID_HIERARCHY:
1003  if (al->hier.ping.timedout)
1004  mb.append("TIMEOUT_", 8);
1005  out = hier_code_str[al->hier.code];
1006  break;
1007 
1008  case LFT_MIME_TYPE:
1009  out = al->http.content_type;
1010  break;
1011 
1012  case LFT_CLIENT_REQ_METHOD:
1013  if (al->request) {
1014  sb = al->request->method.image();
1015  out = sb.c_str();
1016  quote = 1;
1017  }
1018  break;
1019 
1020  case LFT_CLIENT_REQ_URI:
1021  if (const auto uri = al->effectiveVirginUrl()) {
1022  sb = *uri;
1023  out = sb.c_str();
1024  quote = 1;
1025  }
1026  break;
1027 
1029  if (al->request) {
1030  sb = al->request->url.getScheme().image();
1031  out = sb.c_str();
1032  quote = 1;
1033  }
1034  break;
1035 
1037  if (al->request) {
1038  out = al->request->url.host();
1039  quote = 1;
1040  }
1041  break;
1042 
1044  if (al->request) {
1045  outint = al->request->url.port();
1046  doint = 1;
1047  }
1048  break;
1049 
1052  if (al->request) {
1053  sb = al->request->url.path();
1054  out = sb.c_str();
1055  quote = 1;
1056  }
1057  break;
1058 
1060  if (al->request) {
1061  sb.appendf("%u.%u", al->request->http_ver.major, al->request->http_ver.minor);
1062  out = sb.c_str();
1063  }
1064  break;
1065 
1066  case LFT_REQUEST_METHOD:
1067  if (al->hasLogMethod()) {
1068  sb = al->getLogMethod();
1069  out = sb.c_str();
1070  quote = 1;
1071  }
1072  break;
1073 
1074  case LFT_REQUEST_URI:
1075  if (!al->url.isEmpty()) {
1076  sb = al->url;
1077  out = sb.c_str();
1078  }
1079  break;
1080 
1082  case LFT_REQUEST_VERSION:
1083  sb.appendf("%u.%u", al->http.version.major, al->http.version.minor);
1084  out = sb.c_str();
1085  break;
1086 
1087  case LFT_SERVER_REQ_METHOD:
1088  if (al->adapted_request) {
1089  sb = al->adapted_request->method.image();
1090  out = sb.c_str();
1091  quote = 1;
1092  }
1093  break;
1094 
1095  case LFT_SERVER_REQ_URI:
1096  // adapted request URI sent to server/peer
1097  if (al->adapted_request) {
1099  out = sb.c_str();
1100  quote = 1;
1101  }
1102  break;
1103 
1105  if (al->adapted_request) {
1106  sb = al->adapted_request->url.getScheme().image();
1107  out = sb.c_str();
1108  quote = 1;
1109  }
1110  break;
1111 
1113  if (al->adapted_request) {
1114  out = al->adapted_request->url.host();
1115  quote = 1;
1116  }
1117  break;
1118 
1120  if (al->adapted_request) {
1121  outint = al->adapted_request->url.port();
1122  doint = 1;
1123  }
1124  break;
1125 
1127  if (al->adapted_request) {
1128  sb = al->adapted_request->url.path();
1129  out = sb.c_str();
1130  quote = 1;
1131  }
1132  break;
1133 
1135  if (al->adapted_request) {
1136  sb.appendf("%u.%u",
1139  out = tmp;
1140  }
1141  break;
1142 
1144  outoff = al->http.clientRequestSz.messageTotal();
1145  dooff = 1;
1146  break;
1147 
1149  outoff = al->http.clientRequestSz.header;
1150  dooff =1;
1151  break;
1152 
1153  /*case LFT_REQUEST_SIZE_BODY: */
1154  /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
1155 
1157  outoff = al->http.clientReplySz.messageTotal();
1158  dooff = 1;
1159  break;
1160 
1161  case LFT_REPLY_HIGHOFFSET:
1162  outoff = al->cache.highOffset;
1163  dooff = 1;
1164  break;
1165 
1166  case LFT_REPLY_OBJECTSIZE:
1167  outoff = al->cache.objectSize;
1168  dooff = 1;
1169  break;
1170 
1172  outint = al->http.clientReplySz.header;
1173  doint = 1;
1174  break;
1175 
1176  /*case LFT_REPLY_SIZE_BODY: */
1177  /*case LFT_REPLY_SIZE_BODY_NO_TE: */
1178 
1181  doint = 1;
1182  break;
1183  /*case LFT_SERVER_IO_SIZE_TOTAL: */
1184 
1185  case LFT_TAG:
1186  if (al->request) {
1187  out = al->request->tag.termedBuf();
1188  quote = 1;
1189  }
1190  break;
1191 
1192  case LFT_EXT_LOG:
1193  if (al->request) {
1194  out = al->request->extacl_log.termedBuf();
1195  quote = 1;
1196  }
1197  break;
1198 
1199  case LFT_SEQUENCE_NUMBER:
1200  outoff = logSequenceNumber;
1201  dooff = 1;
1202  break;
1203 
1204 #if USE_OPENSSL
1205  case LFT_SSL_BUMP_MODE: {
1206  const Ssl::BumpMode mode = static_cast<Ssl::BumpMode>(al->ssl.bumpMode);
1207  // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
1208  out = Ssl::bumpMode(mode);
1209  }
1210  break;
1211 
1213  if (al->request) {
1215  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1216  if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) {
1218  out = sb.c_str();
1219  }
1220  }
1221  }
1222  break;
1223 
1225  if (al->request) {
1227  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1228  if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) {
1230  out = sb.c_str();
1231  }
1232  }
1233  }
1234  break;
1235 
1236  case LFT_EXT_ACL_USER_CERT:
1237  if (al->request) {
1239  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1240  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1241  out = sslGetUserAttribute(ssl, fmt->data.header.header);
1242  }
1243  }
1244  break;
1245 
1247  if (al->request) {
1249  if (conn && Comm::IsConnOpen(conn->clientConnection)) {
1250  if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get())
1251  out = sslGetCAAttribute(ssl, fmt->data.header.header);
1252  }
1253  }
1254  break;
1255 
1257  if (const auto &cert = al->cache.sslClientCert) {
1258  sb = Security::SubjectName(*cert);
1259  out = sb.c_str();
1260  }
1261  break;
1262 
1264  if (const auto &cert = al->cache.sslClientCert) {
1265  sb = Security::IssuerName(*cert);
1266  out = sb.c_str();
1267  }
1268  break;
1269 
1270  case LFT_SSL_CLIENT_SNI:
1271  if (al->request && al->request->clientConnectionManager.valid()) {
1272  if (const ConnStateData *conn = al->request->clientConnectionManager.get()) {
1273  if (!conn->tlsClientSni().isEmpty()) {
1274  sb = conn->tlsClientSni();
1275  out = sb.c_str();
1276  }
1277  }
1278  }
1279  break;
1280 
1282  if (al->request && al->request->clientConnectionManager.valid()) {
1283  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1284  const char *separator = fmt->data.string ? fmt->data.string : ":";
1285  for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) {
1286  if (!sb.isEmpty())
1287  sb.append(separator);
1288  sb.append(Ssl::GetErrorName(sslError->element.code, true));
1289  if (sslError->element.depth >= 0)
1290  sb.appendf("@depth=%d", sslError->element.depth);
1291  }
1292  if (!sb.isEmpty())
1293  out = sb.c_str();
1294  }
1295  }
1296  break;
1297 
1301  if (al->request && al->request->clientConnectionManager.valid()) {
1302  if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) {
1303  if (X509 *serverCert = srvBump->serverCert.get()) {
1304  if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT)
1305  out = Ssl::GetX509UserAttribute(serverCert, "DN");
1306  else if (fmt->type == LFT_SSL_SERVER_CERT_ISSUER)
1307  out = Ssl::GetX509CAAttribute(serverCert, "DN");
1308  else {
1309  assert(fmt->type == LFT_SSL_SERVER_CERT_WHOLE);
1310  sb = Ssl::GetX509PEM(serverCert);
1311  out = sb.c_str();
1312  quote = 1;
1313  }
1314  }
1315  }
1316  }
1317  break;
1318 
1320  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1322  break;
1323 
1325  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1327  break;
1328 
1330  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1331  out = al->tcpClient->hasTlsNegotiations()->helloVersion();
1332  break;
1333 
1335  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1337  break;
1338 
1340  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1342  break;
1343 
1345  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1347  break;
1348 
1350  if (al->tcpClient && al->tcpClient->hasTlsNegotiations())
1351  out = al->tcpClient->hasTlsNegotiations()->cipherName();
1352  break;
1353 
1355  if (al->hier.tcpServer && al->hier.tcpServer->hasTlsNegotiations())
1356  out = al->hier.tcpServer->hasTlsNegotiations()->cipherName();
1357  break;
1358 #endif
1359 
1361  assert(LFT_REQUEST_URLGROUP_OLD_2X == 0); // should never happen.
1362  break;
1363 
1364  case LFT_NOTE:
1365  tmp[0] = fmt->data.header.separator;
1366  tmp[1] = '\0';
1367  if (fmt->data.header.header && *fmt->data.header.header) {
1368  const char *separator = tmp;
1369  static SBuf note;
1370 #if USE_ADAPTATION
1372  if (ah && ah->metaHeaders) {
1373  if (ah->metaHeaders->find(note, fmt->data.header.header, separator))
1374  sb.append(note);
1375  }
1376 #endif
1377  if (al->notes) {
1378  if (al->notes->find(note, fmt->data.header.header, separator)) {
1379  if (!sb.isEmpty())
1380  sb.append(separator);
1381  sb.append(note);
1382  }
1383  }
1384  out = sb.c_str();
1385  quote = 1;
1386  } else {
1387  // if no argument given use default "\r\n" as notes separator
1388  const char *separator = fmt->data.string ? tmp : "\r\n";
1389 #if USE_ADAPTATION
1391  if (ah && ah->metaHeaders && !ah->metaHeaders->empty())
1392  sb.append(ah->metaHeaders->toString(separator));
1393 #endif
1394  if (al->notes && !al->notes->empty())
1395  sb.append(al->notes->toString(separator));
1396 
1397  out = sb.c_str();
1398  quote = 1;
1399  }
1400  break;
1401 
1402  case LFT_CREDENTIALS:
1403 #if USE_AUTH
1404  if (al->request && al->request->auth_user_request)
1406 #endif
1407  break;
1408 
1409  case LFT_PERCENT:
1410  out = "%";
1411  break;
1412 
1413  case LFT_EXT_ACL_NAME:
1414  out = al->lastAclName;
1415  break;
1416 
1417  case LFT_EXT_ACL_DATA:
1418  if (!al->lastAclData.isEmpty())
1419  out = al->lastAclData.c_str();
1420  break;
1421 
1422  case LFT_MASTER_XACTION:
1423  if (al->request) {
1424  doUint64 = true;
1425  outUint64 = static_cast<uint64_t>(al->request->masterXaction->id.value);
1426  break;
1427  }
1428  }
1429 
1430  if (dooff) {
1431  sb.appendf("%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff);
1432  out = sb.c_str();
1433 
1434  } else if (doint) {
1435  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
1436  out = sb.c_str();
1437  } else if (doUint64) {
1438  sb.appendf("%0*" PRIu64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outUint64);
1439  out = sb.c_str();
1440  } else if (doMsec) {
1441  if (fmt->widthMax < 0) {
1442  sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, tvToMsec(outtv));
1443  } else {
1444  int precision = fmt->widthMax;
1445  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)));
1446  }
1447  out = sb.c_str();
1448  } else if (doSec) {
1449  int precision = fmt->widthMax >=0 ? fmt->widthMax :3;
1450  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));
1451  out = sb.c_str();
1452  }
1453 
1454  if (out && *out) {
1455  if (quote || fmt->quote != LOG_QUOTE_NONE) {
1456  // Do not write to the tmp buffer because it may contain the to-be-quoted value.
1457  static char quotedOut[2 * sizeof(tmp)];
1458  static_assert(sizeof(quotedOut) > 0, "quotedOut has zero length");
1459  quotedOut[0] = '\0';
1460 
1461  char *newout = nullptr;
1462  int newfree = 0;
1463 
1464  switch (fmt->quote) {
1465 
1466  case LOG_QUOTE_NONE:
1467  newout = rfc1738_escape_unescaped(out);
1468  break;
1469 
1470  case LOG_QUOTE_QUOTES: {
1471  size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
1472  if (out_len >= sizeof(tmp)) {
1473  newout = (char *)xmalloc(out_len);
1474  newfree = 1;
1475  } else
1476  newout = quotedOut;
1477  log_quoted_string(out, newout);
1478  }
1479  break;
1480 
1481  case LOG_QUOTE_MIMEBLOB:
1482  newout = QuoteMimeBlob(out);
1483  newfree = 1;
1484  break;
1485 
1486  case LOG_QUOTE_URL:
1487  newout = rfc1738_escape(out);
1488  break;
1489 
1490  case LOG_QUOTE_SHELL: {
1491  MemBuf mbq;
1492  mbq.init();
1493  strwordquote(&mbq, out);
1494  newout = mbq.content();
1495  mbq.stolen = 1;
1496  newfree = 1;
1497  }
1498  break;
1499 
1500  case LOG_QUOTE_RAW:
1501  break;
1502  }
1503 
1504  if (newout) {
1505  if (dofree)
1506  safe_free(out);
1507 
1508  out = newout;
1509 
1510  dofree = newfree;
1511  }
1512  }
1513 
1514  // enforce width limits if configured
1515  const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff && !doMsec && !doSec && !doUint64;
1516  if (haveMaxWidth || fmt->widthMin) {
1517  const int minWidth = fmt->widthMin >= 0 ?
1518  fmt->widthMin :0;
1519  const int maxWidth = haveMaxWidth ?
1520  fmt->widthMax : strlen(out);
1521 
1522  if (fmt->left)
1523  mb.appendf("%-*.*s", minWidth, maxWidth, out);
1524  else
1525  mb.appendf("%*.*s", minWidth, maxWidth, out);
1526  } else
1527  mb.append(out, strlen(out));
1528  } else {
1529  mb.append("-", 1);
1530  }
1531 
1532  if (fmt->space)
1533  mb.append(" ", 1);
1534 
1535  sb.clear();
1536 
1537  if (dofree)
1538  safe_free(out);
1539  }
1540 }
1541 
#define strOrNull(s)
Convert a string to NULL pointer if it is "".
Definition: Format.cc:38
static const Http::Message * actualRequestHeader(const AccessLogEntry::Pointer &al)
Definition: Format.cc:364
static void log_quoted_string(const char *str, char *out)
Definition: Format.cc:292
static const Http::Message * actualReplyHeader(const AccessLogEntry::Pointer &al)
Definition: Format.cc:350
ssize_t HttpHeaderPos
Definition: HttpHeader.h:45
#define HttpHeaderInitPos
Definition: HttpHeader.h:48
unsigned short FindListeningPortNumber(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:882
const Ip::Address * FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:873
int cur
Definition: ModDevPoll.cc:74
time_t squid_curtime
Definition: stub_libtime.cc:20
SBuf StringToSBuf(const String &s)
create a new SBuf from a String by copying contents
Definition: StringConvert.h:17
int conn
the current server connection FD
Definition: Transport.cc:26
void error(char *format,...)
#define assert(EX)
Definition: assert.h:19
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition: base64.c:232
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
Definition: base64.c:265
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
Definition: base64.c:308
#define base64_encode_len(length)
Definition: base64.h:169
char * last_meta
image of the last ICAP response header or eCAP meta received
Security::CertPointer sslClientCert
cert received from the client
struct timeval start_time
The time the master transaction started.
struct timeval trTime
The response time.
MessageSizes clientReplySz
counters for the response sent to client
MessageSizes clientRequestSz
counters for the original request received from client
AnyP::ProtocolVersion version
String reqUri
ICAP Request-URI.
String serviceName
ICAP service name.
struct timeval processingTime
total ICAP processing time
struct timeval trTime
Transaction response time. The timer starts when the ICAP transaction is created and stops when the r...
Adaptation::Icap::XactOutcome outcome
final transaction status
Ip::Address hostAddr
ICAP server IP address.
HttpReply * reply
ICAP reply.
Http::StatusCode resStatus
ICAP response status code.
int64_t bytesRead
number of bytes read from ICAP server so far
Adaptation::Icap::ICAP::Method reqMethod
ICAP request method.
struct timeval ioTime
Transaction I/O time. The timer starts when the first ICAP request byte is scheduled for sending and ...
int64_t bytesSent
number of bytes sent to ICAP server so far
HttpRequest * request
ICAP request.
int bumpMode
whether and how the request was SslBumped
const Error * error() const
void getLogClientIp(char *buf, size_t bufsz) const
HttpReplyPointer reply
SBuf getLogMethod() const
Fetch the transaction method string (ICP opcode, HTCP opcode or HTTP method)
void packReplyHeaders(MemBuf &mb) const
dump all reply headers (for sending or risky logging)
class AccessLogEntry::CacheDetails cache
bool hasLogMethod() const
whether we know what the request method is
const char * getClientIdent() const
Fetch the client IDENT string, or nil if none is available.
HierarchyLogEntry hier
class AccessLogEntry::IcapLogEntry icap
class AccessLogEntry::Headers headers
Comm::ConnectionPointer tcpClient
TCP/IP level details about the client connection.
class AccessLogEntry::HttpDetails http
HttpRequest * adapted_request
HttpRequest * request
const char * getExtUser() const
Fetch the external ACL provided 'user=' string, or nil if none is available.
SBuf lastAclData
string for external_acl_type DATA format code
const char * getLogClientFqdn(char *buf, size_t bufSize) const
class AccessLogEntry::AdaptationDetails adapt
NotePairs::Pointer notes
ProxyProtocol::HeaderPointer proxyProtocolHeader
see ConnStateData::proxyProtocolHeader_
const char * lastAclName
string for external_acl_type ACL format code
const SBuf * effectiveVirginUrl() const
class AccessLogEntry::SslDetails ssl
void sumLogString(const char *serviceId, SBuf &)
dump xaction times, merging retried and retry times together
Definition: History.cc:83
NotePairs::Pointer metaHeaders
Definition: History.h:66
HttpHeader allMeta
All REQMOD and RESPMOD meta headers merged. Last field wins conflicts.
Definition: History.h:63
RefCount< Adaptation::History > Pointer
Definition: History.h:27
void allLogString(const char *serviceId, SBuf &)
dump individual xaction times to a string
Definition: History.cc:67
unsigned int major
major version number
unsigned int minor
minor version number
SBuf image() const
Definition: UriScheme.h:50
void path(const char *p)
Definition: Uri.h:99
void port(unsigned short p)
Definition: Uri.h:94
AnyP::UriScheme const & getScheme() const
Definition: Uri.h:67
void host(const char *src)
Definition: Uri.cc:99
virtual const char * credentialsStr()=0
char const * username() const
Definition: UserRequest.cc:32
CbDataList * next
Definition: CbDataList.h:31
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:162
Cbc * valid() const
was set and is valid
Definition: CbcPointer.h:41
const Security::NegotiationHistory * hasTlsNegotiations() const
Definition: Connection.h:136
Eui::Eui64 remoteEui64
Definition: Connection.h:178
InstanceId< Connection, uint64_t > id
Definition: Connection.h:181
nfmark_t nfmark
Definition: Connection.h:161
Ip::Address remote
Definition: Connection.h:147
Ip::Address local
Definition: Connection.h:144
Eui::Eui48 remoteEui48
Definition: Connection.h:177
Ssl::ServerBump * serverBump()
Definition: client_side.h:286
SBuf preservedClientData
Definition: client_side.h:350
bool encode(char *buf, const int len) const
Definition: Eui48.cc:119
bool encode(char *buf, const int len) const
Definition: Eui64.cc:34
bool parse(const char *def)
Definition: Format.cc:66
virtual ~Format()
Definition: Format.cc:49
void assemble(MemBuf &mb, const AccessLogEntryPointer &al, int logSequenceNumber) const
assemble the state information into a formatted line.
Definition: Format.cc:377
Format(const char *name)
Definition: Format.cc:42
Format * next
Definition: Format.h:61
Token * format
Definition: Format.h:60
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
Token * next
Definition: Token.h:71
int parse(const char *def, enum Quoting *quote)
Definition: Token.cc:291
char host[SQUIDHOSTNAMELEN]
bool totalResponseTime(struct timeval &responseTime)
Definition: access_log.cc:343
int64_t bodyBytesRead
number of body bytes received from the next hop or -1
Http::StatusCode peer_reply_status
last HTTP status code received
Comm::ConnectionPointer tcpServer
TCP/IP level details of the last peer/server connection.
bool peerResponseTime(struct timeval &responseTime)
Definition: access_log.cc:316
SBuf getByNameListMember(const char *name, const char *member, const char separator) const
Definition: HttpHeader.cc:947
HttpHeaderEntry * getEntry(HttpHeaderPos *pos) const
Definition: HttpHeader.cc:588
String getByName(const SBuf &name) const
Definition: HttpHeader.cc:878
const SBuf & image() const
String extacl_log
Definition: HttpRequest.h:182
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:232
Adaptation::History::Pointer adaptHistory(bool createIfNone=false) const
Returns possibly nil history, creating it if requested.
Definition: HttpRequest.cc:405
MasterXaction::Pointer masterXaction
the master transaction this request belongs to. Never nil.
Definition: HttpRequest.h:238
HttpRequestMethod method
Definition: HttpRequest.h:114
String extacl_user
Definition: HttpRequest.h:178
int dnsWait
sum of DNS lookup delays in milliseconds, for dt
Definition: HttpRequest.h:159
String tag
Definition: HttpRequest.h:176
Auth::UserRequest::Pointer auth_user_request
Definition: HttpRequest.h:127
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
Ip::Address client_addr
Definition: HttpRequest.h:149
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
Definition: HttpRequest.cc:753
common parts of HttpRequest and HttpReply
Definition: Message.h:26
HttpHeader header
Definition: Message.h:75
AnyP::ProtocolVersion http_ver
Definition: Message.h:73
Value value
instance identifier
Definition: InstanceId.h:69
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition: Address.cc:792
bool isIPv4() const
Definition: Address.cc:158
unsigned short port() const
Definition: Address.cc:778
const char * c_str() const
compute the status access.log field
Definition: LogTags.cc:66
InstanceId< MasterXaction, uint64_t > id
transaction ID.
Definition: MasterXaction.h:60
Definition: MemBuf.h:24
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:209
void init(mb_size_t szInit, mb_size_t szMax)
Definition: MemBuf.cc:93
char * content()
start of the added data
Definition: MemBuf.h:41
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
unsigned stolen
Definition: MemBuf.h:151
uint64_t header
Definition: MessageSizes.h:21
uint64_t messageTotal() const
total message size
Definition: MessageSizes.h:27
bool empty() const
Definition: Notes.h:253
bool find(SBuf &resultNote, const char *noteKey, const char *sep=",") const
Definition: Notes.cc:272
const char * toString(const char *sep="\r\n") const
Definition: Notes.cc:286
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
C * getRaw() const
Definition: RefCount.h:80
Definition: SBuf.h:94
const char * c_str()
Definition: SBuf.cc:516
bool isEmpty() const
Definition: SBuf.h:431
const char * supportedVersion() const
const char * helloVersion() const
String representation of the received TLS hello message version.
const char * negotiatedVersion() const
String representation of TLS negotiated version.
Comm::ConnectionPointer clientConnection
Definition: Server.h:98
virtual void append(char const *, int)
Appends a c-string to existing packed data.
Definition: store.cc:778
char const * termedBuf() const
Definition: SquidString.h:92
size_type size() const
Definition: SquidString.h:73
int timedout
Definition: PingData.h:42
#define MYNAME
Definition: Stream.h:238
#define DBG_IMPORTANT
Definition: Stream.h:41
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
static int port
Definition: ldap_backend.cc:70
int type
Definition: errorpage.cc:152
#define fd_table
Definition: fde.h:189
const char * errorPageName(int pageId)
error ID to string
Definition: errorpage.cc:663
const char * sslGetUserAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:858
GETX509ATTRIBUTE GetX509UserAttribute
Definition: support.h:109
GETX509PEM GetX509PEM
Definition: support.h:115
SBuf sslGetUserCertificatePEM(SSL *ssl)
Definition: support.cc:891
GETX509ATTRIBUTE GetX509CAAttribute
Definition: support.h:112
const char * sslGetCAAttribute(SSL *ssl, const char *attribute_name)
Definition: support.cc:871
BumpMode
Definition: support.h:126
const char * bumpMode(int bm)
Definition: support.h:138
const char * hier_code_str[]
const char * quote
Definition: html_quote.c:21
@ methodRespmod
Definition: Elements.h:17
@ methodReqmod
Definition: Elements.h:17
const char * methodStr(Method)
Definition: Elements.cc:15
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
const SBuf Dash
ByteCode_t
Definition: ByteCode.h:30
@ LFT_REPLY_HEADER
Definition: ByteCode.h:129
@ LFT_ICAP_REP_ALL_HEADERS
Definition: ByteCode.h:208
@ LFT_REQUEST_VERSION_OLD_2X
Definition: ByteCode.h:85
@ LFT_TLS_SERVER_NEGOTIATED_VERSION
Definition: ByteCode.h:227
@ LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME
Definition: ByteCode.h:167
@ LFT_SERVER_REQ_URLPORT
Definition: ByteCode.h:104
@ LFT_CLIENT_REQ_METHOD
Definition: ByteCode.h:71
@ LFT_EXT_ACL_USER_CA_CERT
Definition: ByteCode.h:245
@ LFT_ICAP_REQUEST_URI
Definition: ByteCode.h:196
@ LFT_SSL_SERVER_CERT_ERRORS
Definition: ByteCode.h:224
@ LFT_CLIENT_HANDSHAKE
Definition: ByteCode.h:51
@ LFT_CLIENT_IP_ADDRESS
Definition: ByteCode.h:37
@ LFT_CLIENT_REQ_URLSCHEME
Definition: ByteCode.h:73
@ LFT_CLIENT_REQUEST_SIZE_HEADERS
Definition: ByteCode.h:111
@ LFT_SERVER_LOCAL_NFMARK
Definition: ByteCode.h:68
@ LFT_CLIENT_FQDN
Definition: ByteCode.h:38
@ LFT_SERVER_LOCAL_IP_OLD_27
Definition: ByteCode.h:65
@ LFT_REQUEST_HEADER_ELEM
Definition: ByteCode.h:91
@ LFT_REPLY_HIGHOFFSET
Definition: ByteCode.h:140
@ LFT_TIME_TO_HANDLE_REQUEST
Definition: ByteCode.h:165
@ LFT_MIME_TYPE
Definition: ByteCode.h:176
@ LFT_SSL_BUMP_MODE
Definition: ByteCode.h:218
@ LFT_TLS_SERVER_NEGOTIATED_CIPHER
Definition: ByteCode.h:229
@ LFT_SERVER_LOCAL_TOS
Definition: ByteCode.h:67
@ LFT_EXT_ACL_CLIENT_EUI48
Definition: ByteCode.h:247
@ LFT_USER_LOGIN
Definition: ByteCode.h:150
@ LFT_PERCENT
Definition: ByteCode.h:237
@ LFT_REQUEST_VERSION
Definition: ByteCode.h:86
@ LFT_ICAP_TR_RESPONSE_TIME
Definition: ByteCode.h:210
@ LFT_HTTP_SENT_STATUS_CODE_OLD_30
Definition: ByteCode.h:122
@ LFT_CLIENT_PORT
Definition: ByteCode.h:39
@ LFT_REPLY_ALL_HEADERS
Definition: ByteCode.h:131
@ LFT_CLIENT_LOCAL_NFMARK
Definition: ByteCode.h:47
@ LFT_ICAP_REQ_ALL_HEADERS
Definition: ByteCode.h:204
@ LFT_SERVER_REQ_URI
Definition: ByteCode.h:101
@ LFT_TRANSPORT_CLIENT_CONNECTION_ID
Definition: ByteCode.h:49
@ LFT_EXT_ACL_USER_CERT_RAW
Definition: ByteCode.h:242
@ LFT_REQUEST_ALL_HEADERS
Definition: ByteCode.h:92
@ LFT_SSL_SERVER_CERT_SUBJECT
Definition: ByteCode.h:222
@ LFT_ADAPTED_REQUEST_ALL_HEADERS
Definition: ByteCode.h:97
@ LFT_ICAP_ADDR
Definition: ByteCode.h:194
@ LFT_USER_NAME
Definition: ByteCode.h:149
@ LFT_NONE
Definition: ByteCode.h:31
@ LFT_SERVER_LOCAL_IP
Definition: ByteCode.h:64
@ LFT_CLIENT_IO_SIZE_TOTAL
Definition: ByteCode.h:146
@ LFT_ICAP_TOTAL_TIME
Definition: ByteCode.h:192
@ LFT_SERVER_PORT
Definition: ByteCode.h:61
@ LFT_REQUEST_HEADER
Definition: ByteCode.h:90
@ LFT_ICAP_REQ_HEADER
Definition: ByteCode.h:202
@ LFT_EXT_ACL_DATA
Definition: ByteCode.h:250
@ LFT_TIME_START
Definition: ByteCode.h:162
@ LFT_SQUID_HIERARCHY
Definition: ByteCode.h:174
@ LFT_ICAP_BYTES_READ
Definition: ByteCode.h:199
@ LFT_SERVER_REQ_URLSCHEME
Definition: ByteCode.h:102
@ LFT_SSL_SERVER_CERT_ISSUER
Definition: ByteCode.h:223
@ LFT_CLIENT_REQ_URLPATH
Definition: ByteCode.h:76
@ LFT_SEQUENCE_NUMBER
Definition: ByteCode.h:180
@ LFT_PROXY_PROTOCOL_RECEIVED_ALL_HEADERS
Definition: ByteCode.h:255
@ LFT_TLS_SERVER_SUPPORTED_VERSION
Definition: ByteCode.h:233
@ LFT_SQUID_ERROR_DETAIL
Definition: ByteCode.h:173
@ LFT_HTTP_BODY_BYTES_READ
Definition: ByteCode.h:126
@ LFT_USER_IDENT
Definition: ByteCode.h:151
@ LFT_EXT_ACL_CLIENT_EUI64
Definition: ByteCode.h:248
@ LFT_CLIENT_LOCAL_TOS
Definition: ByteCode.h:46
@ LFT_TLS_CLIENT_NEGOTIATED_CIPHER
Definition: ByteCode.h:228
@ LFT_TIME_SECONDS_SINCE_EPOCH
Definition: ByteCode.h:158
@ LFT_TIME_SUBSECOND
Definition: ByteCode.h:159
@ LFT_NOTE
Definition: ByteCode.h:236
@ LFT_ADAPTATION_SUM_XACT_TIMES
Definition: ByteCode.h:183
@ LFT_SERVER_IP_ADDRESS
Definition: ByteCode.h:59
@ LFT_PEER_RESPONSE_TIME
Definition: ByteCode.h:166
@ LFT_LOCAL_LISTENING_IP
Definition: ByteCode.h:54
@ LFT_TIME_GMT
Definition: ByteCode.h:161
@ LFT_CLIENT_REQ_URLDOMAIN
Definition: ByteCode.h:74
@ LFT_REQUEST_METHOD
Definition: ByteCode.h:81
@ LFT_CLIENT_REQUEST_SIZE_TOTAL
Definition: ByteCode.h:110
@ LFT_SERVER_LOCAL_PORT
Definition: ByteCode.h:66
@ LFT_ICAP_IO_TIME
Definition: ByteCode.h:211
@ LFT_REPLY_OBJECTSIZE
Definition: ByteCode.h:141
@ LFT_HTTP_SENT_STATUS_CODE
Definition: ByteCode.h:123
@ LFT_TAG
Definition: ByteCode.h:177
@ LFT_REQUEST_URI
Definition: ByteCode.h:82
@ LFT_SERVER_REQ_URLDOMAIN
Definition: ByteCode.h:103
@ LFT_ADAPTED_REPLY_SIZE_HEADERS
Definition: ByteCode.h:142
@ LFT_CLIENT_LOCAL_PORT
Definition: ByteCode.h:44
@ LFT_SSL_USER_CERT_SUBJECT
Definition: ByteCode.h:219
@ LFT_ADAPTATION_LAST_HEADER
Definition: ByteCode.h:185
@ LFT_EXT_LOG
Definition: ByteCode.h:178
@ LFT_STRING
Definition: ByteCode.h:34
@ LFT_CLIENT_REQ_URLPORT
Definition: ByteCode.h:75
@ LFT_ADAPTED_REPLY_SIZE_TOTAL
Definition: ByteCode.h:139
@ LFT_PROXY_PROTOCOL_RECEIVED_HEADER
Definition: ByteCode.h:253
@ LFT_SQUID_ERROR
Definition: ByteCode.h:172
@ LFT_ADAPTATION_LAST_ALL_HEADERS
Definition: ByteCode.h:187
@ LFT_SSL_USER_CERT_ISSUER
Definition: ByteCode.h:220
@ LFT_TLS_CLIENT_NEGOTIATED_VERSION
Definition: ByteCode.h:226
@ LFT_TLS_CLIENT_RECEIVED_HELLO_VERSION
Definition: ByteCode.h:230
@ LFT_ICAP_REP_HEADER_ELEM
Definition: ByteCode.h:207
@ LFT_EXT_ACL_NAME
Definition: ByteCode.h:249
@ LFT_ADAPTED_REQUEST_HEADER
Definition: ByteCode.h:95
@ LFT_REPLY_HEADER_ELEM
Definition: ByteCode.h:130
@ LFT_LOCAL_LISTENING_PORT
Definition: ByteCode.h:55
@ LFT_CLIENT_REQ_VERSION
Definition: ByteCode.h:78
@ LFT_ADAPTATION_LAST_HEADER_ELEM
Definition: ByteCode.h:186
@ LFT_ADAPTATION_ALL_XACT_TIMES
Definition: ByteCode.h:184
@ LFT_CREDENTIALS
Definition: ByteCode.h:215
@ LFT_REQUEST_URLPATH_OLD_31
Definition: ByteCode.h:83
@ LFT_CLIENT_EUI
Definition: ByteCode.h:40
@ LFT_ICAP_REP_HEADER
Definition: ByteCode.h:206
@ LFT_USER_EXTERNAL
Definition: ByteCode.h:154
@ LFT_SERVER_REQ_URLPATH
Definition: ByteCode.h:105
@ LFT_TLS_CLIENT_SUPPORTED_VERSION
Definition: ByteCode.h:232
@ LFT_SERVER_FQDN_OR_PEER_NAME
Definition: ByteCode.h:60
@ LFT_DNS_WAIT_TIME
Definition: ByteCode.h:168
@ LFT_ADAPTED_REQUEST_HEADER_ELEM
Definition: ByteCode.h:96
@ LFT_ICAP_SERV_NAME
Definition: ByteCode.h:195
@ LFT_CLIENT_LOCAL_IP
Definition: ByteCode.h:43
@ LFT_SSL_SERVER_CERT_WHOLE
Definition: ByteCode.h:225
@ LFT_PROXY_PROTOCOL_RECEIVED_HEADER_ELEM
Definition: ByteCode.h:254
@ LFT_TIME_LOCALTIME
Definition: ByteCode.h:160
@ LFT_ICAP_BYTES_SENT
Definition: ByteCode.h:198
@ LFT_ICAP_OUTCOME
Definition: ByteCode.h:212
@ LFT_CLIENT_REQ_URI
Definition: ByteCode.h:72
@ LFT_ICAP_STATUS_CODE
Definition: ByteCode.h:213
@ LFT_SERVER_REQ_VERSION
Definition: ByteCode.h:107
@ LFT_ICAP_REQUEST_METHOD
Definition: ByteCode.h:197
@ LFT_HTTP_RECEIVED_STATUS_CODE
Definition: ByteCode.h:124
@ LFT_SQUID_STATUS
Definition: ByteCode.h:171
@ LFT_ICAP_REQ_HEADER_ELEM
Definition: ByteCode.h:203
@ LFT_SSL_CLIENT_SNI
Definition: ByteCode.h:221
@ LFT_TLS_SERVER_RECEIVED_HELLO_VERSION
Definition: ByteCode.h:231
@ LFT_MASTER_XACTION
Definition: ByteCode.h:238
@ LFT_EXT_ACL_USER_CERTCHAIN_RAW
Definition: ByteCode.h:243
@ LFT_EXT_ACL_USER_CERT
Definition: ByteCode.h:244
@ LFT_SERVER_REQ_METHOD
Definition: ByteCode.h:100
@ LFT_ICAP_BODY_BYTES_READ
Definition: ByteCode.h:200
@ LFT_REQUEST_URLGROUP_OLD_2X
Definition: ByteCode.h:87
size_t AssembleOne(const char *start, MemBuf &buf, const AccessLogEntryPointer &ale)
Definition: Format.cc:99
char * QuoteMimeBlob(const char *header)
Definition: Quoting.cc:43
Quoting
Quoting style for a format output.
Definition: ByteCode.h:259
@ LOG_QUOTE_MIMEBLOB
Definition: ByteCode.h:262
@ LOG_QUOTE_URL
Definition: ByteCode.h:263
@ LOG_QUOTE_RAW
Definition: ByteCode.h:265
@ LOG_QUOTE_SHELL
Definition: ByteCode.h:264
@ LOG_QUOTE_NONE
Definition: ByteCode.h:260
@ LOG_QUOTE_QUOTES
Definition: ByteCode.h:261
@ scNone
Definition: StatusCode.h:21
SBuf IssuerName(Certificate &)
The Issuer field of the given certificate (if found) or an empty SBuf.
Definition: Certificate.cc:28
SBuf SubjectName(Certificate &)
The SubjectName field of the given certificate (if found) or an empty SBuf.
Definition: Certificate.cc:68
const char * GetErrorName(const Security::ErrorCode code, const bool prefixRawCode=false)
Definition: ErrorDetail.h:36
#define xfree
#define xstrdup
#define xmalloc
#define rfc1738_escape(x)
Definition: rfc1738.h:52
#define rfc1738_escape_unescaped(x)
Definition: rfc1738.h:59
static struct stat sb
Definition: squidclient.cc:71
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:830
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
Definition: gadgets.cc:17
long int tvToMsec(struct timeval &t)
Definition: gadgets.h:93
void strwordquote(MemBuf *mb, const char *str)
Definition: tools.cc:1077
#define PRIu64
Definition: types.h:120
#define PRId64
Definition: types.h:110
#define safe_free(x)
Definition: xalloc.h:73

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors