Squid Web Cache v8/master
Loading...
Searching...
No Matches
AccessLogEntry.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 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 "fqdncache.h"
12#include "HttpReply.h"
13#include "HttpRequest.h"
14#include "MemBuf.h"
15#include "proxyp/Header.h"
16#include "SquidConfig.h"
17#include "ssl/support.h"
18
19void
20AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const
21{
22 Ip::Address log_ip;
23
24#if FOLLOW_X_FORWARDED_FOR
27 else
28#endif
29 if (tcpClient)
30 log_ip = tcpClient->remote;
31 else
32 log_ip = cache.caddr;
33
34 // internally generated requests (and some ICAP) lack client IP
35 if (log_ip.isNoAddr()) {
36 strncpy(buf, "-", bufsz);
37 return;
38 }
39
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
46
47 log_ip.toStr(buf, bufsz);
48}
49
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
71SBuf
73{
74 static const SBuf dash("-");
75 SBuf method;
76 if (icp.opcode)
78 else if (htcp.opcode)
79 method.append(htcp.opcode);
80 else if (http.method)
81 method = http.method.image();
82 else
83 method = dash;
84 return method;
85}
86
87void
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
99const char *
101{
103 return request->extacl_user.termedBuf();
104
105 if (cache.extuser && *cache.extuser)
106 return cache.extuser;
107
108 return nullptr;
109}
110
112
114{
116
117#if USE_ADAPTATION
119#endif
120
123
125#if ICAP_CLIENT
128#endif
129}
130
133{
134 if (request) {
135 if (const auto &mx = request->masterXaction)
136 return mx->id.detach();
137 }
138 // TODO: Carefully merge ALE and MasterXaction.
139 return ScopedId("ALE w/o master");
140}
141
142std::ostream &
144{
145 // TODO: Consider printing all instead of the first most important detail.
146
147 if (request) {
148 if (const auto &mx = request->masterXaction)
149 return os << Debug::Extra << "current master transaction: " << mx->id;
150 }
151
152 // provide helpful details since we cannot identify the transaction exactly
153
154 if (tcpClient)
155 return os << Debug::Extra << "current from-client connection: " << tcpClient;
156 else if (!cache.caddr.isNoAddr())
157 return os << Debug::Extra << "current client: " << cache.caddr;
158
159 const auto optionalMethod = [this,&os]() {
160 if (hasLogMethod())
161 os << getLogMethod() << ' ';
162 return "";
163 };
164 if (const auto uri = effectiveVirginUrl())
165 return os << Debug::Extra << "current client request: " << optionalMethod() << *uri;
166 else if (!url.isEmpty())
167 return os << Debug::Extra << "current request: " << optionalMethod() << url;
168 else if (hasLogMethod())
169 return os << Debug::Extra << "current request method: " << getLogMethod();
170
171 return os;
172}
173
174const SBuf *
176{
178 if (effectiveUrl && !effectiveUrl->isEmpty())
179 return effectiveUrl;
180 // We can not use ALE::url here because it may contain a request URI after
181 // adaptation/redirection. When the request is missing, a non-empty ALE::url
182 // means that we missed a setVirginUrlForMissingRequest() call somewhere.
183 return nullptr;
184}
185
186const Error *
188{
189 // the order ensures that the first-imported error is returned
190 if (error_) // updateError() was called before importing the request
191 return &error_;
192 if (request && request->error) // request was imported before updateError()
193 return &request->error;
194 return nullptr; // we imported no errors and no requests
195}
196
197void
199{
200 // the order ensures that error() returns the first-imported error
201 if (request)
202 request->error.update(err);
203 else
204 error_.update(err);
205}
206
207void
213
class SquidConfig Config
#define assert(EX)
Definition assert.h:17
char * last_meta
image of the last ICAP response header or eCAP meta received
HttpReply * reply
ICAP reply.
HttpRequest * request
ICAP request.
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
SBuf virginUrlForMissingRequest_
void syncNotes(HttpRequest *request)
~AccessLogEntry() override
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
class AccessLogEntry::HtcpDetails htcp
const char * getExtUser() const
Fetch the external ACL provided 'user=' string, or nil if none is available.
const char * getLogClientFqdn(char *buf, size_t bufSize) const
class AccessLogEntry::AdaptationDetails adapt
class AccessLogEntry::IcpDetails icp
NotePairs::Pointer notes
const SBuf * effectiveVirginUrl() const
ScopedId codeContextGist() const override
void updateError(const Error &)
sets (or updates the already stored) transaction error as needed
std::ostream & detailCodeContext(std::ostream &os) const override
appends human-friendly context description line(s) to a cache.log record
Ip::Address remote
Definition Connection.h:152
static std::ostream & Extra(std::ostream &)
Definition debug.cc:1316
a transaction problem
Definition Error.h:27
void update(const Error &)
if necessary, stores the given error information (if any)
Definition Error.cc:51
void packHeadersUsingFastPacker(Packable &p) const
Definition HttpReply.cc:87
const SBuf & image() const
MasterXaction::Pointer masterXaction
the master transaction this request belongs to. Never nil.
Ip::Address indirect_client_addr
String extacl_user
NotePairs::Pointer notes()
Error error
the first transaction problem encountered (or falsy)
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition Address.cc:804
void applyClientMask(const Address &mask)
Definition Address.cc:125
bool isNoAddr() const
Definition Address.cc:304
Definition SBuf.h:94
bool isEmpty() const
Definition SBuf.h:435
SBuf & append(const SBuf &S)
Definition SBuf.cc:185
int log_uses_indirect_client
struct SquidConfig::@85 Addrs
struct SquidConfig::@90 onoff
Ip::Address client_netmask
char const * termedBuf() const
Definition SquidString.h:93
size_type size() const
Definition SquidString.h:74
#define FQDN_LOOKUP_IF_MISS
Definition defines.h:34
const char * fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
Definition fqdncache.cc:481
void HTTPMSGUNLOCK(M *&a)
Definition Message.h:150
const char * icp_opcode_str[]
bool ResolveClientAddressesAsap
whether to do reverse DNS lookups for source IPs of accepted connections
Definition fqdncache.cc:30
#define safe_free(x)
Definition xalloc.h:73