/* CommAcceptCbParams */
CommAcceptCbParams::CommAcceptCbParams(void *aData):
- CommCommonCbParams(aData), xaction()
+ CommCommonCbParams(aData)
{
}
{
CommCommonCbParams::print(os);
- if (xaction != NULL)
- os << ", " << xaction->id;
+ if (port && port->listenConn)
+ os << ", " << port->listenConn->codeContextGist();
}
/* CommConnectCbParams */
void print(std::ostream &os) const;
- /// Transaction which this call is part of.
- MasterXaction::Pointer xaction;
+ /// the configuration listening port this call relates to (may be nil)
+ AnyP::PortCfgPointer port;
};
// connect parameters
os << " Http Status:" << status << Raw("body data", object.rawContent(), 64).hex();
}
-Downloader::Downloader(SBuf &url, AsyncCall::Pointer &aCallback, const XactionInitiator initiator, unsigned int level):
+Downloader::Downloader(const SBuf &url, const AsyncCall::Pointer &aCallback, const MasterXactionPointer &masterXaction, unsigned int level):
AsyncJob("Downloader"),
url_(url),
callback_(aCallback),
level_(level),
- initiator_(initiator)
+ masterXaction_(masterXaction)
{
}
{
const HttpRequestMethod method = Http::METHOD_GET;
- const MasterXaction::Pointer mx = new MasterXaction(initiator_);
- auto * const request = HttpRequest::FromUrl(url_, mx, method);
+ const auto request = HttpRequest::FromUrl(url_, masterXaction_, method);
if (!request) {
debugs(33, 5, "Invalid URI: " << url_);
return false; //earlyError(...)
#include "http/forward.h"
#include "http/StatusCode.h"
#include "sbuf/SBuf.h"
-#include "XactionInitiator.h"
class ClientHttpRequest;
class StoreIOBuffer;
class clientStreamNode;
class DownloaderContext;
typedef RefCount<DownloaderContext> DownloaderContextPointer;
+class MasterXaction;
+using MasterXactionPointer = RefCount<MasterXaction>;
/// The Downloader class fetches SBuf-storable things for other Squid
/// components/transactions using internal requests. For example, it is used
Http::StatusCode status;
};
- Downloader(SBuf &url, AsyncCall::Pointer &aCallback, const XactionInitiator initiator, unsigned int level = 0);
+ Downloader(const SBuf &url, const AsyncCall::Pointer &aCallback, const MasterXactionPointer &, 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_;
+ MasterXactionPointer masterXaction_; ///< download transaction context
/// Pointer to an object that stores the clientStream required info
DownloaderContextPointer context_;
public:
typedef RefCount<MasterXaction> Pointer;
- explicit MasterXaction(const XactionInitiator anInitiator) : initiator(anInitiator) {};
+ /// Create a master transaction not associated with a AnyP::PortCfg port.
+ template <XactionInitiator::Initiator anInitiator>
+ static Pointer MakePortless()
+ {
+ static_assert(anInitiator != XactionInitiator::initClient, "not an HTTP or FTP client");
+ return new MasterXaction(anInitiator, nullptr);
+ }
+
+ /// Create a master transaction associated with a AnyP::PortCfg port.
+ /// \param aPort may be nil if port information was lost
+ static Pointer MakePortful(const AnyP::PortCfgPointer &aPort)
+ {
+ return new MasterXaction(XactionInitiator::initClient, aPort);
+ }
/// transaction ID.
InstanceId<MasterXaction, uint64_t> id;
bool generatingConnect = false;
// TODO: add state from other Jobs in the transaction
+
+private:
+ // use public Make() functions instead
+ MasterXaction(const XactionInitiator anInitiator, const AnyP::PortCfgPointer &aPort):
+ squidPort(aPort),
+ initiator(anInitiator)
+ {}
};
#endif /* SQUID_SRC_MASTERXACTION_H */
{
AsyncJob::start();
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerPool);
+ const auto mx = MasterXaction::MakePortless<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", "*", mx);
debugs(53, 3, "AS " << as);
ASState *asState = new ASState;
asState->as_number = as;
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAsn);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initAsn>();
asState->request = new HttpRequest(mx);
asState->request->url = whoisUrl;
asState->request->method = Http::METHOD_GET;
Adaptation::Ecap::Host::MessagePtr
Adaptation::Ecap::Host::newRequest() const
{
- static const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptationOrphan_);
+ static const auto mx = MasterXaction::MakePortless<XactionInitiator::initAdaptationOrphan_>();
return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest(mx)));
}
{
debugs(93,3, typeName << " constructed, this=" << this <<
" [icapx" << id << ']'); // we should not call virtual status() here
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptation);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initAdaptation>();
icapRequest = new HttpRequest(mx);
HTTPMSGLOCK(icapRequest);
icap_tr_start = current_time;
void
httpAccept(const CommAcceptCbParams ¶ms)
{
- MasterXaction::Pointer xact = params.xaction;
- AnyP::PortCfgPointer s = xact->squidPort;
+ Assure(params.port);
// NP: it is possible the port was reconfigured when the call or accept() was queued.
if (params.flag != Comm::OK) {
// Its possible the call was still queued when the client disconnected
- debugs(33, 2, s->listenConn << ": accept failure: " << xstrerr(params.xerrno));
+ debugs(33, 2, params.port->listenConn << ": accept failure: " << xstrerr(params.xerrno));
return;
}
debugs(33, 4, params.conn << ": accepted");
fd_note(params.conn->fd, "client http connect");
+ const auto xact = MasterXaction::MakePortful(params.port);
+ xact->tcpClient = params.conn;
// Socket is ready, setup the connection manager to start using it
auto *srv = Http::NewServer(xact);
+ // XXX: do not abandon the MasterXaction object
AsyncJob::Start(srv); // usually async-calls readSomeData()
}
static void
httpsAccept(const CommAcceptCbParams ¶ms)
{
- MasterXaction::Pointer xact = params.xaction;
- const AnyP::PortCfgPointer s = xact->squidPort;
+ Assure(params.port);
// NP: it is possible the port was reconfigured when the call or accept() was queued.
if (params.flag != Comm::OK) {
// Its possible the call was still queued when the client disconnected
- debugs(33, 2, "httpsAccept: " << s->listenConn << ": accept failure: " << xstrerr(params.xerrno));
+ debugs(33, 2, "httpsAccept: " << params.port->listenConn << ": accept failure: " << xstrerr(params.xerrno));
return;
}
+ const auto xact = MasterXaction::MakePortful(params.port);
+ xact->tcpClient = params.conn;
+
debugs(33, 4, params.conn << " accepted, starting SSL negotiation.");
fd_note(params.conn->fd, "client https connect");
// Socket is ready, setup the connection manager to start using it
auto *srv = Https::NewServer(xact);
+ // XXX: do not abandon the MasterXaction object
AsyncJob::Start(srv); // usually async-calls postHttpsAccept()
}
return;
}
- MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+ const auto mx = MasterXaction::MakePortful(port);
mx->tcpClient = clientConnection;
// Create a fake HTTP request and ALE for the ssl_bump ACL check,
// using tproxy/intercept provided destination IP and port.
extendLifetime();
stream->registerWithConn();
- MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+ const auto mx = MasterXaction::MakePortful(port);
mx->tcpClient = clientConnection;
// Setup Http::Request object. Maybe should be replaced by a call to (modified)
// clientProcessRequest
*/
if (http->request == NULL) {
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+ const auto connManager = http->getConn();
+ const auto mx = MasterXaction::MakePortful(connManager ? connManager->port : nullptr);
// XXX: These fake URI parameters shadow the real (or error:...) URI.
// TODO: Either always set the request earlier and assert here OR use
// http->uri (converted to Anyp::Uri) to create this catch-all request.
if (theCallSub != NULL) {
AsyncCall::Pointer call = theCallSub->callback();
CommAcceptCbParams ¶ms = GetCommParams<CommAcceptCbParams>(call);
- params.xaction = new MasterXaction(XactionInitiator::initClient);
- params.xaction->squidPort = listenPort_;
+ params.port = listenPort_;
params.fd = conn->fd;
- params.conn = params.xaction->tcpClient = newConnDetails;
+ params.conn = newConnDetails;
params.flag = flag;
params.xerrno = errcode;
ScheduleCallHere(call);
char const *tempUrl = vars->extractChar ();
debugs(86, 5, "ESIIncludeStart: Starting subrequest with url '" << tempUrl << "'");
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initEsi);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initEsi>();
if (clientBeginRequest(Http::METHOD_GET, tempUrl, esiBufferRecipient, esiBufferDetach, stream.getRaw(), &tempheaders, stream->localbuffer->buf, HTTP_REQBUF_SZ, mx)) {
debugs(86, DBG_CRITICAL, "ERROR: starting new ESI subrequest failed");
}
// Parse the request
method.HttpRequestMethodXXX(s->method);
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initHtcp);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initHtcp>();
s->request = HttpRequest::FromUrlXXX(s->uri, mx, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method);
if (!s->request) {
debugs(31, 3, "failed to create request. Invalid URI?");
static const SBuf netDB("netdb");
char *uri = internalRemoteUri(p->secure.encryptTransport, p->host, p->http_port, "/squid-internal-dynamic/", netDB);
debugs(38, 3, "Requesting '" << uri << "'");
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcmp);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initIcmp>();
HttpRequestPointer req(HttpRequest::FromUrlXXX(uri, mx));
if (!req) {
return NULL;
}
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initIcp>();
auto *result = HttpRequest::FromUrlXXX(url, mx);
if (!result)
icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr);
std::unique_ptr<MemBuf> replyBuf;
if (strands.empty()) {
const char *url = aggrAction->command().params.httpUri.termedBuf();
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIpc);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initIpc>();
auto *req = HttpRequest::FromUrlXXX(url, mx);
ErrorState err(ERR_INVALID_URL, Http::scNotFound, req, nullptr);
std::unique_ptr<HttpReply> reply(err.BuildHttpReply());
/* fill `e` with a canned 2xx response object */
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initIcon>();
HttpRequestPointer r(HttpRequest::FromUrlXXX(url_, mx));
if (!r)
fatalf("mimeLoadIcon: cannot parse internal URL: %s", url_);
snprintf(url, MAX_URL, "http://");
p->in_addr.toUrl(url+7, MAX_URL -8 );
strcat(url, "/");
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerMcast);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initPeerMcast>();
auto *req = HttpRequest::FromUrlXXX(url, mx);
assert(req != nullptr);
const AccessLogEntry::Pointer ale = new AccessLogEntry;
url = xstrdup(internalRemoteUri(p->secure.encryptTransport, p->host, p->http_port, "/squid-internal-periodic/", SBuf(StoreDigestFileName)));
debugs(72, 2, url);
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initCacheDigest>();
req = HttpRequest::FromUrlXXX(url, mx);
assert(req);
"Security::PeerConnector::certDownloadingDone",
PeerConnectorCertDownloaderDialer(&Security::PeerConnector::certDownloadingDone, this));
- const auto dl = new Downloader(url, certCallback, XactionInitiator::initCertFetcher, certDownloadNestingLevel() + 1);
+ const auto dl = new Downloader(url, certCallback,
+ MasterXaction::MakePortless<XactionInitiator::initCertFetcher>(),
+ certDownloadNestingLevel() + 1);
certDownloadWait.start(dl, certCallback);
}
void
Ftp::Server::AcceptCtrlConnection(const CommAcceptCbParams ¶ms)
{
- MasterXaction::Pointer xact = params.xaction;
- AnyP::PortCfgPointer s = xact->squidPort;
+ Assure(params.port);
// NP: it is possible the port was reconfigured when the call or accept() was queued.
if (params.flag != Comm::OK) {
// Its possible the call was still queued when the client disconnected
- debugs(33, 2, s->listenConn << ": FTP accept failure: " << xstrerr(params.xerrno));
+ debugs(33, 2, params.port->listenConn << ": FTP accept failure: " << xstrerr(params.xerrno));
return;
}
debugs(33, 4, params.conn << ": accepted");
fd_note(params.conn->fd, "client ftp connect");
+ const auto xact = MasterXaction::MakePortful(params.port);
+ xact->tcpClient = params.conn;
+
AsyncJob::Start(new Server(xact));
+ // XXX: do not abandon the MasterXaction object
}
void
const SBuf *path = (params.length() && CommandHasPathParameter(cmd)) ?
¶ms : NULL;
calcUri(path);
- MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+ const auto mx = MasterXaction::MakePortful(port);
mx->tcpClient = clientConnection;
auto * const request = HttpRequest::FromUrl(uri, mx, method);
if (!request) {
}
// TODO: move URL parse into Http Parser and INVALID_URL into the above parse error handling
- MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+ const auto mx = MasterXaction::MakePortful(port);
mx->tcpClient = clientConnection;
request = HttpRequest::FromUrlXXX(http->uri, mx, parser_->method());
if (!request) {
}
ConnStateData *
-Http::NewServer(MasterXactionPointer &xact)
+Http::NewServer(const MasterXaction::Pointer &xact)
{
return new Http1::Server(xact, false);
}
ConnStateData *
-Https::NewServer(MasterXactionPointer &xact)
+Https::NewServer(const MasterXaction::Pointer &xact)
{
return new Http1::Server(xact, true);
}
} // namespace One
/// create a new HTTP connection handler; never returns NULL
-ConnStateData *NewServer(MasterXactionPointer &xact);
+ConnStateData *NewServer(const MasterXaction::Pointer &xact);
} // namespace Http
{
/// create a new HTTPS connection handler; never returns NULL
-ConnStateData *NewServer(MasterXactionPointer &xact);
+ConnStateData *NewServer(const MasterXaction::Pointer &xact);
} // namespace Https
debugs(71, 2, "storeDigestRewrite: start rewrite #" << sd_state.rewrite_count + 1);
const char *url = internalLocalUri("/squid-internal-periodic/", SBuf(StoreDigestFileName));
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initCacheDigest>();
auto req = HttpRequest::FromUrlXXX(url, mx);
RequestFlags flags;
/* vanilla url, implicit method */
unsigned short expected_port;
SBuf url("http://foo:90/bar");
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initHtcp>();
HttpRequest *aRequest = HttpRequest::FromUrl(url, mx);
expected_port = 90;
CPPUNIT_ASSERT(aRequest != nullptr);
/* valid IPv6 address without port */
SBuf url("http://[2000:800::45]/foo");
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initHtcp>();
aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
expected_port = 80;
CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
testHttpRequest::testSanityCheckStartLine()
{
MemBuf input;
- const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+ const auto mx = MasterXaction::MakePortless<XactionInitiator::initHtcp>();
PrivateHttpRequest engine(mx);
Http::StatusCode error = Http::scNone;
size_t hdr_len;