From: Christos Tsantilas Date: Mon, 12 Jun 2017 20:26:41 +0000 (+0300) Subject: transaction_initiator ACL for detecting various unusual transactions X-Git-Tag: M-staged-PR71~122 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5ceaee752b4a01c8a4fd8ab3071ce369a552d04e;p=thirdparty%2Fsquid.git transaction_initiator ACL for detecting various unusual transactions 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. --- diff --git a/src/AclRegs.cc b/src/AclRegs.cc index 48dd65c451..73814e3963 100644 --- a/src/AclRegs.cc +++ b/src/AclRegs.cc @@ -87,6 +87,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" @@ -155,6 +156,7 @@ Acl::Init() RegisterMaker("annotate_client", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAnnotationData, new ACLAnnotateClientStrategy, name); }); RegisterMaker("annotate_transaction", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAnnotationData, new ACLAnnotateTransactionStrategy, name); }); RegisterMaker("has", [](TypeName name)->ACL* {return new ACLStrategised(new ACLHasComponentData, new ACLHasComponentStrategy, name); }); + RegisterMaker("transaction_initiator", [](TypeName name)->ACL* {return new TransactionInitiator(name);}); #if USE_OPENSSL RegisterMaker("ssl_error", [](TypeName name)->ACL* { return new ACLStrategised(new ACLSslErrorData, new ACLSslErrorStrategy, name); }); diff --git a/src/Downloader.cc b/src/Downloader.cc index 38904a75fc..e153861d97 100644 --- a/src/Downloader.cc +++ b/src/Downloader.cc @@ -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(); diff --git a/src/Downloader.h b/src/Downloader.h index 7f8dca42e8..5f8e24bd85 100644 --- a/src/Downloader.h +++ b/src/Downloader.h @@ -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_; diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 8ca441555d..9b75838d19 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -38,15 +38,19 @@ #include "adaptation/icap/icap_log.h" #endif -HttpRequest::HttpRequest() : - Http::Message(hoRequest) +HttpRequest::HttpRequest(const MasterXaction::Pointer &mx) : + Http::Message(hoRequest), + masterXaction(mx) { + assert(mx); init(); } -HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath) : - Http::Message(hoRequest) +HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath, const MasterXaction::Pointer &mx) : + Http::Message(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 req(new HttpRequest()); + std::unique_ptr req(new HttpRequest(mx)); if (urlParse(method, url, *req)) return req.release(); return nullptr; diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 5c097042cd..ef13d19af7 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -12,6 +12,7 @@ #include "base/CbcPointer.h" #include "dns/forward.h" #include "err_type.h" +#include "forward.h" #include "HierarchyLogEntry.h" #include "http/Message.h" #include "http/RequestMethod.h" @@ -48,8 +49,8 @@ class HttpRequest: public Http::Message public: typedef RefCount Pointer; - HttpRequest(); - HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *schemeImage, const char *aUrlpath); + HttpRequest(const MasterXactionPointer &); + HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *schemeImage, const char *aUrlpath, const MasterXactionPointer &); ~HttpRequest(); virtual void reset(); @@ -193,7 +194,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 MasterXactionPointer &, const HttpRequestMethod &method = Http::METHOD_GET); ConnStateData *pinnedConnection(); @@ -214,6 +215,9 @@ public: /// The Downloader object which initiated the HTTP request if any CbcPointer downloader; + /// the master transaction this request belongs to. Never nil. + MasterXactionPointer 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 */ diff --git a/src/Makefile.am b/src/Makefile.am index 323653c9ad..c93d6f4c28 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -486,6 +486,8 @@ squid_SOURCES = \ whois.cc \ wordlist.h \ wordlist.cc \ + XactionInitiator.h \ + XactionInitiator.cc \ $(WIN32_SOURCE) \ $(WINSVC_SOURCE) diff --git a/src/MasterXaction.h b/src/MasterXaction.h index 5554861d02..5aa8822a7f 100644 --- a/src/MasterXaction.h +++ b/src/MasterXaction.h @@ -10,9 +10,12 @@ #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 Pointer; + explicit MasterXaction(const XactionInitiator anInitiator) : initiator(anInitiator) {}; + /// transaction ID. InstanceId 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 }; diff --git a/src/PeerPoolMgr.cc b/src/PeerPoolMgr.cc index a422a06ec8..5329ff0a91 100644 --- a/src/PeerPoolMgr.cc +++ b/src/PeerPoolMgr.cc @@ -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"); diff --git a/src/RequestFlags.h b/src/RequestFlags.h index 9ef3af7066..353186d01c 100644 --- a/src/RequestFlags.h +++ b/src/RequestFlags.h @@ -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 index 0000000000..31e4cc4bbb --- /dev/null +++ b/src/XactionInitiator.cc @@ -0,0 +1,43 @@ +/* + * 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" + +XactionInitiator::Initiators +XactionInitiator::ParseInitiators(const char *name) +{ + typedef std::map 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 index 0000000000..985b85fd15 --- /dev/null +++ b/src/XactionInitiator.h @@ -0,0 +1,67 @@ +/* + * 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 diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index 5707ea1ac8..c152f29bf3 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -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) { diff --git a/src/acl/Makefile.am b/src/acl/Makefile.am index 98804b9e44..d59dd769d1 100644 --- a/src/acl/Makefile.am +++ b/src/acl/Makefile.am @@ -133,6 +133,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 index 0000000000..022598469e --- /dev/null +++ b/src/acl/TransactionInitiator.cc @@ -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/TransactionInitiator.h" +#include "acl/FilledChecklist.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 index 0000000000..ff8ff0b83a --- /dev/null +++ b/src/acl/TransactionInitiator.h @@ -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 */ + diff --git a/src/adaptation/ecap/Host.cc b/src/adaptation/ecap/Host.cc index 705651f08f..3f906c0d28 100644 --- a/src/adaptation/ecap/Host.cc +++ b/src/adaptation/ecap/Host.cc @@ -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 diff --git a/src/adaptation/ecap/XactionRep.cc b/src/adaptation/ecap/XactionRep.cc index 0645a71e8b..660eea5c40 100644 --- a/src/adaptation/ecap/XactionRep.cc +++ b/src/adaptation/ecap/XactionRep.cc @@ -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); @@ -737,5 +738,13 @@ void Adaptation::Ecap::XactionRep::updateSources(Http::Message *adapted) { adapted->sources |= service().cfg().connectionEncryption ? Http::Message::srcEcaps : Http::Message::srcEcap; + + // Update masterXaction object for adapted HTTP requests. + if (HttpRequest *adaptedReq = dynamic_cast(adapted)) { + HttpRequest *request = dynamic_cast (theCauseRep ? + theCauseRep->raw().header : theVirginRep.raw().header); + Must(request); + adaptedReq->masterXaction = request->masterXaction; + } } diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index acb271b545..54e25cd946 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -28,6 +28,7 @@ #include "http/one/TeChunkedParser.h" #include "HttpHeaderTools.h" #include "HttpReply.h" +#include "MasterXaction.h" #include "SquidTime.h" #include "URL.h" @@ -736,7 +737,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()"); @@ -970,8 +971,8 @@ void Adaptation::Icap::ModXact::prepEchoing() Must(!adapted.header); { Http::MessagePointer newHead; - if (dynamic_cast(oldHead)) { - newHead = new HttpRequest; + if (const HttpRequest *r = dynamic_cast(oldHead)) { + newHead = new HttpRequest(r->masterXaction); } else if (dynamic_cast(oldHead)) { newHead = new HttpReply; } @@ -1594,7 +1595,7 @@ Adaptation::Icap::ModXact::encapsulateHead(MemBuf &icapBuf, const char *section, Http::MessagePointer headClone; if (const HttpRequest* old_request = dynamic_cast(head)) { - HttpRequest::Pointer new_request(new HttpRequest); + HttpRequest::Pointer new_request(new HttpRequest(old_request->masterXaction)); // copy the request-line details new_request->method = old_request->method; new_request->url = old_request->url; diff --git a/src/adaptation/icap/Xaction.cc b/src/adaptation/icap/Xaction.cc index cb15486998..8cee03ff08 100644 --- a/src/adaptation/icap/Xaction.cc +++ b/src/adaptation/icap/Xaction.cc @@ -97,7 +97,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)); diff --git a/src/cf.data.pre b/src/cf.data.pre index 8a05095f8d..600f59590a 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1299,6 +1299,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] # diff --git a/src/client_side.cc b/src/client_side.cc index c89a9257b6..d8a5af00b1 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2794,9 +2794,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))); @@ -3436,9 +3438,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; diff --git a/src/client_side.h b/src/client_side.h index fbb33225d6..8c774f2cbf 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -14,6 +14,7 @@ #include "base/RunnersRegistry.h" #include "clientStreamForward.h" #include "comm.h" +#include "forward.h" #include "helper/forward.h" #include "http/forward.h" #include "HttpControlMsg.h" @@ -69,7 +70,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 */ diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 767a43ac25..359cf496c9 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -2280,7 +2280,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); } diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 3a8f0254f4..d4628cbcc2 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -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 */ diff --git a/src/client_side_request.h b/src/client_side_request.h index c515ca7c3f..40c270c5b4 100644 --- a/src/client_side_request.h +++ b/src/client_side_request.h @@ -13,6 +13,7 @@ #include "acl/forward.h" #include "client_side.h" #include "clientStream.h" +#include "forward.h" #include "http/forward.h" #include "HttpHeaderRange.h" #include "LogTags.h" @@ -28,7 +29,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 diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index ba77cb6191..890d13f654 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -328,7 +328,7 @@ Comm::TcpAcceptor::notify(const Comm::Flag flag, const Comm::ConnectionPointer & if (theCallSub != NULL) { AsyncCall::Pointer call = theCallSub->callback(); CommAcceptCbParams ¶ms = GetCommParams(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; diff --git a/src/esi/Include.cc b/src/esi/Include.cc index e92eeb717a..1c2b732f0a 100644 --- a/src/esi/Include.cc +++ b/src/esi/Include.cc @@ -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"); } diff --git a/src/forward.h b/src/forward.h new file mode 100644 index 0000000000..750a9ea647 --- /dev/null +++ b/src/forward.h @@ -0,0 +1,16 @@ +/* + * 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_FORWARD_H +#define SQUID_SRC_FORWARD_H + +class MasterXaction; +template class RefCount; +typedef RefCount MasterXactionPointer; + +#endif diff --git a/src/htcp.cc b/src/htcp.cc index b4c3b19d85..7ebc44fcaf 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -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; } diff --git a/src/icmp/net_db.cc b/src/icmp/net_db.cc index 73aad008fa..c8cf5bfac4 100644 --- a/src/icmp/net_db.cc +++ b/src/icmp/net_db.cc @@ -1274,7 +1274,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); - HttpRequestPointer req(HttpRequest::CreateFromUrl(uri)); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcmp); + HttpRequestPointer req(HttpRequest::FromUrl(uri, mx)); if (!req) { debugs(38, DBG_IMPORTANT, "netdbExchangeStart: Bad URI " << uri); diff --git a/src/icp_v2.cc b/src/icp_v2.cc index bc64d65dee..d9ed9f0df2 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -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; diff --git a/src/mgr/Inquirer.cc b/src/mgr/Inquirer.cc index 85212b11f9..fc662d8bf5 100644 --- a/src/mgr/Inquirer.cc +++ b/src/mgr/Inquirer.cc @@ -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 reply(err.BuildHttpReply()); replyBuf.reset(reply->pack()); diff --git a/src/mime.cc b/src/mime.cc index cc0208f34f..063513dcba 100644 --- a/src/mime.cc +++ b/src/mime.cc @@ -403,7 +403,8 @@ MimeIcon::created(StoreEntry *newEntry) e->setPublicKey(); e->buffer(); - HttpRequestPointer r(HttpRequest::CreateFromUrl(url_)); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon); + HttpRequestPointer r(HttpRequest::FromUrl(url_, mx)); if (!r) fatalf("mimeLoadIcon: cannot parse internal URL: %s", url_); diff --git a/src/neighbors.cc b/src/neighbors.cc index b16994d639..2087b688c1 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1384,7 +1384,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(nullptr); psstate->request = req; HTTPMSGLOCK(psstate->request); diff --git a/src/peer_digest.cc b/src/peer_digest.cc index 3306a2dd91..f288328bf4 100644 --- a/src/peer_digest.cc +++ b/src/peer_digest.cc @@ -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); diff --git a/src/security/PeerConnector.cc b/src/security/PeerConnector.cc index 3d6a37af7e..4b3b6ceaca 100644 --- a/src/security/PeerConnector.cc +++ b/src/security/PeerConnector.cc @@ -629,7 +629,7 @@ Security::PeerConnector::startCertDownloading(SBuf &url) PeerConnectorCertDownloaderDialer(&Security::PeerConnector::certDownloadingDone, this)); const Downloader *csd = (request ? dynamic_cast(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); } diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index 8a7d64ecd6..ca9f71d615 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -728,7 +728,9 @@ Ftp::Server::parseOneRequest() ¶ms : 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(); diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index 4eba62af9d..2cbfbe0f49 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -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); diff --git a/src/servers/Server.h b/src/servers/Server.h index 0a3e109086..40d1ba3e79 100644 --- a/src/servers/Server.h +++ b/src/servers/Server.h @@ -17,6 +17,7 @@ #include "BodyPipe.h" #include "comm/Write.h" #include "CommCalls.h" +#include "forward.h" #include "Pipeline.h" #include "sbuf/SBuf.h" @@ -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 */ diff --git a/src/store_digest.cc b/src/store_digest.cc index 95a428cb05..549b8a241e 100644 --- a/src/store_digest.cc +++ b/src/store_digest.cc @@ -421,7 +421,8 @@ storeDigestRewriteStart(void *datanotused) assert(e); sd_state.rewrite_lock = e; debugs(71, 3, "storeDigestRewrite: url: " << url << " key: " << e->getMD5Text()); - e->mem_obj->request = HttpRequest::CreateFromUrl(url); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest); + e->mem_obj->request = HttpRequest::FromUrl(url, mx); /* wait for rebuild (if any) to finish */ if (sd_state.rebuild_lock) { diff --git a/src/tests/stub_HttpRequest.cc b/src/tests/stub_HttpRequest.cc index 44ab6cc553..620cb6f0eb 100644 --- a/src/tests/stub_HttpRequest.cc +++ b/src/tests/stub_HttpRequest.cc @@ -9,14 +9,15 @@ #include "squid.h" #include "AccessLogEntry.h" #include "HttpRequest.h" +#include "MasterXaction.h" #define STUB_API "HttpRequest.cc" #include "tests/STUB.h" // void httpRequestPack(void *obj, Packable *p); -HttpRequest::HttpRequest() : Http::Message(hoRequest) {STUB} -HttpRequest::HttpRequest(const HttpRequestMethod &, AnyP::ProtocolType, const char *, const char *) : Http::Message(hoRequest) {STUB} +HttpRequest::HttpRequest(const MasterXactionPointer&) : Http::Message(hoRequest) {STUB} +HttpRequest::HttpRequest(const HttpRequestMethod &, AnyP::ProtocolType, const char *, const char *, const MasterXactionPointer &) : Http::Message(hoRequest) {STUB} HttpRequest::~HttpRequest() STUB void HttpRequest::reset() STUB void HttpRequest::initHTTP(const HttpRequestMethod &, AnyP::ProtocolType, const char *, const char *) STUB @@ -47,7 +48,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 diff --git a/src/tests/testHttpRequest.cc b/src/tests/testHttpRequest.cc index 35d9d99b68..2f30ddd8b1 100644 --- a/src/tests/testHttpRequest.cc +++ b/src/tests/testHttpRequest.cc @@ -13,6 +13,7 @@ #include "HttpHeader.h" #include "HttpRequest.h" #include "mime_header.h" +#include "MasterXaction.h" #include "testHttpRequest.h" #include "unitTestMain.h" @@ -22,6 +23,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest ); class PrivateHttpRequest : public HttpRequest { public: + PrivateHttpRequest(const MasterXactionPointer &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(); diff --git a/src/urn.cc b/src/urn.cc index 896231e3d1..71605325d4 100644 --- a/src/urn.cc +++ b/src/urn.cc @@ -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);