2 #include "AccessLogEntry.h"
3 #include "client_side.h"
4 #include "comm/Connection.h"
5 #include "err_detail_type.h"
8 #include "format/Format.h"
9 #include "format/Quoting.h"
10 #include "format/Token.h"
11 #include "fqdncache.h"
12 #include "HttpRequest.h"
15 #include "SquidTime.h"
19 #include "ssl/ErrorDetail.h"
22 /// Convert a string to NULL pointer if it is ""
23 #define strOrNull(s) ((s)==NULL||(s)[0]=='\0'?NULL:(s))
25 Format::Format::Format(const char *n
) :
32 Format::Format::~Format()
34 // erase the list without consuming stack space
36 // unlink the next entry for deletion
49 Format::Format::parse(const char *def
)
51 const char *cur
, *eos
;
52 Token
*new_lt
, *last_lt
;
53 enum Quoting quote
= LOG_QUOTE_NONE
;
55 debugs(46, 2, HERE
<< "got definition '" << def
<< "'");
58 debugs(46, DBG_IMPORTANT
, "WARNING: existing format for '" << name
<< " " << def
<< "'");
62 /* very inefficent parser, but who cares, this needs to be simple */
63 /* First off, let's tokenize, we'll optimize in a second pass.
64 * A token can either be a %-prefixed sequence (usually a dynamic
65 * token but it can be an escaped sequence), or a string. */
67 eos
= def
+ strlen(def
);
68 format
= new_lt
= last_lt
= new Token
;
69 cur
+= new_lt
->parse(cur
, "e
);
73 last_lt
->next
= new_lt
;
75 cur
+= new_lt
->parse(cur
, "e
);
82 Format::Format::dump(StoreEntry
* entry
, const char *directiveName
)
86 // loop rather than recursing to conserve stack space.
87 for (Format
*fmt
= this; fmt
; fmt
= fmt
->next
) {
88 debugs(46, 3, HERE
<< "Dumping format definition for " << fmt
->name
);
89 storeAppendPrintf(entry
, "%s %s ", directiveName
, fmt
->name
);
91 for (Token
*t
= fmt
->format
; t
; t
= t
->next
) {
92 if (t
->type
== LFT_STRING
)
93 storeAppendPrintf(entry
, "%s", t
->data
.string
);
97 ByteCode_t type
= t
->type
;
105 case LFT_ADAPTATION_LAST_HEADER_ELEM
:
108 case LFT_ICAP_REQ_HEADER_ELEM
:
109 case LFT_ICAP_REP_HEADER_ELEM
:
111 case LFT_REQUEST_HEADER_ELEM
:
112 case LFT_ADAPTED_REQUEST_HEADER_ELEM
:
113 case LFT_REPLY_HEADER_ELEM
:
115 if (t
->data
.header
.separator
!= ',')
116 snprintf(argbuf
, sizeof(argbuf
), "%s:%c%s", t
->data
.header
.header
, t
->data
.header
.separator
, t
->data
.header
.element
);
118 snprintf(argbuf
, sizeof(argbuf
), "%s:%s", t
->data
.header
.header
, t
->data
.header
.element
);
123 case LFT_REQUEST_HEADER_ELEM
:
124 type
= LFT_REQUEST_HEADER_ELEM
; // XXX: remove _ELEM?
126 case LFT_ADAPTED_REQUEST_HEADER_ELEM
:
127 type
= LFT_ADAPTED_REQUEST_HEADER_ELEM
; // XXX: remove _ELEM?
129 case LFT_REPLY_HEADER_ELEM
:
130 type
= LFT_REPLY_HEADER_ELEM
; // XXX: remove _ELEM?
133 case LFT_ADAPTATION_LAST_HEADER_ELEM
:
134 type
= LFT_ADAPTATION_LAST_HEADER
;
138 case LFT_ICAP_REQ_HEADER_ELEM
:
139 type
= LFT_ICAP_REQ_HEADER
;
141 case LFT_ICAP_REP_HEADER_ELEM
:
142 type
= LFT_ICAP_REP_HEADER
;
151 case LFT_REQUEST_ALL_HEADERS
:
152 case LFT_ADAPTED_REQUEST_ALL_HEADERS
:
153 case LFT_REPLY_ALL_HEADERS
:
156 case LFT_ADAPTATION_LAST_ALL_HEADERS
:
159 case LFT_ICAP_REQ_ALL_HEADERS
:
160 case LFT_ICAP_REP_ALL_HEADERS
:
164 case LFT_REQUEST_ALL_HEADERS
:
165 type
= LFT_REQUEST_HEADER
;
167 case LFT_ADAPTED_REQUEST_ALL_HEADERS
:
168 type
= LFT_ADAPTED_REQUEST_HEADER
;
170 case LFT_REPLY_ALL_HEADERS
:
171 type
= LFT_REPLY_HEADER
;
174 case LFT_ADAPTATION_LAST_ALL_HEADERS
:
175 type
= LFT_ADAPTATION_LAST_HEADER
;
179 case LFT_ICAP_REQ_ALL_HEADERS
:
180 type
= LFT_ICAP_REQ_HEADER
;
182 case LFT_ICAP_REP_ALL_HEADERS
:
183 type
= LFT_ICAP_REP_HEADER
;
194 arg
= t
->data
.string
;
199 entry
->append("%", 1);
203 case LOG_QUOTE_QUOTES
:
204 entry
->append("\"", 1);
207 case LOG_QUOTE_MIMEBLOB
:
208 entry
->append("[", 1);
212 entry
->append("#", 1);
216 entry
->append("'", 1);
224 entry
->append("-", 1);
227 entry
->append("0", 1);
229 if (t
->widthMin
>= 0)
230 storeAppendPrintf(entry
, "%d", t
->widthMin
);
232 if (t
->widthMax
>= 0)
233 storeAppendPrintf(entry
, ".%d", t
->widthMax
);
236 storeAppendPrintf(entry
, "{%s}", arg
);
238 storeAppendPrintf(entry
, "%s", t
->label
);
241 entry
->append(" ", 1);
245 entry
->append("\n", 1);
251 log_quoted_string(const char *str
, char *out
)
256 int l
= strcspn(str
, "\"\\\r\n\t");
304 Format::Format::assemble(MemBuf
&mb
, const AccessLogEntry::Pointer
&al
, int logSequenceNumber
) const
309 for (Token
*fmt
= format
; fmt
!= NULL
; fmt
= fmt
->next
) { /* for each token */
310 const char *out
= NULL
;
325 out
= fmt
->data
.string
;
328 case LFT_CLIENT_IP_ADDRESS
:
329 al
->getLogClientIp(tmp
, sizeof(tmp
));
333 case LFT_CLIENT_FQDN
:
334 if (al
->cache
.caddr
.isAnyAddr()) // e.g., ICAP OPTIONS lack client
337 out
= fqdncache_gethostbyaddr(al
->cache
.caddr
, FQDN_LOOKUP_IF_MISS
);
339 out
= al
->cache
.caddr
.toStr(tmp
,1024);
344 case LFT_CLIENT_PORT
:
346 outint
= al
->request
->client_addr
.port();
353 // TODO make the ACL checklist have a direct link to any TCP details.
354 if (al
->request
&& al
->request
->clientConnectionManager
.valid() && al
->request
->clientConnectionManager
->clientConnection
!= NULL
) {
355 if (al
->request
->clientConnectionManager
->clientConnection
->remote
.isIPv4())
356 al
->request
->clientConnectionManager
->clientConnection
->remoteEui48
.encode(tmp
, 1024);
358 al
->request
->clientConnectionManager
->clientConnection
->remoteEui64
.encode(tmp
, 1024);
366 case LFT_SERVER_IP_ADDRESS
:
367 if (al
->hier
.tcpServer
!= NULL
) {
368 out
= al
->hier
.tcpServer
->remote
.toStr(tmp
,sizeof(tmp
));
372 case LFT_SERVER_FQDN_OR_PEER_NAME
:
376 case LFT_SERVER_PORT
:
377 if (al
->hier
.tcpServer
!= NULL
) {
378 outint
= al
->hier
.tcpServer
->remote
.port();
383 case LFT_LOCAL_LISTENING_IP
: {
384 // avoid logging a dash if we have reliable info
385 const bool interceptedAtKnownPort
= al
->request
?
386 (al
->request
->flags
.interceptTproxy
||
387 al
->request
->flags
.intercepted
) && al
->cache
.port
:
389 if (interceptedAtKnownPort
) {
390 const bool portAddressConfigured
= !al
->cache
.port
->s
.isAnyAddr();
391 if (portAddressConfigured
)
392 out
= al
->cache
.port
->s
.toStr(tmp
, sizeof(tmp
));
393 } else if (al
->tcpClient
!= NULL
)
394 out
= al
->tcpClient
->local
.toStr(tmp
, sizeof(tmp
));
398 case LFT_CLIENT_LOCAL_IP
:
399 if (al
->tcpClient
!= NULL
) {
400 out
= al
->tcpClient
->local
.toStr(tmp
,sizeof(tmp
));
404 case LFT_CLIENT_LOCAL_TOS
:
405 if (al
->tcpClient
!= NULL
) {
406 snprintf(tmp
, sizeof(tmp
), "0x%x", (uint32_t)al
->tcpClient
->tos
);
411 case LFT_CLIENT_LOCAL_NFMARK
:
412 if (al
->tcpClient
!= NULL
) {
413 snprintf(tmp
, sizeof(tmp
), "0x%x", al
->tcpClient
->nfmark
);
418 case LFT_LOCAL_LISTENING_PORT
:
419 if (al
->cache
.port
) {
420 outint
= al
->cache
.port
->s
.port();
425 case LFT_CLIENT_LOCAL_PORT
:
426 if (al
->tcpClient
!= NULL
) {
427 outint
= al
->tcpClient
->local
.port();
432 case LFT_SERVER_LOCAL_IP_OLD_27
:
433 case LFT_SERVER_LOCAL_IP
:
434 if (al
->hier
.tcpServer
!= NULL
) {
435 out
= al
->hier
.tcpServer
->local
.toStr(tmp
,sizeof(tmp
));
439 case LFT_SERVER_LOCAL_PORT
:
440 if (al
->hier
.tcpServer
!= NULL
) {
441 outint
= al
->hier
.tcpServer
->local
.port();
447 case LFT_SERVER_LOCAL_TOS
:
448 if (al
->hier
.tcpServer
!= NULL
) {
449 snprintf(tmp
, sizeof(tmp
), "0x%x", (uint32_t)al
->hier
.tcpServer
->tos
);
454 case LFT_SERVER_LOCAL_NFMARK
:
455 if (al
->hier
.tcpServer
!= NULL
) {
456 snprintf(tmp
, sizeof(tmp
), "0x%x", al
->hier
.tcpServer
->nfmark
);
461 case LFT_TIME_SECONDS_SINCE_EPOCH
:
462 // some platforms store time in 32-bit, some 64-bit...
463 outoff
= static_cast<int64_t>(current_time
.tv_sec
);
467 case LFT_TIME_SUBSECOND
:
468 outint
= current_time
.tv_usec
/ fmt
->divisor
;
472 case LFT_TIME_LOCALTIME
:
478 spec
= fmt
->data
.timespec
;
480 if (fmt
->type
== LFT_TIME_LOCALTIME
) {
482 spec
= "%d/%b/%Y:%H:%M:%S %z";
483 t
= localtime(&squid_curtime
);
486 spec
= "%d/%b/%Y:%H:%M:%S";
488 t
= gmtime(&squid_curtime
);
491 strftime(tmp
, sizeof(tmp
), spec
, t
);
498 case LFT_TIME_START
: {
499 int precision
= fmt
->widthMax
>=0 ? fmt
->widthMax
: 3;
500 snprintf(tmp
, sizeof(tmp
), "%0*" PRId64
".%0*d", fmt
->zero
&& (fmt
->widthMin
- precision
- 1 >= 0) ? fmt
->widthMin
- precision
- 1 : 0, al
->cache
.start_time
.tv_sec
, precision
, (int)(al
->cache
.start_time
.tv_usec
/ fmt
->divisor
));
505 case LFT_TIME_TO_HANDLE_REQUEST
:
506 outint
= al
->cache
.msec
;
510 case LFT_PEER_RESPONSE_TIME
:
511 if (al
->hier
.peer_response_time
< 0) {
514 outoff
= al
->hier
.peer_response_time
;
519 case LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME
:
520 if (al
->hier
.total_response_time
< 0) {
523 outoff
= al
->hier
.total_response_time
;
528 case LFT_DNS_WAIT_TIME
:
529 if (al
->request
&& al
->request
->dnsWait
>= 0) {
530 outint
= al
->request
->dnsWait
;
535 case LFT_REQUEST_HEADER
:
538 sb
= al
->request
->header
.getByName(fmt
->data
.header
.header
);
540 out
= sb
.termedBuf();
546 case LFT_ADAPTED_REQUEST_HEADER
:
548 if (al
->adapted_request
)
549 sb
= al
->adapted_request
->header
.getByName(fmt
->data
.header
.header
);
551 out
= sb
.termedBuf();
557 case LFT_REPLY_HEADER
:
559 sb
= al
->reply
->header
.getByName(fmt
->data
.header
.header
);
561 out
= sb
.termedBuf();
568 case LFT_ADAPTATION_SUM_XACT_TIMES
:
570 Adaptation::History::Pointer ah
= al
->request
->adaptHistory();
572 ah
->sumLogString(fmt
->data
.string
, sb
);
573 out
= sb
.termedBuf();
577 case LFT_ADAPTATION_ALL_XACT_TIMES
:
579 Adaptation::History::Pointer ah
= al
->request
->adaptHistory();
581 ah
->allLogString(fmt
->data
.string
, sb
);
582 out
= sb
.termedBuf();
586 case LFT_ADAPTATION_LAST_HEADER
:
588 const Adaptation::History::Pointer ah
= al
->request
->adaptHistory();
589 if (ah
!= NULL
) // XXX: add adapt::<all_h but use lastMeta here
590 sb
= ah
->allMeta
.getByName(fmt
->data
.header
.header
);
593 // XXX: here and elsewhere: move such code inside the if guard
594 out
= sb
.termedBuf();
600 case LFT_ADAPTATION_LAST_HEADER_ELEM
:
602 const Adaptation::History::Pointer ah
= al
->request
->adaptHistory();
603 if (ah
!= NULL
) // XXX: add adapt::<all_h but use lastMeta here
604 sb
= ah
->allMeta
.getByNameListMember(fmt
->data
.header
.header
, fmt
->data
.header
.element
, fmt
->data
.header
.separator
);
607 out
= sb
.termedBuf();
613 case LFT_ADAPTATION_LAST_ALL_HEADERS
:
614 out
= al
->adapt
.last_meta
;
624 out
= al
->icap
.hostAddr
.toStr(tmp
,1024);
627 case LFT_ICAP_SERV_NAME
:
628 out
= al
->icap
.serviceName
.termedBuf();
631 case LFT_ICAP_REQUEST_URI
:
632 out
= al
->icap
.reqUri
.termedBuf();
635 case LFT_ICAP_REQUEST_METHOD
:
636 out
= Adaptation::Icap::ICAP::methodStr(al
->icap
.reqMethod
);
639 case LFT_ICAP_BYTES_SENT
:
640 outoff
= al
->icap
.bytesSent
;
644 case LFT_ICAP_BYTES_READ
:
645 outoff
= al
->icap
.bytesRead
;
649 case LFT_ICAP_BODY_BYTES_READ
:
650 if (al
->icap
.bodyBytesRead
>= 0) {
651 outoff
= al
->icap
.bodyBytesRead
;
654 // else if icap.bodyBytesRead < 0, we do not have any http data,
655 // so just print a "-" (204 responses etc)
658 case LFT_ICAP_REQ_HEADER
:
659 if (NULL
!= al
->icap
.request
) {
660 sb
= al
->icap
.request
->header
.getByName(fmt
->data
.header
.header
);
661 out
= sb
.termedBuf();
666 case LFT_ICAP_REQ_HEADER_ELEM
:
667 if (al
->icap
.request
)
668 sb
= al
->icap
.request
->header
.getByNameListMember(fmt
->data
.header
.header
, fmt
->data
.header
.element
, fmt
->data
.header
.separator
);
670 out
= sb
.termedBuf();
676 case LFT_ICAP_REQ_ALL_HEADERS
:
677 if (al
->icap
.request
) {
678 HttpHeaderPos pos
= HttpHeaderInitPos
;
679 while (const HttpHeaderEntry
*e
= al
->icap
.request
->header
.getEntry(&pos
)) {
685 out
= sb
.termedBuf();
690 case LFT_ICAP_REP_HEADER
:
691 if (NULL
!= al
->icap
.reply
) {
692 sb
= al
->icap
.reply
->header
.getByName(fmt
->data
.header
.header
);
693 out
= sb
.termedBuf();
698 case LFT_ICAP_REP_HEADER_ELEM
:
699 if (NULL
!= al
->icap
.reply
)
700 sb
= al
->icap
.reply
->header
.getByNameListMember(fmt
->data
.header
.header
, fmt
->data
.header
.element
, fmt
->data
.header
.separator
);
702 out
= sb
.termedBuf();
708 case LFT_ICAP_REP_ALL_HEADERS
:
709 if (al
->icap
.reply
) {
710 HttpHeaderPos pos
= HttpHeaderInitPos
;
711 while (const HttpHeaderEntry
*e
= al
->icap
.reply
->header
.getEntry(&pos
)) {
717 out
= sb
.termedBuf();
722 case LFT_ICAP_TR_RESPONSE_TIME
:
723 outint
= al
->icap
.trTime
;
727 case LFT_ICAP_IO_TIME
:
728 outint
= al
->icap
.ioTime
;
732 case LFT_ICAP_STATUS_CODE
:
733 outint
= al
->icap
.resStatus
;
737 case LFT_ICAP_OUTCOME
:
738 out
= al
->icap
.outcome
;
741 case LFT_ICAP_TOTAL_TIME
:
742 outint
= al
->icap
.processingTime
;
746 case LFT_REQUEST_HEADER_ELEM
:
748 sb
= al
->request
->header
.getByNameListMember(fmt
->data
.header
.header
, fmt
->data
.header
.element
, fmt
->data
.header
.separator
);
750 out
= sb
.termedBuf();
756 case LFT_ADAPTED_REQUEST_HEADER_ELEM
:
757 if (al
->adapted_request
)
758 sb
= al
->adapted_request
->header
.getByNameListMember(fmt
->data
.header
.header
, fmt
->data
.header
.element
, fmt
->data
.header
.separator
);
760 out
= sb
.termedBuf();
766 case LFT_REPLY_HEADER_ELEM
:
768 sb
= al
->reply
->header
.getByNameListMember(fmt
->data
.header
.header
, fmt
->data
.header
.element
, fmt
->data
.header
.separator
);
770 out
= sb
.termedBuf();
776 case LFT_REQUEST_ALL_HEADERS
:
777 out
= al
->headers
.request
;
783 case LFT_ADAPTED_REQUEST_ALL_HEADERS
:
784 out
= al
->headers
.adapted_request
;
790 case LFT_REPLY_ALL_HEADERS
:
791 out
= al
->headers
.reply
;
799 if (al
->request
&& al
->request
->auth_user_request
!= NULL
)
800 out
= strOrNull(al
->request
->auth_user_request
->username());
803 out
= strOrNull(al
->cache
.extuser
);
806 out
= strOrNull(al
->cache
.ssluser
);
809 out
= strOrNull(al
->cache
.rfc931
);
814 if (al
->request
&& al
->request
->auth_user_request
!= NULL
)
815 out
= strOrNull(al
->request
->auth_user_request
->username());
820 out
= strOrNull(al
->cache
.rfc931
);
823 case LFT_USER_EXTERNAL
:
824 out
= strOrNull(al
->cache
.extuser
);
827 /* case LFT_USER_REALM: */
828 /* case LFT_USER_SCHEME: */
830 // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
831 // but compiler complains if ommited
832 case LFT_HTTP_SENT_STATUS_CODE_OLD_30
:
833 case LFT_HTTP_SENT_STATUS_CODE
:
834 outint
= al
->http
.code
;
840 case LFT_HTTP_RECEIVED_STATUS_CODE
:
841 if (al
->hier
.peer_reply_status
== Http::scNone
) {
844 outint
= al
->hier
.peer_reply_status
;
848 /* case LFT_HTTP_STATUS:
849 * out = statusline->text;
853 case LFT_HTTP_BODY_BYTES_READ
:
854 if (al
->hier
.bodyBytesRead
>= 0) {
855 outoff
= al
->hier
.bodyBytesRead
;
858 // else if hier.bodyBytesRead < 0 we did not have any data exchange with
859 // a peer server so just print a "-" (eg requests served from cache,
860 // or internal error messages).
863 case LFT_SQUID_STATUS
:
864 if (al
->http
.timedout
|| al
->http
.aborted
) {
865 snprintf(tmp
, sizeof(tmp
), "%s%s", LogTags_str
[al
->cache
.code
],
866 al
->http
.statusSfx());
869 out
= LogTags_str
[al
->cache
.code
];
874 case LFT_SQUID_ERROR
:
875 if (al
->request
&& al
->request
->errType
!= ERR_NONE
)
876 out
= errorPageName(al
->request
->errType
);
879 case LFT_SQUID_ERROR_DETAIL
:
881 if (al
->request
&& al
->request
->errType
== ERR_SECURE_CONNECT_FAIL
) {
882 if (! (out
= Ssl::GetErrorName(al
->request
->errDetail
))) {
883 snprintf(tmp
, sizeof(tmp
), "SSL_ERR=%d", al
->request
->errDetail
);
888 if (al
->request
&& al
->request
->errDetail
!= ERR_DETAIL_NONE
) {
889 if (al
->request
->errDetail
> ERR_DETAIL_START
&&
890 al
->request
->errDetail
< ERR_DETAIL_MAX
)
891 out
= errorDetailName(al
->request
->errDetail
);
893 if (al
->request
->errDetail
>= ERR_DETAIL_EXCEPTION_START
)
894 snprintf(tmp
, sizeof(tmp
), "%s=0x%X",
895 errorDetailName(al
->request
->errDetail
), (uint32_t) al
->request
->errDetail
);
897 snprintf(tmp
, sizeof(tmp
), "%s=%d",
898 errorDetailName(al
->request
->errDetail
), al
->request
->errDetail
);
904 case LFT_SQUID_HIERARCHY
:
905 if (al
->hier
.ping
.timedout
)
906 mb
.append("TIMEOUT_", 8);
908 out
= hier_code_str
[al
->hier
.code
];
913 out
= al
->http
.content_type
;
917 case LFT_CLIENT_REQ_METHOD
:
919 out
= al
->request
->method
.image();
924 case LFT_CLIENT_REQ_URI
:
925 // original client URI
927 out
= urlCanonical(al
->request
);
932 case LFT_REQUEST_URLPATH_OLD_31
:
933 case LFT_CLIENT_REQ_URLPATH
:
935 out
= al
->request
->urlpath
.termedBuf();
940 case LFT_CLIENT_REQ_VERSION
:
942 snprintf(tmp
, sizeof(tmp
), "%d.%d", (int) al
->request
->http_ver
.major
, (int) al
->request
->http_ver
.minor
);
947 case LFT_REQUEST_METHOD
:
948 out
= al
->_private
.method_str
;
951 case LFT_REQUEST_URI
:
955 case LFT_REQUEST_VERSION_OLD_2X
:
956 case LFT_REQUEST_VERSION
:
957 snprintf(tmp
, sizeof(tmp
), "%d.%d", (int) al
->http
.version
.major
, (int) al
->http
.version
.minor
);
961 case LFT_SERVER_REQ_METHOD
:
962 if (al
->adapted_request
) {
963 out
= al
->adapted_request
->method
.image();
968 case LFT_SERVER_REQ_URI
:
969 // adapted request URI sent to server/peer
970 if (al
->adapted_request
) {
971 out
= urlCanonical(al
->adapted_request
);
976 case LFT_SERVER_REQ_URLPATH
:
977 if (al
->adapted_request
) {
978 out
= al
->adapted_request
->urlpath
.termedBuf();
983 case LFT_SERVER_REQ_VERSION
:
984 if (al
->adapted_request
) {
985 snprintf(tmp
, sizeof(tmp
), "%d.%d",
986 (int) al
->adapted_request
->http_ver
.major
,
987 (int) al
->adapted_request
->http_ver
.minor
);
992 case LFT_CLIENT_REQUEST_SIZE_TOTAL
:
993 outoff
= al
->http
.clientRequestSz
.messageTotal();
997 case LFT_CLIENT_REQUEST_SIZE_HEADERS
:
998 outoff
= al
->http
.clientRequestSz
.header
;
1002 /*case LFT_REQUEST_SIZE_BODY: */
1003 /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
1005 case LFT_ADAPTED_REPLY_SIZE_TOTAL
:
1006 outoff
= al
->http
.clientReplySz
.messageTotal();
1010 case LFT_REPLY_HIGHOFFSET
:
1011 outoff
= al
->cache
.highOffset
;
1017 case LFT_REPLY_OBJECTSIZE
:
1018 outoff
= al
->cache
.objectSize
;
1024 case LFT_ADAPTED_REPLY_SIZE_HEADERS
:
1025 outint
= al
->http
.clientReplySz
.header
;
1029 /*case LFT_REPLY_SIZE_BODY: */
1030 /*case LFT_REPLY_SIZE_BODY_NO_TE: */
1032 case LFT_CLIENT_IO_SIZE_TOTAL
:
1033 outint
= al
->http
.clientRequestSz
.messageTotal() + al
->http
.clientReplySz
.messageTotal();
1036 /*case LFT_SERVER_IO_SIZE_TOTAL: */
1040 out
= al
->request
->tag
.termedBuf();
1048 out
= al
->request
->extacl_log
.termedBuf();
1054 case LFT_SEQUENCE_NUMBER
:
1055 outoff
= logSequenceNumber
;
1060 case LFT_SSL_BUMP_MODE
: {
1061 const Ssl::BumpMode mode
= static_cast<Ssl::BumpMode
>(al
->ssl
.bumpMode
);
1062 // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
1063 out
= Ssl::bumpMode(mode
);
1067 case LFT_SSL_USER_CERT_SUBJECT
:
1068 if (X509
*cert
= al
->cache
.sslClientCert
.get()) {
1069 if (X509_NAME
*subject
= X509_get_subject_name(cert
)) {
1070 X509_NAME_oneline(subject
, tmp
, sizeof(tmp
));
1076 case LFT_SSL_USER_CERT_ISSUER
:
1077 if (X509
*cert
= al
->cache
.sslClientCert
.get()) {
1078 if (X509_NAME
*issuer
= X509_get_issuer_name(cert
)) {
1079 X509_NAME_oneline(issuer
, tmp
, sizeof(tmp
));
1087 if (fmt
->data
.string
) {
1089 Adaptation::History::Pointer ah
= al
->request
? al
->request
->adaptHistory() : Adaptation::History::Pointer();
1090 if (ah
!= NULL
&& ah
->metaHeaders
!= NULL
) {
1091 if (const char *meta
= ah
->metaHeaders
->find(fmt
->data
.string
))
1095 if (al
->notes
!= NULL
) {
1096 if (const char *note
= al
->notes
->find(fmt
->data
.string
)) {
1102 out
= sb
.termedBuf();
1106 Adaptation::History::Pointer ah
= al
->request
? al
->request
->adaptHistory() : Adaptation::History::Pointer();
1107 if (ah
!= NULL
&& ah
->metaHeaders
!= NULL
&& !ah
->metaHeaders
->empty())
1108 sb
.append(ah
->metaHeaders
->toString());
1110 if (al
->notes
!= NULL
&& !al
->notes
->empty())
1111 sb
.append(al
->notes
->toString());
1113 out
= sb
.termedBuf();
1125 snprintf(tmp
, sizeof(tmp
), "%0*" PRId64
, fmt
->zero
&& fmt
->widthMin
>= 0 ? fmt
->widthMin
: 0, outoff
);
1129 snprintf(tmp
, sizeof(tmp
), "%0*ld", fmt
->zero
&& fmt
->widthMin
>= 0 ? fmt
->widthMin
: 0, outint
);
1134 if (quote
|| fmt
->quote
!= LOG_QUOTE_NONE
) {
1135 char *newout
= NULL
;
1138 switch (fmt
->quote
) {
1140 case LOG_QUOTE_NONE
:
1141 newout
= rfc1738_escape_unescaped(out
);
1144 case LOG_QUOTE_QUOTES
: {
1145 size_t out_len
= static_cast<size_t>(strlen(out
)) * 2 + 1;
1146 if (out_len
>= sizeof(tmp
)) {
1147 newout
= (char *)xmalloc(out_len
);
1151 log_quoted_string(out
, newout
);
1155 case LOG_QUOTE_MIMEBLOB
:
1156 newout
= QuoteMimeBlob(out
);
1161 newout
= rfc1738_escape(out
);
1178 // enforce width limits if configured
1179 const bool haveMaxWidth
= fmt
->widthMax
>=0 && !doint
&& !dooff
&& !fmt
->divisor
;
1180 if (haveMaxWidth
|| fmt
->widthMin
) {
1181 const int minWidth
= fmt
->widthMin
>= 0 ?
1183 const int maxWidth
= haveMaxWidth
?
1184 fmt
->widthMax
: strlen(out
);
1187 mb
.Printf("%-*.*s", minWidth
, maxWidth
, out
);
1189 mb
.Printf("%*.*s", minWidth
, maxWidth
, out
);
1191 mb
.append(out
, strlen(out
));