]> git.ipfire.org Git - thirdparty/squid.git/blob - src/AccessLogEntry.h
Supply ALE with HttpReply before checking http_reply_access (#398)
[thirdparty/squid.git] / src / AccessLogEntry.h
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 #ifndef SQUID_HTTPACCESSLOGENTRY_H
10 #define SQUID_HTTPACCESSLOGENTRY_H
11
12 #include "anyp/PortCfg.h"
13 #include "base/RefCount.h"
14 #include "comm/Connection.h"
15 #include "HierarchyLogEntry.h"
16 #include "http/ProtocolVersion.h"
17 #include "http/RequestMethod.h"
18 #include "HttpHeader.h"
19 #include "icp_opcode.h"
20 #include "ip/Address.h"
21 #include "LogTags.h"
22 #include "MessageSizes.h"
23 #include "Notes.h"
24 #include "proxyp/forward.h"
25 #include "sbuf/SBuf.h"
26 #if ICAP_CLIENT
27 #include "adaptation/icap/Elements.h"
28 #endif
29 #if USE_OPENSSL
30 #include "ssl/gadgets.h"
31 #include "ssl/support.h"
32 #endif
33
34 /* forward decls */
35 class HttpReply;
36 class HttpRequest;
37 class CustomLog;
38
39 class AccessLogEntry: public RefCountable
40 {
41
42 public:
43 typedef RefCount<AccessLogEntry> Pointer;
44
45 AccessLogEntry();
46 ~AccessLogEntry();
47
48 /// Fetch the client IP log string into the given buffer.
49 /// Knows about several alternate locations of the IP
50 /// including indirect forwarded-for IP if configured to log that
51 void getLogClientIp(char *buf, size_t bufsz) const;
52
53 /// Fetch the client IDENT string, or nil if none is available.
54 const char *getClientIdent() const;
55
56 /// Fetch the external ACL provided 'user=' string, or nil if none is available.
57 const char *getExtUser() const;
58
59 /// Fetch the transaction method string (ICP opcode, HTCP opcode or HTTP method)
60 SBuf getLogMethod() const;
61
62 void syncNotes(HttpRequest *request);
63
64 /// dump all reply headers (for sending or risky logging)
65 void packReplyHeaders(MemBuf &mb) const;
66
67 SBuf url;
68
69 /// TCP/IP level details about the client connection
70 Comm::ConnectionPointer tcpClient;
71 // TCP/IP level details about the server or peer connection
72 // are stored in hier.tcpServer
73
74 /** \brief This subclass holds log info for HTTP protocol
75 * \todo Inner class declarations should be moved outside
76 * \todo details of HTTP held in the parent class need moving into here.
77 */
78 class HttpDetails
79 {
80
81 public:
82 HttpRequestMethod method;
83 int code = 0;
84 const char *content_type = nullptr;
85 AnyP::ProtocolVersion version;
86
87 /// counters for the original request received from client
88 // TODO calculate header and payload better (by parser)
89 // XXX payload encoding overheads not calculated at all yet.
90 MessageSizes clientRequestSz;
91
92 /// counters for the response sent to client
93 // TODO calculate header and payload better (by parser)
94 // XXX payload encoding overheads not calculated at all yet.
95 MessageSizes clientReplySz;
96
97 } http;
98
99 /** \brief This subclass holds log info for ICP protocol
100 * \todo Inner class declarations should be moved outside
101 */
102 class IcpDetails
103 {
104 public:
105 icp_opcode opcode = ICP_INVALID;
106 } icp;
107
108 /** \brief This subclass holds log info for HTCP protocol
109 * \todo Inner class declarations should be moved outside
110 */
111 class HtcpDetails
112 {
113 public:
114 const char *opcode = nullptr;
115 } htcp;
116
117 #if USE_OPENSSL
118 /// logging information specific to the SSL protocol
119 class SslDetails
120 {
121 public:
122 const char *user = nullptr; ///< emailAddress from the SSL client certificate
123 int bumpMode = ::Ssl::bumpEnd; ///< whether and how the request was SslBumped
124 } ssl;
125 #endif
126
127 /** \brief This subclass holds log info for Squid internal stats
128 * \todo Inner class declarations should be moved outside
129 * \todo some details relevant to particular protocols need shuffling to other sub-classes
130 * \todo this object field need renaming to 'squid' or something.
131 */
132 class CacheDetails
133 {
134 public:
135 CacheDetails() {
136 caddr.setNoAddr();
137 memset(&start_time, 0, sizeof(start_time));
138 memset(&trTime, 0, sizeof(start_time));
139 }
140
141 Ip::Address caddr;
142 int64_t highOffset = 0;
143 int64_t objectSize = 0;
144 LogTags code;
145 struct timeval start_time; ///< The time the master transaction started
146 struct timeval trTime; ///< The response time
147 const char *rfc931 = nullptr;
148 const char *extuser = nullptr;
149 #if USE_OPENSSL
150 const char *ssluser = nullptr;
151 Security::CertPointer sslClientCert; ///< cert received from the client
152 #endif
153 AnyP::PortCfgPointer port;
154 } cache;
155
156 /** \brief This subclass holds log info for various headers in raw format
157 * \todo shuffle this to the relevant protocol section.
158 */
159 class Headers
160 {
161 public:
162 char *request = nullptr; //< virgin HTTP request headers
163 char *adapted_request = nullptr; //< HTTP request headers after adaptation and redirection
164 } headers;
165
166 #if USE_ADAPTATION
167 /** \brief This subclass holds general adaptation log info.
168 * \todo Inner class declarations should be moved outside.
169 */
170 class AdaptationDetails
171 {
172 public:
173 /// image of the last ICAP response header or eCAP meta received
174 char *last_meta = nullptr;
175 } adapt;
176 #endif
177
178 const char *lastAclName = nullptr; ///< string for external_acl_type %ACL format code
179 SBuf lastAclData; ///< string for external_acl_type %DATA format code
180
181 HierarchyLogEntry hier;
182 HttpReplyPointer reply;
183 HttpRequest *request = nullptr; //< virgin HTTP request
184 HttpRequest *adapted_request = nullptr; //< HTTP request after adaptation and redirection
185
186 /// key:value pairs set by squid.conf note directive and
187 /// key=value pairs returned from URL rewrite/redirect helper
188 NotePairs::Pointer notes;
189
190 /// see ConnStateData::proxyProtocolHeader_
191 ProxyProtocol::HeaderPointer proxyProtocolHeader;
192
193 #if ICAP_CLIENT
194 /** \brief This subclass holds log info for ICAP part of request
195 * \todo Inner class declarations should be moved outside
196 */
197 class IcapLogEntry
198 {
199 public:
200 IcapLogEntry() {
201 memset(&trTime, 0, sizeof(trTime));
202 memset(&ioTime, 0, sizeof(ioTime));
203 memset(&processingTime, 0, sizeof(processingTime));
204 }
205
206 Ip::Address hostAddr; ///< ICAP server IP address
207 String serviceName; ///< ICAP service name
208 String reqUri; ///< ICAP Request-URI
209 Adaptation::Icap::ICAP::Method reqMethod = Adaptation::methodNone; ///< ICAP request method
210 int64_t bytesSent = 0; ///< number of bytes sent to ICAP server so far
211 int64_t bytesRead = 0; ///< number of bytes read from ICAP server so far
212 /**
213 * number of ICAP body bytes read from ICAP server or -1 for no encapsulated
214 * message data in ICAP reply (eg 204 responses)
215 */
216 int64_t bodyBytesRead = -1;
217 HttpRequest* request = nullptr; ///< ICAP request
218 HttpReply* reply = nullptr; ///< ICAP reply
219
220 Adaptation::Icap::XactOutcome outcome = Adaptation::Icap::xoUnknown; ///< final transaction status
221 /** \brief Transaction response time.
222 * The timer starts when the ICAP transaction
223 * is created and stops when the result of the transaction is logged
224 */
225 struct timeval trTime;
226 /** \brief Transaction I/O time.
227 * The timer starts when the first ICAP request
228 * byte is scheduled for sending and stops when the lastbyte of the
229 * ICAP response is received.
230 */
231 struct timeval ioTime;
232 Http::StatusCode resStatus = Http::scNone; ///< ICAP response status code
233 struct timeval processingTime; ///< total ICAP processing time
234 }
235 icap;
236 #endif
237
238 /// Effective URI of the received client (or equivalent) HTTP request or,
239 /// in rare cases where that information was not collected, a nil pointer.
240 /// Receiving errors are represented by "error:..." URIs.
241 /// Adaptations and redirections do not affect this URI.
242 const SBuf *effectiveVirginUrl() const;
243
244 /// Remember Client URI (or equivalent) when there is no HttpRequest.
245 void setVirginUrlForMissingRequest(const SBuf &vu)
246 {
247 if (!request)
248 virginUrlForMissingRequest_ = vu;
249 }
250
251 private:
252 /// Client URI (or equivalent) for effectiveVirginUrl() when HttpRequest is
253 /// missing. This member is ignored unless the request member is nil.
254 SBuf virginUrlForMissingRequest_;
255 };
256
257 class ACLChecklist;
258 class StoreEntry;
259
260 /* Should be in 'AccessLog.h' as the driver */
261 void accessLogLogTo(CustomLog* log, AccessLogEntry::Pointer &al, ACLChecklist* checklist = NULL);
262 void accessLogLog(AccessLogEntry::Pointer &, ACLChecklist * checklist);
263 void accessLogRotate(void);
264 void accessLogClose(void);
265 void accessLogInit(void);
266 const char *accessLogTime(time_t);
267
268 #endif /* SQUID_HTTPACCESSLOGENTRY_H */
269