1 /* 2 * Copyright (C) 1996-2021 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 "SquidConfig.h" 14 15 #if USE_OPENSSL 16 #include "ssl/support.h" 17 SslDetails()18AccessLogEntry::SslDetails::SslDetails(): user(NULL), bumpMode(::Ssl::bumpEnd) 19 { 20 } 21 #endif /* USE_OPENSSL */ 22 23 void getLogClientIp(char * buf,size_t bufsz) const24AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const 25 { 26 Ip::Address log_ip; 27 28 #if FOLLOW_X_FORWARDED_FOR 29 if (Config.onoff.log_uses_indirect_client && request) 30 log_ip = request->indirect_client_addr; 31 else 32 #endif 33 if (tcpClient) 34 log_ip = tcpClient->remote; 35 else 36 log_ip = cache.caddr; 37 38 // internally generated requests (and some ICAP) lack client IP 39 if (log_ip.isNoAddr()) { 40 strncpy(buf, "-", bufsz); 41 return; 42 } 43 44 // Apply so-called 'privacy masking' to IPv4 clients 45 // - localhost IP is always shown in full 46 // - IPv4 clients masked with client_netmask 47 // - IPv6 clients use 'privacy addressing' instead. 48 49 if (!log_ip.isLocalhost() && log_ip.isIPv4()) 50 log_ip.applyMask(Config.Addrs.client_netmask); 51 52 log_ip.toStr(buf, bufsz); 53 } 54 55 SBuf getLogMethod() const56AccessLogEntry::getLogMethod() const 57 { 58 SBuf method; 59 if (icp.opcode) 60 method.append(icp_opcode_str[icp.opcode]); 61 else if (htcp.opcode) 62 method.append(htcp.opcode); 63 else 64 method = http.method.image(); 65 return method; 66 } 67 68 const char * getClientIdent() const69AccessLogEntry::getClientIdent() const 70 { 71 if (tcpClient) 72 return tcpClient->rfc931; 73 74 if (cache.rfc931 && *cache.rfc931) 75 return cache.rfc931; 76 77 return nullptr; 78 } 79 80 const char * getExtUser() const81AccessLogEntry::getExtUser() const 82 { 83 if (request && request->extacl_user.size()) 84 return request->extacl_user.termedBuf(); 85 86 if (cache.extuser && *cache.extuser) 87 return cache.extuser; 88 89 return nullptr; 90 } 91 ~AccessLogEntry()92AccessLogEntry::~AccessLogEntry() 93 { 94 safe_free(headers.request); 95 96 #if USE_ADAPTATION 97 safe_free(adapt.last_meta); 98 #endif 99 100 safe_free(headers.reply); 101 102 safe_free(headers.adapted_request); 103 HTTPMSGUNLOCK(adapted_request); 104 105 safe_free(lastAclName); 106 107 HTTPMSGUNLOCK(reply); 108 HTTPMSGUNLOCK(request); 109 #if ICAP_CLIENT 110 HTTPMSGUNLOCK(icap.reply); 111 HTTPMSGUNLOCK(icap.request); 112 #endif 113 } 114 115 const SBuf * effectiveVirginUrl() const116AccessLogEntry::effectiveVirginUrl() const 117 { 118 const SBuf *effectiveUrl = request ? &request->effectiveRequestUri() : &virginUrlForMissingRequest_; 119 if (effectiveUrl && !effectiveUrl->isEmpty()) 120 return effectiveUrl; 121 // We can not use ALE::url here because it may contain a request URI after 122 // adaptation/redirection. When the request is missing, a non-empty ALE::url 123 // means that we missed a setVirginUrlForMissingRequest() call somewhere. 124 return nullptr; 125 } 126 127