2
* DEBUG: section 93 ICAP (RFC 3507) Client
6
#include "TextException.h"
7
#include "HttpRequest.h"
9
#include "acl/FilledChecklist.h"
11
#include "adaptation/icap/Launcher.h"
12
#include "adaptation/icap/Xaction.h"
13
#include "adaptation/icap/ServiceRep.h"
14
#include "adaptation/icap/Config.h"
17
Adaptation::Icap::Launcher::Launcher(const char *aTypeName,
18
Adaptation::Initiator *anInitiator, Adaptation::ServicePointer &aService):
20
Adaptation::Initiate(aTypeName, anInitiator),
21
theService(aService), theXaction(0), theLaunches(0)
25
Adaptation::Icap::Launcher::~Launcher()
30
void Adaptation::Icap::Launcher::start()
32
Adaptation::Initiate::start();
35
launchXaction("first");
38
void Adaptation::Icap::Launcher::launchXaction(const char *xkind)
42
debugs(93,4, HERE << "launching " << xkind << " xaction #" << theLaunches);
43
Adaptation::Icap::Xaction *x = createXaction();
44
x->attempts = theLaunches;
47
if (theLaunches >= TheConfig.repeat_limit)
48
x->disableRepeats("over icap_retry_limit");
49
theXaction = initiateAdaptation(x);
53
void Adaptation::Icap::Launcher::noteAdaptationAnswer(HttpMsg *message)
56
clearAdaptation(theXaction);
58
debugs(93,3, HERE << "Adaptation::Icap::Launcher::noteAdaptationAnswer exiting ");
61
void Adaptation::Icap::Launcher::noteInitiatorAborted()
64
announceInitiatorAbort(theXaction); // propogate to the transaction
66
Must(done()); // should be nothing else to do
70
// XXX: this call is unused by ICAPXaction in favor of ICAPLauncher::noteXactAbort
71
void Adaptation::Icap::Launcher::noteAdaptationQueryAbort(bool final)
73
debugs(93,5, HERE << "launches: " << theLaunches << "; final: " << final);
74
clearAdaptation(theXaction);
76
Must(done()); // swanSong will notify the initiator
79
void Adaptation::Icap::Launcher::noteXactAbort(XactAbortInfo &info)
81
debugs(93,5, HERE << "theXaction:" << theXaction << " launches: " << theLaunches);
83
// TODO: add more checks from FwdState::checkRetry()?
85
clearAdaptation(theXaction);
86
launchXaction("retry");
88
else if (canRepeat(info)) {
89
clearAdaptation(theXaction);
90
launchXaction("repeat");
92
debugs(93,3, HERE << "cannot retry or repeat a failed transaction");
93
clearAdaptation(theXaction);
94
tellQueryAborted(false); // caller decides based on bypass, consumption
99
bool Adaptation::Icap::Launcher::doneAll() const
101
return (!theInitiator || !theXaction) && Adaptation::Initiate::doneAll();
104
void Adaptation::Icap::Launcher::swanSong()
107
tellQueryAborted(true); // always final here because abnormal
110
clearAdaptation(theXaction);
112
Adaptation::Initiate::swanSong();
115
bool Adaptation::Icap::Launcher::canRetry(Adaptation::Icap::XactAbortInfo &info) const
117
// We do not check and can exceed zero repeat limit when retrying.
118
// This is by design as the limit does not apply to pconn retrying.
119
return !shutting_down && info.isRetriable;
122
bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info) const
124
debugs(93,9, HERE << shutting_down);
125
if (theLaunches >= TheConfig.repeat_limit || shutting_down)
128
debugs(93,9, HERE << info.isRepeatable); // TODO: update and use status()
129
if (!info.isRepeatable)
132
debugs(93,9, HERE << info.icapReply);
133
if (!info.icapReply) // did not get to read an ICAP reply; a timeout?
136
debugs(93,9, HERE << info.icapReply->sline.status);
137
if (!info.icapReply->sline.status) // failed to parse the reply; I/O err
140
ACLFilledChecklist *cl =
141
new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, dash_str);
142
cl->reply = HTTPMSGLOCK(info.icapReply);
144
const bool result = cl->fastCheck();
149
/* ICAPXactAbortInfo */
151
Adaptation::Icap::XactAbortInfo::XactAbortInfo(HttpRequest *anIcapRequest,
152
HttpReply *anIcapReply, bool beRetriable, bool beRepeatable):
153
icapRequest(anIcapRequest ? HTTPMSGLOCK(anIcapRequest) : NULL),
154
icapReply(anIcapReply ? HTTPMSGLOCK(anIcapReply) : NULL),
155
isRetriable(beRetriable), isRepeatable(beRepeatable)
159
Adaptation::Icap::XactAbortInfo::XactAbortInfo(const Adaptation::Icap::XactAbortInfo &i):
160
icapRequest(i.icapRequest ? HTTPMSGLOCK(i.icapRequest) : NULL),
161
icapReply(i.icapReply ? HTTPMSGLOCK(i.icapReply) : NULL),
162
isRetriable(i.isRetriable), isRepeatable(i.isRepeatable)
166
Adaptation::Icap::XactAbortInfo::~XactAbortInfo()
168
HTTPMSGUNLOCK(icapRequest);
169
HTTPMSGUNLOCK(icapReply);