#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"
RegisterMaker("annotate_client", [](TypeName name)->ACL* { return new ACLStrategised<NotePairs::Entry*>(new ACLAnnotationData, new ACLAnnotateClientStrategy, name); });
RegisterMaker("annotate_transaction", [](TypeName name)->ACL* { return new ACLStrategised<NotePairs::Entry*>(new ACLAnnotationData, new ACLAnnotateTransactionStrategy, name); });
RegisterMaker("has", [](TypeName name)->ACL* {return new ACLStrategised<ACLChecklist *>(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<const Security::CertErrors *>(new ACLSslErrorData, new ACLSslErrorStrategy, name); });
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)
{
}
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);
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();
#include "http/forward.h"
#include "http/StatusCode.h"
#include "sbuf/SBuf.h"
+#include "XactionInitiator.h"
class ClientHttpRequest;
class StoreIOBuffer;
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();
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_;
#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();
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);
* 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;
#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"
public:
typedef RefCount<HttpRequest> 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();
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();
/// The Downloader object which initiated the HTTP request if any
CbcPointer<Downloader> 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 */
whois.cc \
wordlist.h \
wordlist.cc \
+ XactionInitiator.h \
+ XactionInitiator.cc \
$(WIN32_SOURCE) \
$(WINSVC_SOURCE)
#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.
*
public:
typedef RefCount<MasterXaction> Pointer;
+ explicit MasterXaction(const XactionInitiator anInitiator) : initiator(anInitiator) {};
+
/// transaction ID.
InstanceId<MasterXaction> id;
/// 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
};
#include "FwdState.h"
#include "globals.h"
#include "HttpRequest.h"
+#include "MasterXaction.h"
#include "neighbors.h"
#include "pconn.h"
#include "PeerPoolMgr.h"
{
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");
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 */
--- /dev/null
+/*
+ * 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<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;
+}
--- /dev/null
+/*
+ * 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
#include "HttpReply.h"
#include "HttpRequest.h"
#include "ipcache.h"
+#include "MasterXaction.h"
#include "mgr/Registration.h"
#include "radix.h"
#include "RequestFlags.h"
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) {
SquidErrorData.h \
Tag.cc \
Tag.h \
+ TransactionInitiator.cc \
+ TransactionInitiator.h \
Url.cc \
Url.h \
UrlLogin.cc \
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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 */
+
#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());
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
#include "format/Format.h"
#include "HttpReply.h"
#include "HttpRequest.h"
+#include "MasterXaction.h"
#include "SquidTime.h"
CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Ecap::XactionRep, XactionRep);
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<HttpRequest*>(adapted)) {
+ HttpRequest *request = dynamic_cast<HttpRequest*> (theCauseRep ?
+ theCauseRep->raw().header : theVirginRep.raw().header);
+ Must(request);
+ adaptedReq->masterXaction = request->masterXaction;
+ }
}
#include "http/one/TeChunkedParser.h"
#include "HttpHeaderTools.h"
#include "HttpReply.h"
+#include "MasterXaction.h"
#include "SquidTime.h"
#include "URL.h"
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()");
Must(!adapted.header);
{
Http::MessagePointer 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;
}
Http::MessagePointer headClone;
if (const HttpRequest* old_request = dynamic_cast<const HttpRequest*>(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;
{
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));
# 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]
#
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)));
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;
#include "base/RunnersRegistry.h"
#include "clientStreamForward.h"
#include "comm.h"
+#include "forward.h"
#include "helper/forward.h"
#include "http/forward.h"
#include "HttpControlMsg.h"
{
public:
- explicit ConnStateData(const MasterXaction::Pointer &xact);
+ explicit ConnStateData(const MasterXactionPointer &xact);
virtual ~ConnStateData();
/* ::Server API */
*/
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);
}
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);
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;
}
*/
request->flags.accelerated = http->flags.accel;
- request->flags.internalClient = true;
-
/* this is an internally created
* request, not subject to acceleration
* target overrides */
#include "acl/forward.h"
#include "client_side.h"
#include "clientStream.h"
+#include "forward.h"
#include "http/forward.h"
#include "HttpHeaderRange.h"
#include "LogTags.h"
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
if (theCallSub != NULL) {
AsyncCall::Pointer call = theCallSub->callback();
CommAcceptCbParams ¶ms = 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;
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");
}
--- /dev/null
+/*
+ * 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 C> class RefCount;
+typedef RefCount<MasterXaction> MasterXactionPointer;
+
+#endif
// 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;
}
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);
}
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;
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());
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_);
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);
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);
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);
}
¶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();
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);
#include "BodyPipe.h"
#include "comm/Write.h"
#include "CommCalls.h"
+#include "forward.h"
#include "Pipeline.h"
#include "sbuf/SBuf.h"
class Server : virtual public AsyncJob, public BodyProducer
{
public:
- Server(const MasterXaction::Pointer &xact);
+ Server(const MasterXactionPointer &xact);
virtual ~Server() {}
/* AsyncJob API */
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) {
#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
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
#include "HttpHeader.h"
#include "HttpRequest.h"
#include "mime_header.h"
+#include "MasterXaction.h"
#include "testHttpRequest.h"
#include "unitTestMain.h"
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); };
};
/* 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);
/* 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);
/* 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);
/* 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);
/* 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);
/* 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);
/* 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);
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();
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);