]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Add transaction_initiator ACL for detecting various unusual transactions
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Sun, 25 Jun 2017 02:23:07 +0000 (14:23 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Sun, 25 Jun 2017 02:23:07 +0000 (14:23 +1200)
This ACL is essential in several use cases, including:

* After fetching a missing intermediate certificate, Squid uses the
  regular cache (and regular caching rules) to store the response. Squid
  deployments that do not want to cache regular traffic need to cache
  fetched certificates and only them.

  acl fetched_certificate transaction_initiator certificate-fetching
  cache allow fetched_certificate
  cache deny all

* Many traffic policies and tools assume the existence of an HTTP client
  behind every transaction. Internal Squid requests violate that
  assumption. Identifying internal requests protects external ACLs, log
  analyzers, and other mechanisms from the transactions they mishandle.

  acl skip_logging transaction_initiator internal
  access_log ... !skip_logging

The new transaction_initiator ACL classifies transactions based on their
initiator. Currently supported initiators are esi, certificate-fetching,
cache-digest, internal, client, and all. In the future, the same ACL
will be able to identify HTTP/2 push transactions using the "server"
initiator. See src/cf.data.pre for details.

This is a Measurement Factory project.

42 files changed:
src/AclRegs.cc
src/Downloader.cc
src/Downloader.h
src/HttpRequest.cc
src/HttpRequest.h
src/Makefile.am
src/MasterXaction.h
src/PeerPoolMgr.cc
src/RequestFlags.h
src/XactionInitiator.cc [new file with mode: 0644]
src/XactionInitiator.h [new file with mode: 0644]
src/acl/Asn.cc
src/acl/Makefile.am
src/acl/TransactionInitiator.cc [new file with mode: 0644]
src/acl/TransactionInitiator.h [new file with mode: 0644]
src/adaptation/ecap/Host.cc
src/adaptation/ecap/XactionRep.cc
src/adaptation/icap/ModXact.cc
src/adaptation/icap/Xaction.cc
src/cf.data.pre
src/client_side.cc
src/client_side.h
src/client_side_reply.cc
src/client_side_request.cc
src/client_side_request.h
src/comm/TcpAcceptor.cc
src/esi/Include.cc
src/htcp.cc
src/icmp/net_db.cc
src/icp_v2.cc
src/mgr/Inquirer.cc
src/mime.cc
src/neighbors.cc
src/peer_digest.cc
src/security/PeerConnector.cc
src/servers/FtpServer.cc
src/servers/Http1Server.cc
src/servers/Server.h
src/store_digest.cc
src/tests/stub_HttpRequest.cc
src/tests/testHttpRequest.cc
src/urn.cc

index 026f4b09fe27c34a54705e98ee5a13ec83c27ec0..d79e0994eca4021b832bfb9661ec2ff2aa365cdf 100644 (file)
@@ -84,6 +84,7 @@
 #include "acl/Tag.h"
 #include "acl/Time.h"
 #include "acl/TimeData.h"
+#include "acl/TransactionInitiator.h"
 #include "acl/Url.h"
 #include "acl/UrlLogin.h"
 #include "acl/UrlPath.h"
@@ -150,6 +151,7 @@ Acl::Init()
     RegisterMaker("tag", [](TypeName name)->ACL* { return new ACLStrategised<const char *>(new ACLStringData, new ACLTagStrategy, name); });
     RegisterMaker("note", [](TypeName name)->ACL* { return new ACLStrategised<NotePairs::Entry*>(new ACLNoteData, new ACLNoteStrategy, name); });
     RegisterMaker("has", [](TypeName name)->ACL* {return new ACLStrategised<ACLChecklist *>(new ACLHasComponentData, new ACLHasComponentStrategy, name); });
+    RegisterMaker("transaction_initiator", [](TypeName name)->ACL* {return new Acl::TransactionInitiator(name);});
 
 #if USE_OPENSSL
     RegisterMaker("ssl_error", [](TypeName name)->ACL* { return new ACLStrategised<const Security::CertErrors *>(new ACLSslErrorData, new ACLSslErrorStrategy, name); });
index 38904a75fca3c9f2cfc12a1cb1d7691ed5cde0fd..e153861d97589014791ef555347c8c8bd87586c8 100644 (file)
@@ -63,11 +63,12 @@ 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)
 {
 }
 
@@ -128,7 +129,8 @@ 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_);
+    HttpRequest *const request = HttpRequest::FromUrl(uri, mx, method);
     if (!request) {
         debugs(33, 5, "Invalid URI: " << url_);
         xfree(uri);
@@ -137,7 +139,6 @@ Downloader::buildRequest()
     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();
index 7f8dca42e83c35cd86e4adeb9a75b5d401620051..5f8e24bd859c1db60be94f6e3d23c65af2eb6344 100644 (file)
@@ -14,6 +14,7 @@
 #include "http/forward.h"
 #include "http/StatusCode.h"
 #include "sbuf/SBuf.h"
+#include "XactionInitiator.h"
 
 class ClientHttpRequest;
 class StoreIOBuffer;
@@ -45,7 +46,7 @@ public:
         Http::StatusCode status;
     };
 
-    Downloader(SBuf &url, AsyncCall::Pointer &aCallback, unsigned int level = 0);
+    Downloader(SBuf &url, AsyncCall::Pointer &aCallback, const XactionInitiator initiator, unsigned int level = 0);
     virtual ~Downloader();
     virtual void swanSong();
 
@@ -75,6 +76,8 @@ private:
     AsyncCall::Pointer callback_; ///< callback to call when download finishes
     SBuf object_; ///< the object body data
     const unsigned int level_; ///< holds the nested downloads level
+    /// The initiator of the download request.
+    XactionInitiator initiator_;
 
     /// Pointer to an object that stores the clientStream required info
     DownloaderContextPointer context_;
index 0b68e29e945ec160fbe52c80b5fba5d1b08fedd0..a437b21d40d535274f534172d97b6d7d1fc151a1 100644 (file)
 #include "adaptation/icap/icap_log.h"
 #endif
 
-HttpRequest::HttpRequest() :
-    HttpMsg(hoRequest)
+HttpRequest::HttpRequest(const MasterXaction::Pointer &mx) :
+    HttpMsg(hoRequest),
+    masterXaction(mx)
 {
+    assert(mx);
     init();
 }
 
-HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath) :
-    HttpMsg(hoRequest)
+HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath, const MasterXaction::Pointer &mx) :
+    HttpMsg(hoRequest),
+    masterXaction(mx)
 {
+    assert(mx);
     static unsigned int id = 1;
     debugs(93,7, HERE << "constructed, this=" << this << " id=" << ++id);
     init();
@@ -170,7 +174,7 @@ HttpRequest::reset()
 HttpRequest *
 HttpRequest::clone() const
 {
-    HttpRequest *copy = new HttpRequest();
+    HttpRequest *copy = new HttpRequest(masterXaction);
     copy->method = method;
     // TODO: move common cloning clone to Msg::copyTo() or copy ctor
     copy->header.append(&header);
@@ -515,9 +519,9 @@ HttpRequest::expectingBody(const HttpRequestMethod &, int64_t &theSize) const
  * If the request cannot be created cleanly, NULL is returned
  */
 HttpRequest *
-HttpRequest::CreateFromUrl(char * url, const HttpRequestMethod& method)
+HttpRequest::FromUrl(char * url, const MasterXaction::Pointer &mx, const HttpRequestMethod& method)
 {
-    std::unique_ptr<HttpRequest> req(new HttpRequest());
+    std::unique_ptr<HttpRequest> req(new HttpRequest(mx));
     if (urlParse(method, url, *req))
         return req.release();
     return nullptr;
index a43a07ce48e116de90b2a8e9f7c7550f94d35be9..5f445ab632f9b58896a6aa625fbdf1e899660bb8 100644 (file)
@@ -15,6 +15,7 @@
 #include "HierarchyLogEntry.h"
 #include "http/RequestMethod.h"
 #include "HttpMsg.h"
+#include "MasterXaction.h"
 #include "Notes.h"
 #include "RequestFlags.h"
 #include "URL.h"
@@ -48,8 +49,8 @@ class HttpRequest: public HttpMsg
 public:
     typedef RefCount<HttpRequest> Pointer;
 
-    HttpRequest();
-    HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *schemeImage, const char *aUrlpath);
+    HttpRequest(const MasterXaction::Pointer &);
+    HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *schemeImage, const char *aUrlpath, const MasterXaction::Pointer &);
     ~HttpRequest();
     virtual void reset();
 
@@ -195,7 +196,7 @@ public:
 
     static void httpRequestPack(void *obj, Packable *p);
 
-    static HttpRequest * CreateFromUrl(char * url, const HttpRequestMethod &method = Http::METHOD_GET);
+    static HttpRequest * FromUrl(char * url, const MasterXaction::Pointer &, const HttpRequestMethod &method = Http::METHOD_GET);
 
     ConnStateData *pinnedConnection();
 
@@ -216,6 +217,9 @@ public:
     /// The Downloader object which initiated the HTTP request if any
     CbcPointer<Downloader> downloader;
 
+    /// the master transaction this request belongs to. Never nil.
+    MasterXaction::Pointer masterXaction;
+
     /// forgets about the cached Range header (for a reason)
     void ignoreRange(const char *reason);
     int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */
index a8a58e3a32862428778c748ebe49d25dcc09e7d6..578b747437ea0796c2ecbdeaf2d8f000d8b315b7 100644 (file)
@@ -483,6 +483,8 @@ squid_SOURCES = \
        whois.cc \
        wordlist.h \
        wordlist.cc \
+       XactionInitiator.h \
+       XactionInitiator.cc \
        $(WIN32_SOURCE) \
        $(WINSVC_SOURCE)
 
index 5554861d02c73681df98d4167b31043a021343b7..5aa8822a7fad484b64eb4566b9341b67353bcd42 100644 (file)
 #define SQUID_SRC_MASTERXACTION_H
 
 #include "anyp/forward.h"
+#include "anyp/PortCfg.h"
 #include "base/InstanceId.h"
 #include "base/Lock.h"
+#include "base/RefCount.h"
 #include "comm/forward.h"
+#include "XactionInitiator.h"
 
 /** Master transaction details.
  *
@@ -38,6 +41,8 @@ class MasterXaction : public RefCountable
 public:
     typedef RefCount<MasterXaction> Pointer;
 
+    explicit MasterXaction(const XactionInitiator anInitiator) : initiator(anInitiator) {};
+
     /// transaction ID.
     InstanceId<MasterXaction> id;
 
@@ -47,6 +52,9 @@ public:
     /// the client TCP connection which originated this transaction
     Comm::ConnectionPointer tcpClient;
 
+    /// the initiator of this transaction
+    XactionInitiator initiator;
+
     // TODO: add state from other Jobs in the transaction
 };
 
index a422a06ec8734b1b26fe465bc1e54ca639cc0b3c..5329ff0a919a76f9f40b623f4909c1342f7be527 100644 (file)
@@ -18,6 +18,7 @@
 #include "FwdState.h"
 #include "globals.h"
 #include "HttpRequest.h"
+#include "MasterXaction.h"
 #include "neighbors.h"
 #include "pconn.h"
 #include "PeerPoolMgr.h"
@@ -59,9 +60,10 @@ PeerPoolMgr::start()
 {
     AsyncJob::start();
 
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerPool);
     // ErrorState, getOutgoingAddress(), and other APIs may require a request.
     // We fake one. TODO: Optionally send this request to peers?
-    request = new HttpRequest(Http::METHOD_OPTIONS, AnyP::PROTO_HTTP, "http", "*");
+    request = new HttpRequest(Http::METHOD_OPTIONS, AnyP::PROTO_HTTP, "http", "*", mx);
     request->url.host(peer->host);
 
     checkpoint("peer initialized");
index 9ef3af70669d37146518c72639a9e31eb24797be..353186d01cefa60758f3e67ce7d62125563e6597 100644 (file)
@@ -72,9 +72,6 @@ public:
     bool spoofClientIp = false;
     /** set if the request is internal (\see ClientHttpRequest::flags.internal)*/
     bool internal = false;
-    //XXX this is set in in clientBeginRequest, but never tested.
-    /** set for internally-generated requests */
-    bool internalClient = false;
     /** if set, request to try very hard to keep the connection alive */
     bool mustKeepalive = false;
     /** set if the rquest wants connection oriented auth */
diff --git a/src/XactionInitiator.cc b/src/XactionInitiator.cc
new file mode 100644 (file)
index 0000000..a272c51
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "cache_cf.h"
+#include "Debug.h"
+#include "XactionInitiator.h"
+
+#include <map>
+#include <string>
+
+XactionInitiator::Initiators
+XactionInitiator::ParseInitiators(const char *name)
+{
+    typedef std::map<std::string, XactionInitiator::Initiators> InitiatorsMap;
+    static InitiatorsMap SupportedInitiators = {
+        {"client", initClient},
+        {"peer-pool", initPeerPool},
+        {"certificate-fetching", initCertFetcher},
+        {"esi", initEsi},
+        {"cache-digest", initCacheDigest},
+        {"server", initServer},
+        {"htcp", initHtcp},
+        {"icp", initIcp},
+        {"icmp", initIcmp},
+        {"asn", initAsn},
+        {"ipc", initIpc},
+        {"adaptation", initAdaptation},
+        {"icon", initIcon},
+        {"peer-mcast", initPeerMcast},
+        {"internal", InternalInitiators()},
+        {"all", AllInitiators()}
+    };
+    const auto it = SupportedInitiators.find(name);
+    if (it != SupportedInitiators.cend())
+        return it->second;
+
+    debugs(28, DBG_CRITICAL, "FATAL: Invalid transaction_initiator value near " << name);
+    self_destruct();
+    return 0;
+}
+
diff --git a/src/XactionInitiator.h b/src/XactionInitiator.h
new file mode 100644 (file)
index 0000000..d84d9f8
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_SRC_XACTION_INITIATOR_H
+#define SQUID_SRC_XACTION_INITIATOR_H
+
+/// identifies a protocol agent or Squid feature initiating transactions
+class XactionInitiator {
+public:
+    /// transaction triggers
+    enum Initiator {
+        initUnknown = 0,
+        initClient = 1 << 0, ///< HTTP or FTP client
+        initPeerPool = 1 << 1, ///< PeerPool manager
+        initCertFetcher = 1 << 2, ///< Missing intermediate certificates fetching code
+        initEsi = 1 << 3, ///< ESI processing code
+        initCacheDigest = 1 << 4, ///< Cache Digest fetching code
+        initHtcp = 1<< 5, ///< HTCP client
+        initIcp = 1 << 6, ///< the ICP/neighbors subsystem
+        initIcmp = 1 << 7, ///< the ICMP RTT database (NetDB) neighbors exchange subsystem
+        initAsn = 1 << 8, ///< the ASN db subsystem
+        initIpc = 1 << 9, ///< the IPC subsystem
+        initAdaptation = 1 << 10,  ///< ICAP/ECAP requests generated by Squid
+        initIcon = 1 << 11, ///< internal icons
+        initPeerMcast = 1 << 12, ///< neighbor multicast
+        initServer = 1 << 13, ///< HTTP/2 push request (not yet supported by Squid)
+
+        initAdaptationOrphan_ = 1 << 31 ///< eCAP-created HTTP message w/o an associated HTTP transaction (not ACL-detectable)
+    };
+
+    typedef uint32_t Initiators; ///< Initiator set
+
+    // this class is a just a trivial wrapper so we allow explicit conversions
+    XactionInitiator(Initiator i) : initiator(i) {}
+
+    /// whether this initiator belongs to the given set
+    bool in(Initiators setOfInitiators) const {return (initiator & setOfInitiators) != 0;}
+
+    /// whether the transaction was initiated by an internal subsystem
+    bool internalClient() const {
+        return (initiator & InternalInitiators()) != 0;
+    }
+
+    /// internally generated requests
+    static Initiators InternalInitiators() {
+        return initPeerPool | initCertFetcher | initEsi | initCacheDigest | initIcp | initIcmp | initIpc | initAdaptation | initIcon | initPeerMcast;
+    }
+
+    /// all initiators
+    static Initiators AllInitiators() {
+        return 0xFFFFFFFF;
+    }
+
+    static Initiators ParseInitiators(const char *name);
+
+private:
+    XactionInitiator() {}
+
+    Initiator initiator;
+};
+
+#endif // SQUID_SRC_XACTION_INITIATOR_H
+
index 5707ea1ac8f0a548b6c51ae6e258caed29b34d86..c152f29bf3d2f4974476745b432c77aec14bf1d4 100644 (file)
@@ -20,6 +20,7 @@
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "ipcache.h"
+#include "MasterXaction.h"
 #include "mgr/Registration.h"
 #include "radix.h"
 #include "RequestFlags.h"
@@ -240,7 +241,8 @@ asnCacheStart(int as)
     debugs(53, 3, "AS " << as);
     snprintf(asres, 4096, "whois://%s/!gAS%d", Config.as_whois_server, as);
     asState->as_number = as;
-    asState->request = HttpRequest::CreateFromUrl(asres);
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAsn);
+    asState->request = HttpRequest::FromUrl(asres, mx);
     assert(asState->request != NULL);
 
     if ((e = storeGetPublic(asres, Http::METHOD_GET)) == NULL) {
index d2dbf014f0b83f7086a97284cd1f839eb7a2c5f3..6d540fa0655cc50d89352fa9d4f8431883baf850 100644 (file)
@@ -127,6 +127,8 @@ libacls_la_SOURCES = \
        SquidErrorData.h \
        Tag.cc \
        Tag.h \
+       TransactionInitiator.cc \
+       TransactionInitiator.h \
        Url.cc \
        Url.h \
        UrlLogin.cc \
diff --git a/src/acl/TransactionInitiator.cc b/src/acl/TransactionInitiator.cc
new file mode 100644 (file)
index 0000000..b2e0d63
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+/* DEBUG: section 28    Access Control */
+
+#include "squid.h"
+#include "acl/FilledChecklist.h"
+#include "acl/TransactionInitiator.h"
+#include "cache_cf.h"
+#include "Debug.h"
+#include "HttpRequest.h"
+#include "MasterXaction.h"
+#include "SquidConfig.h"
+
+ACL *
+Acl::TransactionInitiator::clone() const
+{
+    return new Acl::TransactionInitiator(*this);
+}
+
+Acl::TransactionInitiator::TransactionInitiator (const char *aClass) : class_ (aClass), initiators_(0)
+{}
+
+char const *
+Acl::TransactionInitiator::typeString() const
+{
+    return class_;
+}
+
+bool
+Acl::TransactionInitiator::empty () const
+{
+    return false;
+}
+
+void
+Acl::TransactionInitiator::parse()
+{
+    while (const char *s = ConfigParser::strtokFile()) {
+        initiators_ |= XactionInitiator::ParseInitiators(s);
+        cfgWords.push_back(SBuf(s));
+    }
+}
+
+int
+Acl::TransactionInitiator::match(ACLChecklist *checklist)
+{
+    ACLFilledChecklist *filled = Filled((ACLChecklist*)checklist);
+    assert(filled->request);
+    assert(filled->request->masterXaction);
+    const XactionInitiator requestInitiator = filled->request->masterXaction->initiator;
+    return requestInitiator.in(initiators_) ? 1 : 0;
+}
+
+SBufList
+Acl::TransactionInitiator::dump() const
+{
+    return cfgWords;
+}
+
diff --git a/src/acl/TransactionInitiator.h b/src/acl/TransactionInitiator.h
new file mode 100644 (file)
index 0000000..ff8ff0b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_ACL_TRANSACTION_INITIATOR_H
+#define SQUID_ACL_TRANSACTION_INITIATOR_H
+
+#include "acl/Acl.h"
+#include "acl/Checklist.h"
+#include "XactionInitiator.h"
+
+namespace Acl
+{
+
+/// transaction_initiator ACL
+class TransactionInitiator : public ACL
+{
+    MEMPROXY_CLASS(TransactionInitiator);
+
+public:
+    TransactionInitiator(char const *);
+
+    virtual ACL *clone()const;
+    virtual char const *typeString() const;
+    virtual void parse();
+    virtual int match(ACLChecklist *checklist);
+    virtual bool requiresRequest() const { return true; }
+    virtual SBufList dump() const;
+    virtual bool empty () const;
+
+protected:
+    char const *class_;
+    XactionInitiator::Initiators initiators_;
+    SBufList cfgWords; /// initiator names in the configured order
+};
+
+} // namespace Acl
+
+#endif /* SQUID_ACL_TRANSACTION_INITIATOR_H */
+
index 705651f08fa569777e952fc2d8f0f4983d192d77..3f906c0d2836ed2fe8436b6fc2268b40f6f022d9 100644 (file)
@@ -18,6 +18,7 @@
 #include "base/TextException.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
+#include "MasterXaction.h"
 
 const libecap::Name Adaptation::Ecap::protocolInternal("internal", libecap::Name::NextId());
 const libecap::Name Adaptation::Ecap::protocolCacheObj("cache_object", libecap::Name::NextId());
@@ -162,7 +163,8 @@ Adaptation::Ecap::Host::closeDebug(std::ostream *debug)
 Adaptation::Ecap::Host::MessagePtr
 Adaptation::Ecap::Host::newRequest() const
 {
-    return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest));
+    static const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptationOrphan_);
+    return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest(mx)));
 }
 
 Adaptation::Ecap::Host::MessagePtr
index c330a9832bc69c8be1d2f35cb823c5f7c49eb09f..c2a345cd1fb238b0b05254bc7a7ae9d1e105dd2c 100644 (file)
@@ -23,6 +23,7 @@
 #include "format/Format.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
+#include "MasterXaction.h"
 #include "SquidTime.h"
 
 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Ecap::XactionRep, XactionRep);
@@ -738,5 +739,13 @@ void
 Adaptation::Ecap::XactionRep::updateSources(HttpMsg *adapted)
 {
     adapted->sources |= service().cfg().connectionEncryption ? HttpMsg::srcEcaps : HttpMsg::srcEcap;
+
+    // Update masterXaction object for adapted HTTP requests.
+    if (HttpRequest *adaptedReq = dynamic_cast<HttpRequest*>(adapted)) {
+        HttpRequest *request = dynamic_cast<HttpRequest*> (theCauseRep ?
+                               theCauseRep->raw().header : theVirginRep.raw().header);
+        Must(request);
+        adaptedReq->masterXaction = request->masterXaction;
+    }
 }
 
index 153e8fa8e4d5892f158fa6816cb8471feaa0e609..10f80ded4d843f3aa358e52faccce75bb83c132f 100644 (file)
@@ -30,6 +30,7 @@
 #include "HttpMsg.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
+#include "MasterXaction.h"
 #include "SquidTime.h"
 #include "URL.h"
 
@@ -734,7 +735,7 @@ void Adaptation::Icap::ModXact::maybeAllocateHttpMsg()
         setOutcome(service().cfg().method == ICAP::methodReqmod ?
                    xoSatisfied : xoModified);
     } else if (gotEncapsulated("req-hdr")) {
-        adapted.setHeader(new HttpRequest);
+        adapted.setHeader(new HttpRequest(virginRequest().masterXaction));
         setOutcome(xoModified);
     } else
         throw TexcHere("Neither res-hdr nor req-hdr in maybeAllocateHttpMsg()");
@@ -961,8 +962,8 @@ void Adaptation::Icap::ModXact::prepEchoing()
     Must(!adapted.header);
     {
         HttpMsg::Pointer newHead;
-        if (dynamic_cast<const HttpRequest*>(oldHead)) {
-            newHead = new HttpRequest;
+        if (const HttpRequest *r = dynamic_cast<const HttpRequest*>(oldHead)) {
+            newHead = new HttpRequest(r->masterXaction);
         } else if (dynamic_cast<const HttpReply*>(oldHead)) {
             newHead = new HttpReply;
         }
@@ -1547,8 +1548,8 @@ void Adaptation::Icap::ModXact::encapsulateHead(MemBuf &icapBuf, const char *sec
     HttpMsg::Pointer headClone;
 
     if (const HttpRequest* old_request = dynamic_cast<const HttpRequest*>(head)) {
-        HttpRequest::Pointer new_request(new HttpRequest);
-        // copy the requst-line details
+        HttpRequest::Pointer new_request(new HttpRequest(old_request->masterXaction));
+         // copy the requst-line details
         new_request->method = old_request->method;
         new_request->url = old_request->url;
         new_request->http_ver = old_request->http_ver;
index cb9b4bfa409547f28e0a35043616518467a29e4e..9d2d99c849690baa0a89859622fce24d73e63686 100644 (file)
@@ -99,7 +99,8 @@ Adaptation::Icap::Xaction::Xaction(const char *aTypeName, Adaptation::Icap::Serv
 {
     debugs(93,3, typeName << " constructed, this=" << this <<
            " [icapx" << id << ']'); // we should not call virtual status() here
-    icapRequest = new HttpRequest;
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptation);
+    icapRequest = new HttpRequest(mx);
     HTTPMSGLOCK(icapRequest);
     icap_tr_start = current_time;
     memset(&icap_tio_start, 0, sizeof(icap_tio_start));
index ccaf00c6f2757189a1861057d397a8298c72e614..d4c5ca7e14e12d82d98932e07254f8b5dc141da7 100644 (file)
@@ -1242,6 +1242,28 @@ DOC_START
          # adaptation_meta because it starts matching immediately after
          # the service has been selected for adaptation.
 
+       acl aclname transaction_initiator initiator ...
+         # Matches transaction's initiator [fast]
+         #
+         # Supported initiators are:
+         #  esi: matches transactions fetching ESI resources
+         #  certificate-fetching: matches transactions fetching
+         #     a missing intermediate TLS certificate
+         #  cache-digest: matches transactions fetching Cache Digests
+         #     from a cache_peer
+         #  htcp: matches HTCP requests from peers
+         #  icp: matches ICP requests to peers
+         #  icmp: matches ICMP RTT database (NetDB) requests to peers
+         #  asn: matches asns db requests
+         #  internal: matches any of the above
+         #  client: matches transactions containing an HTTP or FTP
+         #     client request received at a Squid *_port
+         #  all: matches any transaction, including internal transactions
+         #     without a configurable initiator and hopefully rare
+         #     transactions without a known-to-Squid initiator
+         #
+         # Multiple initiators are ORed.
+
        acl aclname has component
          # matches a transaction "component" [fast]
          #
index 25e7e7200d8b0d38825e70ae7328416b3d5657ea..6ac4583b88f46f3fc8fb04ba1796be986cc54b12 100644 (file)
@@ -2793,9 +2793,11 @@ ConnStateData::postHttpsAccept()
             return;
         }
 
+        MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+        mx->tcpClient = clientConnection;
         // Create a fake HTTP request for ssl_bump ACL check,
         // using tproxy/intercept provided destination IP and port.
-        HttpRequest *request = new HttpRequest();
+        HttpRequest *request = new HttpRequest(mx);
         static char ip[MAX_IPSTRLEN];
         assert(clientConnection->flags & (COMM_TRANSPARENT | COMM_INTERCEPTION));
         request->url.host(clientConnection->local.toStr(ip, sizeof(ip)));
@@ -3435,9 +3437,11 @@ ConnStateData::buildFakeRequest(Http::MethodType const method, SBuf &useHost, un
 
     stream->registerWithConn();
 
+    MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+    mx->tcpClient = clientConnection;
     // Setup Http::Request object. Maybe should be replaced by a call to (modified)
     // clientProcessRequest
-    HttpRequest::Pointer request = new HttpRequest();
+    HttpRequest::Pointer request = new HttpRequest(mx);
     AnyP::ProtocolType proto = (method == Http::METHOD_NONE) ? AnyP::PROTO_AUTHORITY_FORM : AnyP::PROTO_HTTP;
     request->url.setScheme(proto, nullptr);
     request->method = method;
index cc4ae92787b2bee88c9083ec28b9f80cc4335d4d..23731fc3bb520ad63e66594d80cea798c349999f 100644 (file)
@@ -31,6 +31,9 @@
 class ClientHttpRequest;
 class HttpHdrRangeSpec;
 
+class MasterXaction;
+typedef RefCount<MasterXaction> MasterXactionPointer;
+
 #if USE_OPENSSL
 namespace Ssl
 {
@@ -66,7 +69,7 @@ class ConnStateData : public Server, public HttpControlMsgSink, private Independ
 {
 
 public:
-    explicit ConnStateData(const MasterXaction::Pointer &xact);
+    explicit ConnStateData(const MasterXactionPointer &xact);
     virtual ~ConnStateData();
 
     /* ::Server API */
index dee800319700fc5276a73e24367961ecd12bc179..e1fa4fd00b0d8b67f9881eefe792531fa9a690b6 100644 (file)
@@ -2279,7 +2279,8 @@ clientReplyContext::createStoreEntry(const HttpRequestMethod& m, RequestFlags re
      */
 
     if (http->request == NULL) {
-        http->request = new HttpRequest(m, AnyP::PROTO_NONE, "http", null_string);
+        const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+        http->request = new HttpRequest(m, AnyP::PROTO_NONE, "http", null_string, mx);
         HTTPMSGLOCK(http->request);
     }
 
index 450650275017ef813b8cb86036cf4994a6b8f0dd..4b3140fe50c35762f354d57670d26b1d7ade924a 100644 (file)
@@ -320,7 +320,7 @@ ClientHttpRequest::~ClientHttpRequest()
 int
 clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * streamcallback,
                    CSD * streamdetach, ClientStreamData streamdata, HttpHeader const *header,
-                   char *tailbuf, size_t taillen)
+                   char *tailbuf, size_t taillen, const MasterXaction::Pointer &mx)
 {
     size_t url_sz;
     ClientHttpRequest *http = new ClientHttpRequest(NULL);
@@ -346,7 +346,7 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre
     http->uri = (char *)xcalloc(url_sz, 1);
     strcpy(http->uri, url);
 
-    if ((request = HttpRequest::CreateFromUrl(http->uri, method)) == NULL) {
+    if ((request = HttpRequest::FromUrl(http->uri, mx, method)) == NULL) {
         debugs(85, 5, "Invalid URL: " << http->uri);
         return -1;
     }
@@ -368,8 +368,6 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre
      */
     request->flags.accelerated = http->flags.accel;
 
-    request->flags.internalClient = true;
-
     /* this is an internally created
      * request, not subject to acceleration
      * target overrides */
index edecdc4d8eaac98f5b8338b4af93197363488d89..1c634d833cf0ee56bb2d1164749a3a000bb55c0a 100644 (file)
@@ -13,6 +13,7 @@
 #include "acl/forward.h"
 #include "client_side.h"
 #include "clientStream.h"
+#include "http/forward.h"
 #include "HttpHeaderRange.h"
 #include "LogTags.h"
 
@@ -27,7 +28,7 @@ class ConnStateData;
 class MemObject;
 
 /* client_side_request.c - client side request related routines (pure logic) */
-int clientBeginRequest(const HttpRequestMethod&, char const *, CSCB *, CSD *, ClientStreamData, HttpHeader const *, char *, size_t);
+int clientBeginRequest(const HttpRequestMethod&, char const *, CSCB *, CSD *, ClientStreamData, HttpHeader const *, char *, size_t, const MasterXactionPointer &);
 
 class ClientHttpRequest
 #if USE_ADAPTATION
index 189f5a6849af1b1aa3152977c8874bff686d6df3..83248482c0a09f52701e1b0b6f5ee5dc7777d90d 100644 (file)
@@ -328,7 +328,7 @@ Comm::TcpAcceptor::notify(const Comm::Flag flag, const Comm::ConnectionPointer &
     if (theCallSub != NULL) {
         AsyncCall::Pointer call = theCallSub->callback();
         CommAcceptCbParams &params = GetCommParams<CommAcceptCbParams>(call);
-        params.xaction = new MasterXaction;
+        params.xaction = new MasterXaction(XactionInitiator::initClient);
         params.xaction->squidPort = listenPort_;
         params.fd = conn->fd;
         params.conn = params.xaction->tcpClient = newConnDetails;
index e92eeb717a525332b4a2bc87a39a7fc252083fcc..1c2b732f0a91aa38e5fefd039497d3f3ab10a590 100644 (file)
@@ -299,8 +299,8 @@ ESIInclude::Start (ESIStreamContext::Pointer stream, char const *url, ESIVarStat
     char const *tempUrl = vars->extractChar ();
 
     debugs(86, 5, "ESIIncludeStart: Starting subrequest with url '" << tempUrl << "'");
-
-    if (clientBeginRequest(Http::METHOD_GET, tempUrl, esiBufferRecipient, esiBufferDetach, stream.getRaw(), &tempheaders, stream->localbuffer->buf, HTTP_REQBUF_SZ)) {
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initEsi);
+    if (clientBeginRequest(Http::METHOD_GET, tempUrl, esiBufferRecipient, esiBufferDetach, stream.getRaw(), &tempheaders, stream->localbuffer->buf, HTTP_REQBUF_SZ, mx)) {
         debugs(86, DBG_CRITICAL, "starting new ESI subrequest failed");
     }
 
index b4c3b19d85e993bc5b267e0e2cdfe8aa12f37139..7ebc44fcaf5942fdf6e0af7c1ed184bb74b1cc38 100644 (file)
@@ -678,7 +678,8 @@ htcpUnpackSpecifier(char *buf, int sz)
     // Parse the request
     method.HttpRequestMethodXXX(s->method);
 
-    s->request = HttpRequest::CreateFromUrl(s->uri, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method);
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initHtcp);
+    s->request = HttpRequest::FromUrl(s->uri, mx, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method);
     return s;
 }
 
index c85c3591ffbe10714c59e25a5955498f7bcdced3..11078d31967483c22c2973587b9ef1dcc4f544b9 100644 (file)
@@ -1286,7 +1286,8 @@ netdbExchangeStart(void *data)
     char *uri = internalRemoteUri(p->host, p->http_port, "/squid-internal-dynamic/", netDB);
     debugs(38, 3, "netdbExchangeStart: Requesting '" << uri << "'");
     assert(NULL != uri);
-    HttpRequest *req = HttpRequest::CreateFromUrl(uri);
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcmp);
+    HttpRequest *req = HttpRequest::FromUrl(uri, mx);
 
     if (req == NULL) {
         debugs(38, DBG_IMPORTANT, "netdbExchangeStart: Bad URI " << uri);
index bc64d65deea971c1c3da4f2f6de3b856b3d13783..d9ed9f0df27647d3571ca62e84d8fe7af1bffdac 100644 (file)
@@ -439,8 +439,8 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from)
     }
 
     HttpRequest *result;
-
-    if ((result = HttpRequest::CreateFromUrl(url)) == NULL)
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp);
+    if ((result = HttpRequest::FromUrl(url, mx)) == NULL)
         icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from);
 
     return result;
index 85212b11f9aecfb5d71d33250af311415871b8ff..fc662d8bf58b5e44339194f52529fbdce849c002 100644 (file)
@@ -76,7 +76,8 @@ Mgr::Inquirer::start()
     if (strands.empty()) {
         LOCAL_ARRAY(char, url, MAX_URL);
         snprintf(url, MAX_URL, "%s", aggrAction->command().params.httpUri.termedBuf());
-        HttpRequest *req = HttpRequest::CreateFromUrl(url);
+        const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIpc);
+        HttpRequest *req = HttpRequest::FromUrl(url, mx);
         ErrorState err(ERR_INVALID_URL, Http::scNotFound, req);
         std::unique_ptr<HttpReply> reply(err.BuildHttpReply());
         replyBuf.reset(reply->pack());
index bf411de46f84d746e6d5361879109fb8411f9e59..a070e3213b5578d505927dbf798804beff67f3b1 100644 (file)
@@ -402,7 +402,8 @@ MimeIcon::created(StoreEntry *newEntry)
     EBIT_SET(e->flags, ENTRY_SPECIAL);
     e->setPublicKey();
     e->buffer();
-    HttpRequest *r = HttpRequest::CreateFromUrl(url_);
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon);
+    HttpRequest *r = HttpRequest::FromUrl(url_, mx);
 
     if (NULL == r)
         fatalf("mimeLoadIcon: cannot parse internal URL: %s", url_);
index f1c91d9a8d870c5fb0df91871e36e771a20d884e..ce1bc0f8ed97ae5c5eacdd6644540be53cfa5bbf 100644 (file)
@@ -1382,7 +1382,8 @@ peerCountMcastPeersStart(void *data)
     p->in_addr.toUrl(url+7, MAX_URL -8 );
     strcat(url, "/");
     fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET);
-    HttpRequest *req = HttpRequest::CreateFromUrl(url);
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerMcast);
+    HttpRequest *req = HttpRequest::FromUrl(url, mx);
     psstate = new ps_state;
     psstate->request = req;
     HTTPMSGLOCK(psstate->request);
index ca577516a25c97fec7d844403f15772bcdcd18ec..887091038fdc23833d1a0824b63ac5dc09f8f17e 100644 (file)
@@ -319,7 +319,8 @@ peerDigestRequest(PeerDigest * pd)
     else
         url = xstrdup(internalRemoteUri(p->host, p->http_port, "/squid-internal-periodic/", SBuf(StoreDigestFileName)));
 
-    req = HttpRequest::CreateFromUrl(url);
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest);
+    req = HttpRequest::FromUrl(url, mx);
 
     assert(req);
 
index bf1169def1a097806d7635f9d882eef06de62555..15e5d7c784db996f586ed868531d4131e080ce59 100644 (file)
@@ -633,7 +633,7 @@ Security::PeerConnector::startCertDownloading(SBuf &url)
                                       PeerConnectorCertDownloaderDialer(&Security::PeerConnector::certDownloadingDone, this));
 
     const Downloader *csd = (request ? dynamic_cast<const Downloader*>(request->downloader.valid()) : nullptr);
-    Downloader *dl = new Downloader(url, certCallback, csd ? csd->nestedLevel() + 1 : 1);
+    Downloader *dl = new Downloader(url, certCallback, XactionInitiator::initCertFetcher, csd ? csd->nestedLevel() + 1 : 1);
     AsyncJob::Start(dl);
 }
 
index 8a7d64ecd6651e753b177114ab03d9d75f4ce09b..ca9f71d6153ef467da7e7cd048d0b9cfec142076 100644 (file)
@@ -728,7 +728,9 @@ Ftp::Server::parseOneRequest()
                        &params : NULL;
     calcUri(path);
     char *newUri = xstrdup(uri.c_str());
-    HttpRequest *const request = HttpRequest::CreateFromUrl(newUri, method);
+    MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+    mx->tcpClient = clientConnection;
+    HttpRequest *const request = HttpRequest::FromUrl(newUri, mx, method);
     if (!request) {
         debugs(33, 5, "Invalid FTP URL: " << uri);
         uri.clear();
index 9066ff33a4d0b23bc2a9995ac6c97813ccf763e0..b9a72aa6bb09a5220d44592b3cc4fa40c66607d2 100644 (file)
@@ -132,7 +132,9 @@ Http::One::Server::buildHttpRequest(Http::StreamPointer &context)
         return false;
     }
 
-    if ((request = HttpRequest::CreateFromUrl(http->uri, parser_->method())) == NULL) {
+    MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+    mx->tcpClient = clientConnection;
+    if ((request = HttpRequest::FromUrl(http->uri, mx, parser_->method())) == NULL) {
         debugs(33, 5, "Invalid URL: " << http->uri);
         // setLogUri should called before repContext->setReplyToError
         setLogUri(http, http->uri, true);
index 0a3e1090863e0357305754925b89893d481c9b2f..8cb4fb13fc7711e6854cac0b49b1406b695531c2 100644 (file)
@@ -19,6 +19,7 @@
 #include "CommCalls.h"
 #include "Pipeline.h"
 #include "sbuf/SBuf.h"
+#include "servers/forward.h"
 
 /**
  * Common base for all Server classes used
@@ -27,7 +28,7 @@
 class Server : virtual public AsyncJob, public BodyProducer
 {
 public:
-    Server(const MasterXaction::Pointer &xact);
+    Server(const MasterXactionPointer &xact);
     virtual ~Server() {}
 
     /* AsyncJob API */
index e4366472d235c98e0ffa3c002bdd4016f0f16796..be4530109f31e12a698ea54d1bd751d975950e86 100644 (file)
@@ -421,7 +421,8 @@ storeDigestRewriteStart(void *datanotused)
     assert(e);
     sd_state.rewrite_lock = e;
     debugs(71, 3, "storeDigestRewrite: url: " << url << " key: " << e->getMD5Text());
-    HttpRequest *req = HttpRequest::CreateFromUrl(url);
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest);
+    HttpRequest *req = HttpRequest::FromUrl(url, mx);
     e->mem_obj->request = req;
     HTTPMSGLOCK(e->mem_obj->request);
     /* wait for rebuild (if any) to finish */
index 7670dc7d1c1bdb456874bd411883f9bd70f8ad65..59ecb5ca3b5df051a70ae01f4616d31f24b06275 100644 (file)
@@ -15,8 +15,8 @@
 
 // void httpRequestPack(void *obj, Packable *p);
 
-HttpRequest::HttpRequest() : HttpMsg(hoRequest) {STUB}
-HttpRequest::HttpRequest(const HttpRequestMethod &, AnyP::ProtocolType, const char *, const char *) : HttpMsg(hoRequest) {STUB}
+HttpRequest::HttpRequest(const MasterXaction::Pointer&) : HttpMsg(hoRequest) {STUB}
+HttpRequest::HttpRequest(const HttpRequestMethod &, AnyP::ProtocolType, const char *, const char *, const MasterXaction::Pointer &) : HttpMsg(hoRequest) {STUB}
 HttpRequest::~HttpRequest() STUB
 void HttpRequest::reset() STUB
 void HttpRequest::initHTTP(const HttpRequestMethod &, AnyP::ProtocolType, const char *, const char *) STUB
@@ -47,7 +47,7 @@ int HttpRequest::prefixLen() const STUB_RETVAL(0)
 void HttpRequest::swapOut(StoreEntry *) STUB
 void HttpRequest::pack(Packable *) const STUB
 void HttpRequest::httpRequestPack(void *, Packable *) STUB
-HttpRequest * HttpRequest::CreateFromUrl(char *, const HttpRequestMethod &) STUB_RETVAL(NULL)
+HttpRequest * HttpRequest::FromUrl(char *, const MasterXaction::Pointer &, const HttpRequestMethod &) STUB_RETVAL(NULL)
 ConnStateData *HttpRequest::pinnedConnection() STUB_RETVAL(NULL)
 const SBuf HttpRequest::storeId() STUB_RETVAL(SBuf("."))
 void HttpRequest::ignoreRange(const char *) STUB
index 35d9d99b68dfe964d467ddbbdeba8633e5f5841b..fa02079197683f7573195c803e78af64a8643c5e 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "HttpHeader.h"
 #include "HttpRequest.h"
+#include "MasterXaction.h"
 #include "mime_header.h"
 #include "testHttpRequest.h"
 #include "unitTestMain.h"
@@ -22,6 +23,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest );
 class PrivateHttpRequest : public HttpRequest
 {
 public:
+    PrivateHttpRequest(const MasterXaction::Pointer &mx) : HttpRequest(mx) {}
     bool doSanityCheckStartLine(const char *b, const size_t h, Http::StatusCode *e) { return sanityCheckStartLine(b,h,e); };
 };
 
@@ -44,7 +46,8 @@ testHttpRequest::testCreateFromUrl()
     /* vanilla url, implict method */
     unsigned short expected_port;
     char * url = xstrdup("http://foo:90/bar");
-    HttpRequest *aRequest = HttpRequest::CreateFromUrl(url);
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+    HttpRequest *aRequest = HttpRequest::FromUrl(url, mx);
     expected_port = 90;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
     CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
@@ -56,7 +59,7 @@ testHttpRequest::testCreateFromUrl()
 
     /* vanilla url */
     url = xstrdup("http://foo:90/bar");
-    aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET);
+    aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
     expected_port = 90;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
     CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
@@ -68,7 +71,7 @@ testHttpRequest::testCreateFromUrl()
 
     /* vanilla url, different method */
     url = xstrdup("http://foo/bar");
-    aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_PUT);
+    aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_PUT);
     expected_port = 80;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
     CPPUNIT_ASSERT(aRequest->method == Http::METHOD_PUT);
@@ -81,13 +84,13 @@ testHttpRequest::testCreateFromUrl()
     /* a connect url with non-CONNECT data */
     HttpRequest *nullRequest = nullptr;
     url = xstrdup(":foo/bar");
-    aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_CONNECT);
+    aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_CONNECT);
     xfree(url);
     CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest);
 
     /* a CONNECT url with CONNECT data */
     url = xstrdup("foo:45");
-    aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_CONNECT);
+    aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_CONNECT);
     expected_port = 45;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
     CPPUNIT_ASSERT(aRequest->method == Http::METHOD_CONNECT);
@@ -112,7 +115,8 @@ testHttpRequest::testIPv6HostColonBug()
 
     /* valid IPv6 address without port */
     url = xstrdup("http://[2000:800::45]/foo");
-    aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET);
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+    aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
     expected_port = 80;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
     CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
@@ -124,7 +128,7 @@ testHttpRequest::testIPv6HostColonBug()
 
     /* valid IPv6 address with port */
     url = xstrdup("http://[2000:800::45]:90/foo");
-    aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET);
+    aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
     expected_port = 90;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
     CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
@@ -136,7 +140,7 @@ testHttpRequest::testIPv6HostColonBug()
 
     /* IPv6 address as invalid (bug trigger) */
     url = xstrdup("http://2000:800::45/foo");
-    aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET);
+    aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
     expected_port = 80;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
     CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
@@ -151,7 +155,8 @@ void
 testHttpRequest::testSanityCheckStartLine()
 {
     MemBuf input;
-    PrivateHttpRequest engine;
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+    PrivateHttpRequest engine(mx);
     Http::StatusCode error = Http::scNone;
     size_t hdr_len;
     input.init();
index 896231e3d13663772157c7c2d5e9be88ee229ba5..71605325d455bafabe99ceacbab3a0b4a84cbca5 100644 (file)
@@ -151,7 +151,7 @@ UrnState::setUriResFromRequest(HttpRequest *r)
     safe_free(host);
     safe_free(urlres);
     urlres = xstrdup(local_urlres);
-    urlres_r = HttpRequest::CreateFromUrl(urlres);
+    urlres_r = HttpRequest::FromUrl(urlres, r->masterXaction);
 
     if (urlres_r == NULL) {
         debugs(52, 3, "urnStart: Bad uri-res URL " << urlres);