/*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#include "adaptation/Config.h"
#endif
#include "CachePeer.h"
-#include "err_detail_type.h"
-#include "errorpage.h"
-#include "errorpage.h"
+#include "error/Detail.h"
#include "errorpage.h"
#include "format/Token.h"
#include "globals.h"
accessLogLogTo(CustomLog* log, AccessLogEntry::Pointer &al, ACLChecklist * checklist)
{
- if (al->url == NULL)
- al->url = dash_str;
+ if (al->url.isEmpty())
+ al->url = Format::Dash;
if (!al->http.content_type || *al->http.content_type == '\0')
al->http.content_type = dash_str;
- if (al->icp.opcode)
- al->_private.method_str = icp_opcode_str[al->icp.opcode];
- else if (al->htcp.opcode)
- al->_private.method_str = al->htcp.opcode;
- else
- al->_private.method_str = NULL;
-
if (al->hier.host[0] == '\0')
xstrncpy(al->hier.host, dash_str, SQUIDHOSTNAMELEN);
for (; log; log = log->next) {
- if (log->aclList && checklist && checklist->fastCheck(log->aclList) != ACCESS_ALLOWED)
+ if (log->aclList && checklist && !checklist->fastCheck(log->aclList).allowed())
continue;
// The special-case "none" type has no logfile object set
else {
unsigned int ibuf[365];
size_t isize;
- xstrncpy((char *) ibuf, al->url, 364 * sizeof(int));
- isize = ((strlen(al->url) + 8) / 8) * 2;
+ xstrncpy((char *) ibuf, al->url.c_str(), 364 * sizeof(int));
+ isize = ((al->url.length() + 8) / 8) * 2;
if (isize > 364)
isize = 364;
store_complete_stop.tv_sec =0;
store_complete_stop.tv_usec =0;
- peer_http_request_sent.tv_sec = 0;
- peer_http_request_sent.tv_usec = 0;
-
- peer_response_time.tv_sec = -1;
- peer_response_time.tv_usec = 0;
+ clearPeerNotes();
totalResponseTime_.tv_sec = -1;
totalResponseTime_.tv_usec = 0;
}
void
-HierarchyLogEntry::note(const Comm::ConnectionPointer &server, const char *requestedHost)
+HierarchyLogEntry::resetPeerNotes(const Comm::ConnectionPointer &server, const char *requestedHost)
{
+ clearPeerNotes();
+
tcpServer = server;
if (tcpServer == NULL) {
code = HIER_NONE;
}
}
+/// forget previous notePeerRead() and notePeerWrite() calls (if any)
+void
+HierarchyLogEntry::clearPeerNotes()
+{
+ peer_last_read_.tv_sec = 0;
+ peer_last_read_.tv_usec = 0;
+
+ peer_last_write_.tv_sec = 0;
+ peer_last_write_.tv_usec = 0;
+
+ bodyBytesRead = -1;
+}
+
+void
+HierarchyLogEntry::notePeerRead()
+{
+ peer_last_read_ = current_time;
+}
+
+void
+HierarchyLogEntry::notePeerWrite()
+{
+ peer_last_write_ = current_time;
+}
+
void
HierarchyLogEntry::startPeerClock()
{
void
HierarchyLogEntry::stopPeerClock(const bool force)
{
- debugs(46, 5, "First connection started: " << firstConnStart_.tv_sec << "." <<
- std::setfill('0') << std::setw(6) << firstConnStart_.tv_usec <<
+ debugs(46, 5, "First connection started: " << firstConnStart_ <<
", current total response time value: " << (totalResponseTime_.tv_sec * 1000 + totalResponseTime_.tv_usec/1000) <<
(force ? ", force fixing" : ""));
if (!force && totalResponseTime_.tv_sec != -1)
tvSub(totalResponseTime_, firstConnStart_, current_time);
}
-void
+bool
+HierarchyLogEntry::peerResponseTime(struct timeval &responseTime)
+{
+ // no I/O whatsoever
+ if (peer_last_write_.tv_sec <= 0 && peer_last_read_.tv_sec <= 0)
+ return false;
+
+ // accommodate read without (completed) write
+ const auto last_write = peer_last_write_.tv_sec > 0 ?
+ peer_last_write_ : peer_last_read_;
+
+ // accommodate write without (completed) read
+ const auto last_read = peer_last_read_.tv_sec > 0 ?
+ peer_last_read_ : peer_last_write_;
+
+ tvSub(responseTime, last_write, last_read);
+ // The peer response time (%<pt) stopwatch is currently defined to start
+ // when we wrote the entire request. Thus, if we wrote something after the
+ // last read, report zero peer response time.
+ if (responseTime.tv_sec < 0) {
+ responseTime.tv_sec = 0;
+ responseTime.tv_usec = 0;
+ }
+
+ return true;
+}
+
+bool
HierarchyLogEntry::totalResponseTime(struct timeval &responseTime)
{
// This should not really happen, but there may be rare code
stopPeerClock(false);
responseTime = totalResponseTime_;
+ return responseTime.tv_sec >= 0 && responseTime.tv_usec >= 0;
}
static void