AccessLogEntry.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 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 (tcpClient)
103  return tcpClient->rfc931;
104 
105  if (cache.rfc931 && *cache.rfc931)
106  return cache.rfc931;
107 
108  return nullptr;
109 }
110 
111 const char *
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 
124 
126 {
128 
129 #if USE_ADAPTATION
131 #endif
132 
135 
137 
139 #if ICAP_CLIENT
142 #endif
143 }
144 
145 ScopedId
147 {
148  if (request) {
149  if (const auto &mx = request->masterXaction)
150  return mx->id.detach();
151  }
152  // TODO: Carefully merge ALE and MasterXaction.
153  return ScopedId("ALE w/o master");
154 }
155 
156 std::ostream &
157 AccessLogEntry::detailCodeContext(std::ostream &os) const
158 {
159  // TODO: Consider printing all instead of the first most important detail.
160 
161  if (request) {
162  if (const auto &mx = request->masterXaction)
163  return os << Debug::Extra << "current master transaction: " << mx->id;
164  }
165 
166  // provide helpful details since we cannot identify the transaction exactly
167 
168  if (tcpClient)
169  return os << Debug::Extra << "current from-client connection: " << tcpClient;
170  else if (!cache.caddr.isNoAddr())
171  return os << Debug::Extra << "current client: " << cache.caddr;
172 
173  const auto optionalMethod = [this,&os]() {
174  if (hasLogMethod())
175  os << getLogMethod() << ' ';
176  return "";
177  };
178  if (const auto uri = effectiveVirginUrl())
179  return os << Debug::Extra << "current client request: " << optionalMethod() << *uri;
180  else if (!url.isEmpty())
181  return os << Debug::Extra << "current request: " << optionalMethod() << url;
182  else if (hasLogMethod())
183  return os << Debug::Extra << "current request method: " << getLogMethod();
184 
185  return os;
186 }
187 
188 const SBuf *
190 {
191  const SBuf *effectiveUrl = request ? &request->effectiveRequestUri() : &virginUrlForMissingRequest_;
192  if (effectiveUrl && !effectiveUrl->isEmpty())
193  return effectiveUrl;
194  // We can not use ALE::url here because it may contain a request URI after
195  // adaptation/redirection. When the request is missing, a non-empty ALE::url
196  // means that we missed a setVirginUrlForMissingRequest() call somewhere.
197  return nullptr;
198 }
199 
200 const Error *
202 {
203  // the order ensures that the first-imported error is returned
204  if (error_) // updateError() was called before importing the request
205  return &error_;
206  if (request && request->error) // request was imported before updateError()
207  return &request->error;
208  return nullptr; // we imported no errors and no requests
209 }
210 
211 void
213 {
214  // the order ensures that error() returns the first-imported error
215  if (request)
216  request->error.update(err);
217  else
218  error_.update(err);
219 }
220 
221 void
223 {
224  if (reply)
226 }
227 
#define FQDN_LOOKUP_IF_MISS
Definition: defines.h:34
const char * getClientIdent() const
Fetch the client IDENT string, or nil if none is available.
SBuf virginUrlForMissingRequest_
const char * getLogClientFqdn(char *buf, size_t bufSize) const
static std::ostream & Extra(std::ostream &os)
prefixes each grouped debugs() line after the first one in the group
Definition: Stream.h:117
const Error * error() const
bool isEmpty() const
Definition: SBuf.h:424
struct SquidConfig::@105 Addrs
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:87
Ip::Address client_netmask
Definition: SquidConfig.h:247
const SBuf * effectiveVirginUrl() const
const SBuf & image() const
void HTTPMSGUNLOCK(M *&a)
Definition: Message.h:150
NotePairs::Pointer notes
void packHeadersUsingFastPacker(Packable &p) const
Definition: HttpReply.cc:85
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:792
class AccessLogEntry::HttpDetails http
class AccessLogEntry::IcpDetails icp
a transaction problem
Definition: Error.h:18
class AccessLogEntry::IcapLogEntry icap
void syncNotes(HttpRequest *request)
HttpRequest * request
void applyClientMask(const Address &mask)
Definition: Address.cc:105
char rfc931[USER_IDENT_SZ]
Definition: Connection.h:174
const char * fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
Definition: fqdncache.cc:482
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:24
const char * lastAclName
string for external_acl_type ACL format code
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:147
MasterXaction::Pointer masterXaction
the master transaction this request belongs to. Never nil.
Definition: HttpRequest.h:238
#define assert(EX)
Definition: assert.h:19
char const * termedBuf() const
Definition: SquidString.h:92
class AccessLogEntry::CacheDetails cache
static uint32 C
Definition: md4.c:43
HttpRequestMethod method
HttpReply * reply
ICAP reply.
class AccessLogEntry::Headers headers
class AccessLogEntry::AdaptationDetails adapt
SBuf & append(const SBuf &S)
Definition: SBuf.cc:185
bool isNoAddr() const
Definition: Address.cc:284
virtual ~AccessLogEntry()
virtual std::ostream & detailCodeContext(std::ostream &os) const override
appends human-friendly context description line(s) to a cache.log record
int log_uses_indirect_client
Definition: SquidConfig.h:334
HttpRequest * adapted_request
struct SquidConfig::@110 onoff
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
virtual ScopedId codeContextGist() const override
void update(const Error &)
if necessary, stores the given error information (if any)
Definition: Error.cc:16
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
Definition: HttpRequest.cc:752
NotePairs::Pointer notes()
Definition: HttpRequest.cc:760
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

Web Site Translations

Mirrors