]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/MemObject.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / MemObject.cc
index a5f90fd1d5f5662b70cbb17edde2c473f1c38cea..00fc25589bceffcd8a17bceea98669de59e51d39 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -13,7 +13,6 @@
 #include "Generic.h"
 #include "globals.h"
 #include "HttpReply.h"
-#include "HttpRequest.h"
 #include "MemBuf.h"
 #include "MemObject.h"
 #include "profiler/Profiler.h"
@@ -77,7 +76,11 @@ MemObject::hasUris() const
 void
 MemObject::setUris(char const *aStoreId, char const *aLogUri, const HttpRequestMethod &aMethod)
 {
+    if (hasUris())
+        return;
+
     storeId_ = aStoreId;
+    debugs(88, 3, this << " storeId: " << storeId_);
 
     // fast pointer comparison for a common storeCreateEntry(url,url,...) case
     if (!aLogUri || aLogUri == aStoreId)
@@ -92,31 +95,17 @@ MemObject::setUris(char const *aStoreId, char const *aLogUri, const HttpRequestM
 #endif
 }
 
-MemObject::MemObject() :
-    inmem_lo(0),
-    nclients(0),
-    smpCollapsed(false),
-    request(NULL),
-    ping_reply_callback(NULL),
-    ircb_data(NULL),
-    id(0),
-    object_sz(-1),
-    swap_hdr_sz(0),
-#if URL_CHECKSUM_DEBUG
-    chksum(0),
-#endif
-    vary_headers(NULL)
+MemObject::MemObject()
 {
-    debugs(20, 3, "new MemObject " << this);
+    debugs(20, 3, "MemObject constructed, this=" << this);
+    ping_reply_callback = nullptr;
     memset(&start_ping, 0, sizeof(start_ping));
-    memset(&abort, 0, sizeof(abort));
-    _reply = new HttpReply;
-    HTTPMSGLOCK(_reply);
+    reply_ = new HttpReply;
 }
 
 MemObject::~MemObject()
 {
-    debugs(20, 3, "del MemObject " << this);
+    debugs(20, 3, "MemObject destructed, this=" << this);
     const Ctx ctx = ctx_enter(hasUris() ? urlXXX() : "[unknown_ctx]");
 
 #if URL_CHECKSUM_DEBUG
@@ -140,19 +129,22 @@ MemObject::~MemObject()
 
 #endif
 
-    HTTPMSGUNLOCK(_reply);
-
-    HTTPMSGUNLOCK(request);
-
     ctx_exit(ctx);              /* must exit before we free mem->url */
+}
 
-    safe_free(vary_headers);
+HttpReply &
+MemObject::adjustableBaseReply()
+{
+    assert(!updatedReply_);
+    return *reply_;
 }
 
 void
-MemObject::unlinkRequest()
+MemObject::replaceBaseReply(const HttpReplyPointer &r)
 {
-    HTTPMSGUNLOCK(request);
+    assert(r);
+    reply_ = r;
+    updatedReply_ = nullptr;
 }
 
 void
@@ -183,26 +175,14 @@ MemObject::dump() const
     debugs(20, DBG_IMPORTANT, "MemObject->inmem_hi: " << data_hdr.endOffset());
     debugs(20, DBG_IMPORTANT, "MemObject->inmem_lo: " << inmem_lo);
     debugs(20, DBG_IMPORTANT, "MemObject->nclients: " << nclients);
-    debugs(20, DBG_IMPORTANT, "MemObject->reply: " << _reply);
+    debugs(20, DBG_IMPORTANT, "MemObject->reply: " << reply_);
+    debugs(20, DBG_IMPORTANT, "MemObject->updatedReply: " << updatedReply_);
+    debugs(20, DBG_IMPORTANT, "MemObject->appliedUpdates: " << appliedUpdates);
     debugs(20, DBG_IMPORTANT, "MemObject->request: " << request);
     debugs(20, DBG_IMPORTANT, "MemObject->logUri: " << logUri_);
     debugs(20, DBG_IMPORTANT, "MemObject->storeId: " << storeId_);
 }
 
-HttpReply const *
-MemObject::getReply() const
-{
-    return _reply;
-}
-
-void
-MemObject::replaceHttpReply(HttpReply *newrep)
-{
-    HTTPMSGUNLOCK(_reply);
-    _reply = newrep;
-    HTTPMSGLOCK(_reply);
-}
-
 struct LowestMemReader : public unary_function<store_client, void> {
     LowestMemReader(int64_t seed):current(seed) {}
 
@@ -230,8 +210,8 @@ void
 MemObject::stat(MemBuf * mb) const
 {
     mb->appendf("\t" SQUIDSBUFPH " %s\n", SQUIDSBUFPRINT(method.image()), logUri());
-    if (vary_headers)
-        mb->appendf("\tvary_headers: %s\n", vary_headers);
+    if (!vary_headers.isEmpty())
+        mb->appendf("\tvary_headers: " SQUIDSBUFPH "\n", SQUIDSBUFPRINT(vary_headers));
     mb->appendf("\tinmem_lo: %" PRId64 "\n", inmem_lo);
     mb->appendf("\tinmem_hi: %" PRId64 "\n", data_hdr.endOffset());
     mb->appendf("\tswapout: %" PRId64 " bytes queued\n", swapout.queue_offset);
@@ -245,8 +225,6 @@ MemObject::stat(MemBuf * mb) const
         mb->appendf("\tmem-cache index: %d state: %d offset: %" PRId64 "\n", memCache.index, memCache.io, memCache.offset);
     if (object_sz >= 0)
         mb->appendf("\tobject_sz: %" PRId64 "\n", object_sz);
-    if (smpCollapsed)
-        mb->appendf("\tsmp-collapsed\n");
 
     StoreClientStats statsVisitor(mb);
 
@@ -264,8 +242,8 @@ MemObject::markEndOfReplyHeaders()
 {
     const int hdr_sz = endOffset();
     assert(hdr_sz >= 0);
-    assert(_reply);
-    _reply->hdr_sz = hdr_sz;
+    assert(reply_);
+    reply_->hdr_sz = hdr_sz;
 }
 
 int64_t
@@ -280,18 +258,27 @@ MemObject::size() const
 int64_t
 MemObject::expectedReplySize() const
 {
-    debugs(20, 7, HERE << "object_sz: " << object_sz);
-    if (object_sz >= 0) // complete() has been called; we know the exact answer
+    if (object_sz >= 0) {
+        debugs(20, 7, object_sz << " frozen by complete()");
         return object_sz;
+    }
+
+    const auto hdr_sz = baseReply().hdr_sz;
 
-    if (_reply) {
-        const int64_t clen = _reply->bodySize(method);
-        debugs(20, 7, HERE << "clen: " << clen);
-        if (clen >= 0 && _reply->hdr_sz > 0) // yuck: HttpMsg sets hdr_sz to 0
-            return clen + _reply->hdr_sz;
+    // Cannot predict future length using an empty/unset or HTTP/0 reply.
+    // For any HTTP/1 reply, hdr_sz is positive  -- status-line cannot be empty.
+    if (hdr_sz <= 0)
+        return -1;
+
+    const auto clen = baseReply().bodySize(method);
+    if (clen < 0) {
+        debugs(20, 7, "unknown; hdr: " << hdr_sz);
+        return -1;
     }
 
-    return -1; // not enough information to predict
+    const auto messageSize = clen + hdr_sz;
+    debugs(20, 7, messageSize << " hdr: " << hdr_sz << " clen: " << clen);
+    return messageSize;
 }
 
 void
@@ -301,6 +288,10 @@ MemObject::reset()
     data_hdr.freeContent();
     inmem_lo = 0;
     /* Should we check for clients? */
+    assert(reply_);
+    reply_->reset();
+    updatedReply_ = nullptr;
+    appliedUpdates = false;
 }
 
 int64_t
@@ -317,11 +308,12 @@ MemObject::lowestMemReaderOffset() const
 bool
 MemObject::readAheadPolicyCanRead() const
 {
-    const bool canRead = endOffset() - getReply()->hdr_sz <
+    const auto savedHttpHeaders = baseReply().hdr_sz;
+    const bool canRead = endOffset() - savedHttpHeaders <
                          lowestMemReaderOffset() + Config.readAheadGap;
 
     if (!canRead) {
-        debugs(19, 9, "no: " << endOffset() << '-' << getReply()->hdr_sz <<
+        debugs(19, 5, "no: " << endOffset() << '-' << savedHttpHeaders <<
                " < " << lowestMemReaderOffset() << '+' << Config.readAheadGap);
     }
 
@@ -464,6 +456,14 @@ MemObject::setNoDelay(bool const newValue)
 void
 MemObject::delayRead(DeferredRead const &aRead)
 {
+#if USE_DELAY_POOLS
+    if (readAheadPolicyCanRead()) {
+        if (DelayId mostAllowedId = mostBytesAllowed()) {
+            mostAllowedId.delayRead(aRead);
+            return;
+        }
+    }
+#endif
     deferredReads.delayRead(aRead);
 }