]> git.ipfire.org Git - thirdparty/squid.git/blob - src/AccessLogEntry.cc
Supply ALE with HttpReply before checking http_reply_access (#398)
[thirdparty/squid.git] / src / AccessLogEntry.cc
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 #include "squid.h"
10 #include "AccessLogEntry.h"
11 #include "HttpReply.h"
12 #include "HttpRequest.h"
13 #include "MemBuf.h"
14 #include "proxyp/Header.h"
15 #include "SquidConfig.h"
16 #include "ssl/support.h"
17
18 void
19 AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const
20 {
21 Ip::Address log_ip;
22
23 #if FOLLOW_X_FORWARDED_FOR
24 if (Config.onoff.log_uses_indirect_client && request)
25 log_ip = request->indirect_client_addr;
26 else
27 #endif
28 if (tcpClient)
29 log_ip = tcpClient->remote;
30 else
31 log_ip = cache.caddr;
32
33 // internally generated requests (and some ICAP) lack client IP
34 if (log_ip.isNoAddr()) {
35 strncpy(buf, "-", bufsz);
36 return;
37 }
38
39 // Apply so-called 'privacy masking' to IPv4 clients
40 // - localhost IP is always shown in full
41 // - IPv4 clients masked with client_netmask
42 // - IPv6 clients use 'privacy addressing' instead.
43
44 log_ip.applyClientMask(Config.Addrs.client_netmask);
45
46 log_ip.toStr(buf, bufsz);
47 }
48
49 SBuf
50 AccessLogEntry::getLogMethod() const
51 {
52 SBuf method;
53 if (icp.opcode)
54 method.append(icp_opcode_str[icp.opcode]);
55 else if (htcp.opcode)
56 method.append(htcp.opcode);
57 else
58 method = http.method.image();
59 return method;
60 }
61
62 void
63 AccessLogEntry::syncNotes(HttpRequest *req)
64 {
65 // XXX: auth code only has access to HttpRequest being authenticated
66 // so we must handle the case where HttpRequest is set without ALE being set.
67 assert(req);
68 if (!notes)
69 notes = req->notes();
70 else
71 assert(notes == req->notes());
72 }
73
74 const char *
75 AccessLogEntry::getClientIdent() const
76 {
77 if (tcpClient)
78 return tcpClient->rfc931;
79
80 if (cache.rfc931 && *cache.rfc931)
81 return cache.rfc931;
82
83 return nullptr;
84 }
85
86 const char *
87 AccessLogEntry::getExtUser() const
88 {
89 if (request && request->extacl_user.size())
90 return request->extacl_user.termedBuf();
91
92 if (cache.extuser && *cache.extuser)
93 return cache.extuser;
94
95 return nullptr;
96 }
97
98 AccessLogEntry::AccessLogEntry() {}
99
100 AccessLogEntry::~AccessLogEntry()
101 {
102 safe_free(headers.request);
103
104 #if USE_ADAPTATION
105 safe_free(adapt.last_meta);
106 #endif
107
108 safe_free(headers.adapted_request);
109 HTTPMSGUNLOCK(adapted_request);
110
111 safe_free(lastAclName);
112
113 HTTPMSGUNLOCK(request);
114 #if ICAP_CLIENT
115 HTTPMSGUNLOCK(icap.reply);
116 HTTPMSGUNLOCK(icap.request);
117 #endif
118 }
119
120 const SBuf *
121 AccessLogEntry::effectiveVirginUrl() const
122 {
123 const SBuf *effectiveUrl = request ? &request->effectiveRequestUri() : &virginUrlForMissingRequest_;
124 if (effectiveUrl && !effectiveUrl->isEmpty())
125 return effectiveUrl;
126 // We can not use ALE::url here because it may contain a request URI after
127 // adaptation/redirection. When the request is missing, a non-empty ALE::url
128 // means that we missed a setVirginUrlForMissingRequest() call somewhere.
129 return nullptr;
130 }
131
132 void
133 AccessLogEntry::packReplyHeaders(MemBuf &mb) const
134 {
135 if (reply)
136 reply->packHeadersUsingFastPacker(mb);
137 }
138