AccessLogEntry.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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 
19 void
20 AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const
21 {
22  Ip::Address log_ip;
23 
24 #if FOLLOW_X_FORWARDED_FOR
26  log_ip = request->indirect_client_addr;
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 
50 const char *
51 AccessLogEntry::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 
71 SBuf
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 
87 void
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 
99 const char *
101 {
102  if (request && request->extacl_user.size())
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 
131 ScopedId
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 
142 std::ostream &
143 AccessLogEntry::detailCodeContext(std::ostream &os) const
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 
174 const SBuf *
176 {
177  const SBuf *effectiveUrl = request ? &request->effectiveRequestUri() : &virginUrlForMissingRequest_;
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 
186 const 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 
197 void
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 
207 void
209 {
210  if (reply)
212 }
213 
#define FQDN_LOOKUP_IF_MISS
Definition: defines.h:34
SBuf virginUrlForMissingRequest_
const char * getLogClientFqdn(char *buf, size_t bufSize) const
const Error * error() const
bool isEmpty() const
Definition: SBuf.h:435
void updateError(const Error &)
sets (or updates the already stored) transaction error as needed
class AccessLogEntry::HtcpDetails htcp
HttpRequest * request
ICAP request.
HttpReplyPointer reply
Definition: SBuf.h:93
Ip::Address client_netmask
Definition: SquidConfig.h:242
const SBuf * effectiveVirginUrl() const
struct SquidConfig::@97 onoff
const SBuf & image() const
void HTTPMSGUNLOCK(M *&a)
Definition: Message.h:150
NotePairs::Pointer notes
void packHeadersUsingFastPacker(Packable &p) const
Definition: HttpReply.cc:87
String extacl_user
Definition: HttpRequest.h:178
Error error
the first transaction problem encountered (or falsy)
Definition: HttpRequest.h:161
bool ResolveClientAddressesAsap
whether to do reverse DNS lookups for source IPs of accepted connections
Definition: fqdncache.cc:30
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition: Address.cc:812
class AccessLogEntry::HttpDetails http
class AccessLogEntry::IcpDetails icp
a transaction problem
Definition: Error.h:27
class AccessLogEntry::IcapLogEntry icap
void syncNotes(HttpRequest *request)
HttpRequest * request
void applyClientMask(const Address &mask)
Definition: Address.cc:125
const char * fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
Definition: fqdncache.cc:481
char * last_meta
image of the last ICAP response header or eCAP meta received
Ip::Address indirect_client_addr
Definition: HttpRequest.h:152
Definition: MemBuf.h:23
Comm::ConnectionPointer tcpClient
TCP/IP level details about the client connection.
#define safe_free(x)
Definition: xalloc.h:73
Ip::Address remote
Definition: Connection.h:149
MasterXaction::Pointer masterXaction
the master transaction this request belongs to. Never nil.
Definition: HttpRequest.h:238
#define assert(EX)
Definition: assert.h:17
class AccessLogEntry::CacheDetails cache
static uint32 C
Definition: md4.c:43
HttpRequestMethod method
HttpReply * reply
ICAP reply.
class AccessLogEntry::Headers headers
static std::ostream & Extra(std::ostream &)
Definition: debug.cc:1316
class AccessLogEntry::AdaptationDetails adapt
SBuf & append(const SBuf &S)
Definition: SBuf.cc:185
bool isNoAddr() const
Definition: Address.cc:304
std::ostream & detailCodeContext(std::ostream &os) const override
appends human-friendly context description line(s) to a cache.log record
~AccessLogEntry() override
int log_uses_indirect_client
Definition: SquidConfig.h:328
const char * termedBuf() const
Definition: SquidString.h:92
HttpRequest * adapted_request
size_type size() const
Definition: SquidString.h:73
void getLogClientIp(char *buf, size_t bufsz) const
void packReplyHeaders(MemBuf &mb) const
dump all reply headers (for sending or risky logging)
bool hasLogMethod() const
whether we know what the request method is
ScopedId codeContextGist() const override
void update(const Error &)
if necessary, stores the given error information (if any)
Definition: Error.cc:51
struct SquidConfig::@92 Addrs
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
Definition: HttpRequest.cc:744
NotePairs::Pointer notes()
Definition: HttpRequest.cc:752
const char * getExtUser() const
Fetch the external ACL provided 'user=' string, or nil if none is available.
SBuf getLogMethod() const
Fetch the transaction method string (ICP opcode, HTCP opcode or HTTP method)
const char * icp_opcode_str[]
class SquidConfig Config
Definition: SquidConfig.cc:12

 

Introduction

Documentation

Support

Miscellaneous