]> git.ipfire.org Git - thirdparty/squid.git/blame - src/adaptation/icap/Launcher.cc
Add source-maintenance.sh to perform automated Maintenance Updates
[thirdparty/squid.git] / src / adaptation / icap / Launcher.cc
CommitLineData
c824c43b 1/*
b510f3a1 2 * DEBUG: section 93 ICAP (RFC 3507) Client
c824c43b 3 */
4
5#include "squid.h"
3ff65596 6#include "acl/FilledChecklist.h"
26cc52cb
AR
7#include "adaptation/icap/Launcher.h"
8#include "adaptation/icap/Xaction.h"
9#include "adaptation/icap/ServiceRep.h"
3ff65596 10#include "adaptation/icap/Config.h"
3d93a84d
AJ
11#include "base/TextException.h"
12#include "HttpMsg.h"
13#include "HttpRequest.h"
14#include "HttpReply.h"
c824c43b 15
16
26cc52cb 17Adaptation::Icap::Launcher::Launcher(const char *aTypeName,
af6a12ee 18 Adaptation::Initiator *anInitiator, Adaptation::ServicePointer &aService):
26ac0430 19 AsyncJob(aTypeName),
a22e6cd3
AR
20 Adaptation::Initiate(aTypeName, anInitiator),
21 theService(aService), theXaction(0), theLaunches(0)
c824c43b 22{
23}
24
26cc52cb 25Adaptation::Icap::Launcher::~Launcher()
c824c43b 26{
27 assert(!theXaction);
28}
29
26cc52cb 30void Adaptation::Icap::Launcher::start()
c824c43b 31{
0bef8dd7 32 Adaptation::Initiate::start();
c824c43b 33
34 Must(theInitiator);
3ff65596 35 launchXaction("first");
c824c43b 36}
37
3ff65596 38void Adaptation::Icap::Launcher::launchXaction(const char *xkind)
c824c43b 39{
40 Must(!theXaction);
41 ++theLaunches;
3ff65596 42 debugs(93,4, HERE << "launching " << xkind << " xaction #" << theLaunches);
26cc52cb 43 Adaptation::Icap::Xaction *x = createXaction();
3ff65596
AR
44 x->attempts = theLaunches;
45 if (theLaunches > 1)
c824c43b 46 x->disableRetries();
3ff65596
AR
47 if (theLaunches >= TheConfig.repeat_limit)
48 x->disableRepeats("over icap_retry_limit");
0bef8dd7 49 theXaction = initiateAdaptation(x);
c824c43b 50 Must(theXaction);
51}
52
26cc52cb 53void Adaptation::Icap::Launcher::noteAdaptationAnswer(HttpMsg *message)
c824c43b 54{
c824c43b 55 sendAnswer(message);
0bef8dd7 56 clearAdaptation(theXaction);
c824c43b 57 Must(done());
26cc52cb 58 debugs(93,3, HERE << "Adaptation::Icap::Launcher::noteAdaptationAnswer exiting ");
c824c43b 59}
60
26cc52cb 61void Adaptation::Icap::Launcher::noteInitiatorAborted()
c824c43b 62{
c824c43b 63
64 announceInitiatorAbort(theXaction); // propogate to the transaction
65 clearInitiator();
66 Must(done()); // should be nothing else to do
67
c824c43b 68}
69
3ff65596 70// XXX: this call is unused by ICAPXaction in favor of ICAPLauncher::noteXactAbort
26cc52cb 71void Adaptation::Icap::Launcher::noteAdaptationQueryAbort(bool final)
c824c43b 72{
3ff65596 73 debugs(93,5, HERE << "launches: " << theLaunches << "; final: " << final);
0bef8dd7 74 clearAdaptation(theXaction);
e1381638 75
3ff65596
AR
76 Must(done()); // swanSong will notify the initiator
77}
78
79void Adaptation::Icap::Launcher::noteXactAbort(XactAbortInfo &info)
80{
81 debugs(93,5, HERE << "theXaction:" << theXaction << " launches: " << theLaunches);
c824c43b 82
e1381638 83 // TODO: add more checks from FwdState::checkRetry()?
3ff65596
AR
84 if (canRetry(info)) {
85 clearAdaptation(theXaction);
86 launchXaction("retry");
e1381638 87 } else if (canRepeat(info)) {
3ff65596
AR
88 clearAdaptation(theXaction);
89 launchXaction("repeat");
c824c43b 90 } else {
3ff65596
AR
91 debugs(93,3, HERE << "cannot retry or repeat a failed transaction");
92 clearAdaptation(theXaction);
a22e6cd3
AR
93 tellQueryAborted(false); // caller decides based on bypass, consumption
94 Must(done());
e1381638 95 }
c824c43b 96}
97
26cc52cb 98bool Adaptation::Icap::Launcher::doneAll() const
26ac0430 99{
0bef8dd7 100 return (!theInitiator || !theXaction) && Adaptation::Initiate::doneAll();
c824c43b 101}
102
26cc52cb 103void Adaptation::Icap::Launcher::swanSong()
c824c43b 104{
105 if (theInitiator)
a22e6cd3 106 tellQueryAborted(true); // always final here because abnormal
c824c43b 107
108 if (theXaction)
0bef8dd7 109 clearAdaptation(theXaction);
c824c43b 110
0bef8dd7 111 Adaptation::Initiate::swanSong();
c824c43b 112}
3ff65596
AR
113
114bool Adaptation::Icap::Launcher::canRetry(Adaptation::Icap::XactAbortInfo &info) const
115{
116 // We do not check and can exceed zero repeat limit when retrying.
117 // This is by design as the limit does not apply to pconn retrying.
118 return !shutting_down && info.isRetriable;
119}
120
121bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info) const
122{
123 debugs(93,9, HERE << shutting_down);
124 if (theLaunches >= TheConfig.repeat_limit || shutting_down)
125 return false;
126
127 debugs(93,9, HERE << info.isRepeatable); // TODO: update and use status()
128 if (!info.isRepeatable)
129 return false;
130
131 debugs(93,9, HERE << info.icapReply);
132 if (!info.icapReply) // did not get to read an ICAP reply; a timeout?
133 return true;
e1381638 134
3ff65596
AR
135 debugs(93,9, HERE << info.icapReply->sline.status);
136 if (!info.icapReply->sline.status) // failed to parse the reply; I/O err
137 return true;
e1381638 138
3ff65596
AR
139 ACLFilledChecklist *cl =
140 new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, dash_str);
141 cl->reply = HTTPMSGLOCK(info.icapReply);
e1381638 142
3ff65596
AR
143 const bool result = cl->fastCheck();
144 delete cl;
145 return result;
146}
147
148/* ICAPXactAbortInfo */
149
150Adaptation::Icap::XactAbortInfo::XactAbortInfo(HttpRequest *anIcapRequest,
e1381638
AJ
151 HttpReply *anIcapReply, bool beRetriable, bool beRepeatable):
152 icapRequest(anIcapRequest ? HTTPMSGLOCK(anIcapRequest) : NULL),
153 icapReply(anIcapReply ? HTTPMSGLOCK(anIcapReply) : NULL),
154 isRetriable(beRetriable), isRepeatable(beRepeatable)
3ff65596
AR
155{
156}
157
158Adaptation::Icap::XactAbortInfo::XactAbortInfo(const Adaptation::Icap::XactAbortInfo &i):
e1381638
AJ
159 icapRequest(i.icapRequest ? HTTPMSGLOCK(i.icapRequest) : NULL),
160 icapReply(i.icapReply ? HTTPMSGLOCK(i.icapReply) : NULL),
161 isRetriable(i.isRetriable), isRepeatable(i.isRepeatable)
3ff65596
AR
162{
163}
164
165Adaptation::Icap::XactAbortInfo::~XactAbortInfo()
166{
167 HTTPMSGUNLOCK(icapRequest);
168 HTTPMSGUNLOCK(icapReply);
169}