]> git.ipfire.org Git - thirdparty/squid.git/blame - src/adaptation/icap/Launcher.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / adaptation / icap / Launcher.cc
CommitLineData
c824c43b 1/*
4ac4a490 2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
bbc27441
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
c824c43b 7 */
8
bbc27441
AJ
9/* DEBUG: section 93 ICAP (RFC 3507) Client */
10
582c2af2 11#include "squid.h"
3ff65596 12#include "acl/FilledChecklist.h"
1adcebc3 13#include "adaptation/Answer.h"
602d9612 14#include "adaptation/icap/Config.h"
26cc52cb 15#include "adaptation/icap/Launcher.h"
26cc52cb 16#include "adaptation/icap/ServiceRep.h"
602d9612 17#include "adaptation/icap/Xaction.h"
3d93a84d 18#include "base/TextException.h"
582c2af2 19#include "globals.h"
3d93a84d 20#include "HttpMsg.h"
3d93a84d 21#include "HttpReply.h"
602d9612 22#include "HttpRequest.h"
c824c43b 23
26cc52cb 24Adaptation::Icap::Launcher::Launcher(const char *aTypeName,
4cb2536f 25 Adaptation::ServicePointer &aService):
f53969cc
SM
26 AsyncJob(aTypeName),
27 Adaptation::Initiate(aTypeName),
28 theService(aService), theXaction(0), theLaunches(0)
c824c43b 29{
30}
31
26cc52cb 32Adaptation::Icap::Launcher::~Launcher()
c824c43b 33{
34 assert(!theXaction);
35}
36
26cc52cb 37void Adaptation::Icap::Launcher::start()
c824c43b 38{
0bef8dd7 39 Adaptation::Initiate::start();
c824c43b 40
4299f876 41 Must(theInitiator.set());
3ff65596 42 launchXaction("first");
c824c43b 43}
44
3ff65596 45void Adaptation::Icap::Launcher::launchXaction(const char *xkind)
c824c43b 46{
47 Must(!theXaction);
48 ++theLaunches;
3ff65596 49 debugs(93,4, HERE << "launching " << xkind << " xaction #" << theLaunches);
26cc52cb 50 Adaptation::Icap::Xaction *x = createXaction();
3ff65596 51 x->attempts = theLaunches;
129fe2a1
CT
52 if (theLaunches > 1) {
53 x->clearError();
c824c43b 54 x->disableRetries();
129fe2a1 55 }
3ff65596
AR
56 if (theLaunches >= TheConfig.repeat_limit)
57 x->disableRepeats("over icap_retry_limit");
0bef8dd7 58 theXaction = initiateAdaptation(x);
4299f876 59 Must(initiated(theXaction));
c824c43b 60}
61
3af10ac0 62void Adaptation::Icap::Launcher::noteAdaptationAnswer(const Answer &answer)
c824c43b 63{
3af10ac0
AR
64 debugs(93,5, HERE << "launches: " << theLaunches << " answer: " << answer);
65
66 // XXX: akError is unused by ICAPXaction in favor of noteXactAbort()
67 Must(answer.kind != Answer::akError);
68
69 sendAnswer(answer);
0bef8dd7 70 clearAdaptation(theXaction);
c824c43b 71 Must(done());
c824c43b 72}
73
26cc52cb 74void Adaptation::Icap::Launcher::noteInitiatorAborted()
c824c43b 75{
c824c43b 76
77 announceInitiatorAbort(theXaction); // propogate to the transaction
78 clearInitiator();
79 Must(done()); // should be nothing else to do
80
c824c43b 81}
82
4299f876 83void Adaptation::Icap::Launcher::noteXactAbort(XactAbortInfo info)
3ff65596
AR
84{
85 debugs(93,5, HERE << "theXaction:" << theXaction << " launches: " << theLaunches);
c824c43b 86
e1381638 87 // TODO: add more checks from FwdState::checkRetry()?
3ff65596
AR
88 if (canRetry(info)) {
89 clearAdaptation(theXaction);
90 launchXaction("retry");
e1381638 91 } else if (canRepeat(info)) {
3ff65596
AR
92 clearAdaptation(theXaction);
93 launchXaction("repeat");
c824c43b 94 } else {
3ff65596
AR
95 debugs(93,3, HERE << "cannot retry or repeat a failed transaction");
96 clearAdaptation(theXaction);
a22e6cd3
AR
97 tellQueryAborted(false); // caller decides based on bypass, consumption
98 Must(done());
e1381638 99 }
c824c43b 100}
101
26cc52cb 102bool Adaptation::Icap::Launcher::doneAll() const
26ac0430 103{
0bef8dd7 104 return (!theInitiator || !theXaction) && Adaptation::Initiate::doneAll();
c824c43b 105}
106
26cc52cb 107void Adaptation::Icap::Launcher::swanSong()
c824c43b 108{
4299f876 109 if (theInitiator.set())
a22e6cd3 110 tellQueryAborted(true); // always final here because abnormal
c824c43b 111
4299f876 112 if (theXaction.set())
0bef8dd7 113 clearAdaptation(theXaction);
c824c43b 114
0bef8dd7 115 Adaptation::Initiate::swanSong();
c824c43b 116}
3ff65596
AR
117
118bool Adaptation::Icap::Launcher::canRetry(Adaptation::Icap::XactAbortInfo &info) const
119{
120 // We do not check and can exceed zero repeat limit when retrying.
121 // This is by design as the limit does not apply to pconn retrying.
122 return !shutting_down && info.isRetriable;
123}
124
125bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info) const
126{
127 debugs(93,9, HERE << shutting_down);
128 if (theLaunches >= TheConfig.repeat_limit || shutting_down)
129 return false;
130
131 debugs(93,9, HERE << info.isRepeatable); // TODO: update and use status()
132 if (!info.isRepeatable)
133 return false;
134
135 debugs(93,9, HERE << info.icapReply);
136 if (!info.icapReply) // did not get to read an ICAP reply; a timeout?
137 return true;
e1381638 138
9b769c67
AJ
139 debugs(93,9, info.icapReply->sline.status());
140 // XXX: Http::scNone is not the only sign of parse error
141 // XXX: if there is a specific HTTP error code describing the problem, that may be set
142 if (info.icapReply->sline.status() == Http::scNone) // failed to parse the reply; I/O err
3ff65596 143 return true;
e1381638 144
3ff65596
AR
145 ACLFilledChecklist *cl =
146 new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, dash_str);
b248c2a3
AJ
147 cl->reply = info.icapReply;
148 HTTPMSGLOCK(cl->reply);
e1381638 149
2efeb0b7 150 bool result = cl->fastCheck() == ACCESS_ALLOWED;
3ff65596
AR
151 delete cl;
152 return result;
153}
154
155/* ICAPXactAbortInfo */
156
157Adaptation::Icap::XactAbortInfo::XactAbortInfo(HttpRequest *anIcapRequest,
e1381638 158 HttpReply *anIcapReply, bool beRetriable, bool beRepeatable):
f53969cc
SM
159 icapRequest(anIcapRequest),
160 icapReply(anIcapReply),
161 isRetriable(beRetriable),
162 isRepeatable(beRepeatable)
3ff65596 163{
b248c2a3
AJ
164 if (icapRequest)
165 HTTPMSGLOCK(icapRequest);
166 if (icapReply)
167 HTTPMSGLOCK(icapReply);
3ff65596
AR
168}
169
170Adaptation::Icap::XactAbortInfo::XactAbortInfo(const Adaptation::Icap::XactAbortInfo &i):
f53969cc
SM
171 icapRequest(i.icapRequest),
172 icapReply(i.icapReply),
173 isRetriable(i.isRetriable),
174 isRepeatable(i.isRepeatable)
3ff65596 175{
b248c2a3
AJ
176 if (icapRequest)
177 HTTPMSGLOCK(icapRequest);
178 if (icapReply)
179 HTTPMSGLOCK(icapReply);
3ff65596
AR
180}
181
182Adaptation::Icap::XactAbortInfo::~XactAbortInfo()
183{
184 HTTPMSGUNLOCK(icapRequest);
185 HTTPMSGUNLOCK(icapReply);
186}
f53969cc 187