2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_HTTPACCESSLOGENTRY_H
10 #define SQUID_HTTPACCESSLOGENTRY_H
12 #include "anyp/PortCfg.h"
13 #include "base/CodeContext.h"
14 #include "comm/Connection.h"
15 #include "error/Error.h"
16 #include "HierarchyLogEntry.h"
17 #include "http/ProtocolVersion.h"
18 #include "http/RequestMethod.h"
19 #include "HttpHeader.h"
20 #include "icp_opcode.h"
21 #include "ip/Address.h"
23 #include "MessageSizes.h"
25 #include "proxyp/forward.h"
26 #include "sbuf/SBuf.h"
28 #include "adaptation/icap/Elements.h"
31 #include "ssl/gadgets.h"
32 #include "ssl/support.h"
40 class AccessLogEntry
: public CodeContext
44 typedef RefCount
<AccessLogEntry
> Pointer
;
47 virtual ~AccessLogEntry();
50 virtual std::ostream
&detailCodeContext(std::ostream
&os
) const override
;
51 virtual ScopedId
codeContextGist() const override
;
53 /// Fetch the client IP log string into the given buffer.
54 /// Knows about several alternate locations of the IP
55 /// including indirect forwarded-for IP if configured to log that
56 void getLogClientIp(char *buf
, size_t bufsz
) const;
58 /// %>A: Compute client FQDN if possible, using the supplied buf if needed.
59 /// \returns result for immediate logging (not necessarily pointing to buf)
60 /// Side effect: Enables reverse DNS lookups of future client addresses.
61 const char *getLogClientFqdn(char *buf
, size_t bufSize
) const;
63 /// Fetch the client IDENT string, or nil if none is available.
64 const char *getClientIdent() const;
66 /// Fetch the external ACL provided 'user=' string, or nil if none is available.
67 const char *getExtUser() const;
69 /// whether we know what the request method is
70 bool hasLogMethod() const { return icp
.opcode
|| htcp
.opcode
|| http
.method
; }
72 /// Fetch the transaction method string (ICP opcode, HTCP opcode or HTTP method)
73 SBuf
getLogMethod() const;
75 void syncNotes(HttpRequest
*request
);
77 /// dump all reply headers (for sending or risky logging)
78 void packReplyHeaders(MemBuf
&mb
) const;
82 /// TCP/IP level details about the client connection
83 Comm::ConnectionPointer tcpClient
;
84 // TCP/IP level details about the server or peer connection
85 // are stored in hier.tcpServer
87 /** \brief This subclass holds log info for HTTP protocol
88 * TODO: Inner class declarations should be moved outside
89 * TODO: details of HTTP held in the parent class need moving into here.
95 HttpRequestMethod method
;
97 const char *content_type
= nullptr;
98 AnyP::ProtocolVersion version
;
100 /// counters for the original request received from client
101 // TODO calculate header and payload better (by parser)
102 // XXX payload encoding overheads not calculated at all yet.
103 MessageSizes clientRequestSz
;
105 /// counters for the response sent to client
106 // TODO calculate header and payload better (by parser)
107 // XXX payload encoding overheads not calculated at all yet.
108 MessageSizes clientReplySz
;
112 /** \brief This subclass holds log info for ICP protocol
113 * TODO: Inner class declarations should be moved outside
118 icp_opcode opcode
= ICP_INVALID
;
121 /** \brief This subclass holds log info for HTCP protocol
122 * TODO: Inner class declarations should be moved outside
127 const char *opcode
= nullptr;
131 /// logging information specific to the SSL protocol
135 const char *user
= nullptr; ///< emailAddress from the SSL client certificate
136 int bumpMode
= ::Ssl::bumpEnd
; ///< whether and how the request was SslBumped
140 /** \brief This subclass holds log info for Squid internal stats
141 * TODO: Inner class declarations should be moved outside
142 * TODO: some details relevant to particular protocols need shuffling to other sub-classes
143 * TODO: this object field need renaming to 'squid' or something.
150 memset(&start_time
, 0, sizeof(start_time
));
151 memset(&trTime
, 0, sizeof(start_time
));
155 int64_t highOffset
= 0;
156 int64_t objectSize
= 0;
158 struct timeval start_time
; ///< The time the master transaction started
159 struct timeval trTime
; ///< The response time
160 const char *rfc931
= nullptr;
161 const char *extuser
= nullptr;
163 const char *ssluser
= nullptr;
164 Security::CertPointer sslClientCert
; ///< cert received from the client
166 AnyP::PortCfgPointer port
;
169 /** \brief This subclass holds log info for various headers in raw format
170 * TODO: shuffle this to the relevant protocol section.
175 char *request
= nullptr; //< virgin HTTP request headers
176 char *adapted_request
= nullptr; //< HTTP request headers after adaptation and redirection
180 /** \brief This subclass holds general adaptation log info.
181 * TODO: Inner class declarations should be moved outside.
183 class AdaptationDetails
186 /// image of the last ICAP response header or eCAP meta received
187 char *last_meta
= nullptr;
191 const char *lastAclName
= nullptr; ///< string for external_acl_type %ACL format code
192 SBuf lastAclData
; ///< string for external_acl_type %DATA format code
194 HierarchyLogEntry hier
;
195 HttpReplyPointer reply
;
196 HttpRequest
*request
= nullptr; //< virgin HTTP request
197 HttpRequest
*adapted_request
= nullptr; //< HTTP request after adaptation and redirection
199 /// key:value pairs set by squid.conf note directive and
200 /// key=value pairs returned from URL rewrite/redirect helper
201 NotePairs::Pointer notes
;
203 /// see ConnStateData::proxyProtocolHeader_
204 ProxyProtocol::HeaderPointer proxyProtocolHeader
;
207 /** \brief This subclass holds log info for ICAP part of request
208 * TODO: Inner class declarations should be moved outside
214 memset(&trTime
, 0, sizeof(trTime
));
215 memset(&ioTime
, 0, sizeof(ioTime
));
216 memset(&processingTime
, 0, sizeof(processingTime
));
219 Ip::Address hostAddr
; ///< ICAP server IP address
220 String serviceName
; ///< ICAP service name
221 String reqUri
; ///< ICAP Request-URI
222 Adaptation::Icap::ICAP::Method reqMethod
= Adaptation::methodNone
; ///< ICAP request method
223 int64_t bytesSent
= 0; ///< number of bytes sent to ICAP server so far
224 int64_t bytesRead
= 0; ///< number of bytes read from ICAP server so far
226 * number of ICAP body bytes read from ICAP server or -1 for no encapsulated
227 * message data in ICAP reply (eg 204 responses)
229 int64_t bodyBytesRead
= -1;
230 HttpRequest
* request
= nullptr; ///< ICAP request
231 HttpReply
* reply
= nullptr; ///< ICAP reply
233 Adaptation::Icap::XactOutcome outcome
= Adaptation::Icap::xoUnknown
; ///< final transaction status
234 /** \brief Transaction response time.
235 * The timer starts when the ICAP transaction
236 * is created and stops when the result of the transaction is logged
238 struct timeval trTime
;
239 /** \brief Transaction I/O time.
240 * The timer starts when the first ICAP request
241 * byte is scheduled for sending and stops when the lastbyte of the
242 * ICAP response is received.
244 struct timeval ioTime
;
245 Http::StatusCode resStatus
= Http::scNone
; ///< ICAP response status code
246 struct timeval processingTime
; ///< total ICAP processing time
251 /// Effective URI of the received client (or equivalent) HTTP request or,
252 /// in rare cases where that information was not collected, a nil pointer.
253 /// Receiving errors are represented by "error:..." URIs.
254 /// Adaptations and redirections do not affect this URI.
255 const SBuf
*effectiveVirginUrl() const;
257 /// Remember Client URI (or equivalent) when there is no HttpRequest.
258 void setVirginUrlForMissingRequest(const SBuf
&vu
)
261 virginUrlForMissingRequest_
= vu
;
264 /// \returns stored transaction error information (or nil)
265 const Error
*error() const;
267 /// sets (or updates the already stored) transaction error as needed
268 void updateError(const Error
&);
271 /// transaction problem
272 /// if set, overrides (and should eventually replace) request->error
275 /// Client URI (or equivalent) for effectiveVirginUrl() when HttpRequest is
276 /// missing. This member is ignored unless the request member is nil.
277 SBuf virginUrlForMissingRequest_
;
283 /* Should be in 'AccessLog.h' as the driver */
284 void accessLogLogTo(CustomLog
*, const AccessLogEntryPointer
&, ACLChecklist
*checklist
= nullptr);
285 void accessLogLog(const AccessLogEntryPointer
&, ACLChecklist
*);
286 void accessLogRotate(void);
287 void accessLogClose(void);
288 void accessLogInit(void);
289 const char *accessLogTime(time_t);
291 #endif /* SQUID_HTTPACCESSLOGENTRY_H */