]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/Downloader.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / Downloader.cc
index a9320b37758c13849ee42cf9f0ee9496a23c3d83..ee5433b6581a5a5647763429807e8559b07900e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2016 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.
@@ -63,16 +63,28 @@ Downloader::CbDialer::print(std::ostream &os) const
     os << " Http Status:" << status << Raw("body data", object.rawContent(), 64).hex();
 }
 
-Downloader::Downloader(SBuf &url, AsyncCall::Pointer &aCallback, unsigned int level):
+Downloader::Downloader(SBuf &url, AsyncCall::Pointer &aCallback, const XactionInitiator initiator, unsigned int level):
     AsyncJob("Downloader"),
     url_(url),
     callback_(aCallback),
-    level_(level)
+    level_(level),
+    initiator_(initiator)
 {
 }
 
 Downloader::~Downloader()
 {
+    debugs(33, 6, this);
+}
+
+void
+Downloader::swanSong()
+{
+    debugs(33, 6, this);
+    if (context_) {
+        context_->finished();
+        context_ = nullptr;
+    }
 }
 
 bool
@@ -116,17 +128,15 @@ Downloader::buildRequest()
 {
     const HttpRequestMethod method = Http::METHOD_GET;
 
-    char *uri = xstrdup(url_.c_str());
-    HttpRequest *const request = HttpRequest::CreateFromUrl(uri, method);
+    const MasterXaction::Pointer mx = new MasterXaction(initiator_);
+    auto * const request = HttpRequest::FromUrl(url_, mx, method);
     if (!request) {
         debugs(33, 5, "Invalid URI: " << url_);
-        xfree(uri);
         return false; //earlyError(...)
     }
     request->http_ver = Http::ProtocolVersion();
     request->header.putStr(Http::HdrType::HOST, request->url.host());
     request->header.putTime(Http::HdrType::DATE, squid_curtime);
-    request->flags.internalClient = true;
     request->client_addr.setNoAddr();
 #if FOLLOW_X_FORWARDED_FOR
     request->indirect_client_addr.setNoAddr();
@@ -141,11 +151,10 @@ Downloader::buildRequest()
            "\n----------");
 
     ClientHttpRequest *const http = new ClientHttpRequest(nullptr);
-    http->request = request;
-    HTTPMSGLOCK(http->request);
+    http->initRequest(request);
     http->req_sz = 0;
-    http->uri = uri;
-    setLogUri (http, urlCanonicalClean(request));
+    // XXX: performance regression. c_str() reallocates
+    http->uri = xstrdup(url_.c_str());
 
     context_ = new DownloaderContext(this, http);
     StoreIOBuffer tempBuffer;
@@ -234,12 +243,6 @@ void
 Downloader::downloadFinished()
 {
     debugs(33, 7, this);
-    // We cannot delay http destruction until refcounting deletes
-    // DownloaderContext. The http object destruction will cause
-    // clientStream cleanup and will release the refcount to context_
-    // object hold by clientStream structures.
-    context_->finished();
-    context_ = nullptr;
     Must(done());
 }
 
@@ -256,12 +259,10 @@ Downloader::callBack(Http::StatusCode const statusCode)
     ScheduleCallHere(callback_);
     callback_ = nullptr;
 
-    // Calling deleteThis method here to finish Downloader
-    // may result to squid crash.
-    // This method called by handleReply method which maybe called
-    // by ClientHttpRequest::doCallouts. The doCallouts after this object
-    // deleted, may operate on non valid objects.
-    // Schedule an async call here just to force squid to delete this object.
+    // We cannot deleteThis() because we may be called synchronously from
+    // doCallouts() via handleReply() (XXX), and doCallouts() may crash if we
+    // disappear. Instead, schedule an async call now so that later, when the
+    // call firing code discovers a done() job, it deletes us.
     CallJobHere(33, 7, CbcPointer<Downloader>(this), Downloader, downloadFinished);
 }