]> git.ipfire.org Git - thirdparty/squid.git/blame - src/AccessLogEntry.cc
Upgrade Acl::Node::name to SBuf; remove AclMatchedName global (#1766)
[thirdparty/squid.git] / src / AccessLogEntry.cc
CommitLineData
bbc27441 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
bbc27441
AJ
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
f7f3304a 9#include "squid.h"
d4204018 10#include "AccessLogEntry.h"
a8c7a110 11#include "fqdncache.h"
582c2af2 12#include "HttpReply.h"
d4204018 13#include "HttpRequest.h"
49f57088 14#include "MemBuf.h"
36c774f7 15#include "proxyp/Header.h"
4d5904f7 16#include "SquidConfig.h"
f3d7d090
AJ
17#include "ssl/support.h"
18
d4204018
AJ
19void
20AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const
21{
998ef291
AJ
22 Ip::Address log_ip;
23
d4204018
AJ
24#if FOLLOW_X_FORWARDED_FOR
25 if (Config.onoff.log_uses_indirect_client && request)
998ef291 26 log_ip = request->indirect_client_addr;
d4204018
AJ
27 else
28#endif
705c36c6 29 if (tcpClient)
998ef291 30 log_ip = tcpClient->remote;
705c36c6 31 else
998ef291
AJ
32 log_ip = cache.caddr;
33
705c36c6
AJ
34 // internally generated requests (and some ICAP) lack client IP
35 if (log_ip.isNoAddr()) {
36 strncpy(buf, "-", bufsz);
37 return;
38 }
39
998ef291
AJ
40 // Apply so-called 'privacy masking' to IPv4 clients
41 // - localhost IP is always shown in full
42 // - IPv4 clients masked with client_netmask
43 // - IPv6 clients use 'privacy addressing' instead.
44
36c774f7 45 log_ip.applyClientMask(Config.Addrs.client_netmask);
998ef291
AJ
46
47 log_ip.toStr(buf, bufsz);
d4204018 48}
41ebd397 49
a8c7a110
AR
50const char *
51AccessLogEntry::getLogClientFqdn(char * const buf, const size_t bufSize) const
52{
53 // TODO: Use indirect client and tcpClient like getLogClientIp() does.
54 const auto &client = cache.caddr;
55
56 // internally generated (and ICAP OPTIONS) requests lack client IP
57 if (client.isAnyAddr())
58 return "-";
59
60 // If we are here, Squid was configured to use %>A or equivalent.
61 // Improve our chances of getting FQDN by resolving client IPs ASAP.
62 Dns::ResolveClientAddressesAsap = true; // may already be true
63
64 // Too late for ours, but FQDN_LOOKUP_IF_MISS might help the next caller.
65 if (const auto fqdn = fqdncache_gethostbyaddr(client, FQDN_LOOKUP_IF_MISS))
66 return fqdn; // TODO: Return a safe SBuf from fqdncache_gethostbyaddr().
67
68 return client.toStr(buf, bufSize);
69}
70
58b148e1
AJ
71SBuf
72AccessLogEntry::getLogMethod() const
73{
ec2c4acf 74 static const SBuf dash("-");
58b148e1
AJ
75 SBuf method;
76 if (icp.opcode)
77 method.append(icp_opcode_str[icp.opcode]);
78 else if (htcp.opcode)
79 method.append(htcp.opcode);
ec2c4acf 80 else if (http.method)
58b148e1 81 method = http.method.image();
ec2c4acf
AR
82 else
83 method = dash;
58b148e1
AJ
84 return method;
85}
86
75d47340
CT
87void
88AccessLogEntry::syncNotes(HttpRequest *req)
89{
90 // XXX: auth code only has access to HttpRequest being authenticated
91 // so we must handle the case where HttpRequest is set without ALE being set.
92 assert(req);
93 if (!notes)
94 notes = req->notes();
95 else
96 assert(notes == req->notes());
97}
98
e3bf07f5
AJ
99const char *
100AccessLogEntry::getClientIdent() const
101{
102 if (tcpClient)
103 return tcpClient->rfc931;
104
105 if (cache.rfc931 && *cache.rfc931)
106 return cache.rfc931;
107
108 return nullptr;
109}
110
111const char *
112AccessLogEntry::getExtUser() const
113{
114 if (request && request->extacl_user.size())
115 return request->extacl_user.termedBuf();
116
117 if (cache.extuser && *cache.extuser)
118 return cache.extuser;
119
120 return nullptr;
121}
122
36c774f7
EB
123AccessLogEntry::AccessLogEntry() {}
124
41ebd397
CT
125AccessLogEntry::~AccessLogEntry()
126{
127 safe_free(headers.request);
128
f5d0906a 129#if USE_ADAPTATION
41ebd397
CT
130 safe_free(adapt.last_meta);
131#endif
132
41ebd397
CT
133 safe_free(headers.adapted_request);
134 HTTPMSGUNLOCK(adapted_request);
135
41ebd397
CT
136 HTTPMSGUNLOCK(request);
137#if ICAP_CLIENT
138 HTTPMSGUNLOCK(icap.reply);
139 HTTPMSGUNLOCK(icap.request);
140#endif
41ebd397 141}
f53969cc 142
ccfbe8f4
AR
143ScopedId
144AccessLogEntry::codeContextGist() const
145{
146 if (request) {
147 if (const auto &mx = request->masterXaction)
148 return mx->id.detach();
149 }
150 // TODO: Carefully merge ALE and MasterXaction.
151 return ScopedId("ALE w/o master");
152}
153
154std::ostream &
155AccessLogEntry::detailCodeContext(std::ostream &os) const
156{
157 // TODO: Consider printing all instead of the first most important detail.
158
159 if (request) {
160 if (const auto &mx = request->masterXaction)
161 return os << Debug::Extra << "current master transaction: " << mx->id;
162 }
163
164 // provide helpful details since we cannot identify the transaction exactly
165
166 if (tcpClient)
167 return os << Debug::Extra << "current from-client connection: " << tcpClient;
168 else if (!cache.caddr.isNoAddr())
169 return os << Debug::Extra << "current client: " << cache.caddr;
170
171 const auto optionalMethod = [this,&os]() {
172 if (hasLogMethod())
173 os << getLogMethod() << ' ';
174 return "";
175 };
176 if (const auto uri = effectiveVirginUrl())
177 return os << Debug::Extra << "current client request: " << optionalMethod() << *uri;
178 else if (!url.isEmpty())
179 return os << Debug::Extra << "current request: " << optionalMethod() << url;
180 else if (hasLogMethod())
181 return os << Debug::Extra << "current request method: " << getLogMethod();
182
183 return os;
184}
185
bec110e4
EB
186const SBuf *
187AccessLogEntry::effectiveVirginUrl() const
188{
57a5679b 189 const SBuf *effectiveUrl = request ? &request->effectiveRequestUri() : &virginUrlForMissingRequest_;
bec110e4
EB
190 if (effectiveUrl && !effectiveUrl->isEmpty())
191 return effectiveUrl;
192 // We can not use ALE::url here because it may contain a request URI after
193 // adaptation/redirection. When the request is missing, a non-empty ALE::url
194 // means that we missed a setVirginUrlForMissingRequest() call somewhere.
195 return nullptr;
196}
197
83b053a0
CT
198const Error *
199AccessLogEntry::error() const
200{
201 // the order ensures that the first-imported error is returned
202 if (error_) // updateError() was called before importing the request
203 return &error_;
204 if (request && request->error) // request was imported before updateError()
205 return &request->error;
206 return nullptr; // we imported no errors and no requests
207}
208
209void
210AccessLogEntry::updateError(const Error &err)
211{
212 // the order ensures that error() returns the first-imported error
213 if (request)
214 request->error.update(err);
215 else
216 error_.update(err);
217}
218
49f57088
EB
219void
220AccessLogEntry::packReplyHeaders(MemBuf &mb) const
221{
222 if (reply)
223 reply->packHeadersUsingFastPacker(mb);
224}
225