]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/icap/Launcher.cc
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 93 ICAP (RFC 3507) Client */
12 #include "acl/FilledChecklist.h"
13 #include "adaptation/Answer.h"
14 #include "adaptation/icap/Config.h"
15 #include "adaptation/icap/Launcher.h"
16 #include "adaptation/icap/ServiceRep.h"
17 #include "adaptation/icap/Xaction.h"
18 #include "base/TextException.h"
20 #include "HttpReply.h"
22 Adaptation::Icap::Launcher::Launcher(const char *aTypeName
,
23 Adaptation::ServicePointer
&aService
):
25 Adaptation::Initiate(aTypeName
),
26 theService(aService
), theXaction(0), theLaunches(0)
30 Adaptation::Icap::Launcher::~Launcher()
35 void Adaptation::Icap::Launcher::start()
37 Adaptation::Initiate::start();
39 Must(theInitiator
.set());
40 launchXaction("first");
43 void Adaptation::Icap::Launcher::launchXaction(const char *xkind
)
47 debugs(93,4, HERE
<< "launching " << xkind
<< " xaction #" << theLaunches
);
48 Adaptation::Icap::Xaction
*x
= createXaction();
49 x
->attempts
= theLaunches
;
50 if (theLaunches
> 1) {
54 if (theLaunches
>= TheConfig
.repeat_limit
)
55 x
->disableRepeats("over icap_retry_limit");
56 theXaction
= initiateAdaptation(x
);
57 Must(initiated(theXaction
));
60 void Adaptation::Icap::Launcher::noteAdaptationAnswer(const Answer
&answer
)
62 debugs(93,5, HERE
<< "launches: " << theLaunches
<< " answer: " << answer
);
64 // XXX: akError is unused by ICAPXaction in favor of noteXactAbort()
65 Must(answer
.kind
!= Answer::akError
);
68 clearAdaptation(theXaction
);
72 void Adaptation::Icap::Launcher::noteInitiatorAborted()
75 announceInitiatorAbort(theXaction
); // propagate to the transaction
77 Must(done()); // should be nothing else to do
81 void Adaptation::Icap::Launcher::noteXactAbort(XactAbortInfo info
)
83 debugs(93,5, HERE
<< "theXaction:" << theXaction
<< " launches: " << theLaunches
);
85 // TODO: add more checks from FwdState::checkRetry()?
87 clearAdaptation(theXaction
);
88 launchXaction("retry");
89 } else if (canRepeat(info
)) {
90 clearAdaptation(theXaction
);
91 launchXaction("repeat");
93 debugs(93,3, HERE
<< "cannot retry or repeat a failed transaction");
94 clearAdaptation(theXaction
);
95 tellQueryAborted(false); // caller decides based on bypass, consumption
100 bool Adaptation::Icap::Launcher::doneAll() const
102 return (!theInitiator
|| !theXaction
) && Adaptation::Initiate::doneAll();
105 void Adaptation::Icap::Launcher::swanSong()
107 if (theInitiator
.set())
108 tellQueryAborted(true); // always final here because abnormal
110 if (theXaction
.set())
111 clearAdaptation(theXaction
);
113 Adaptation::Initiate::swanSong();
116 bool Adaptation::Icap::Launcher::canRetry(Adaptation::Icap::XactAbortInfo
&info
) const
118 // We do not check and can exceed zero repeat limit when retrying.
119 // This is by design as the limit does not apply to pconn retrying.
120 return !shutting_down
&& info
.isRetriable
;
123 bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo
&info
) const
125 debugs(93,9, HERE
<< shutting_down
);
126 if (theLaunches
>= TheConfig
.repeat_limit
|| shutting_down
)
129 debugs(93,9, HERE
<< info
.isRepeatable
); // TODO: update and use status()
130 if (!info
.isRepeatable
)
133 debugs(93,9, HERE
<< info
.icapReply
);
134 if (!info
.icapReply
) // did not get to read an ICAP reply; a timeout?
137 debugs(93,9, info
.icapReply
->sline
.status());
138 // XXX: Http::scNone is not the only sign of parse error
139 // XXX: if there is a specific HTTP error code describing the problem, that may be set
140 if (info
.icapReply
->sline
.status() == Http::scNone
) // failed to parse the reply; I/O err
143 ACLFilledChecklist
*cl
=
144 new ACLFilledChecklist(TheConfig
.repeat
, info
.icapRequest
, dash_str
);
145 cl
->reply
= info
.icapReply
;
146 HTTPMSGLOCK(cl
->reply
);
148 bool result
= cl
->fastCheck().allowed();
153 /* ICAPXactAbortInfo */
155 Adaptation::Icap::XactAbortInfo::XactAbortInfo(HttpRequest
*anIcapRequest
,
156 HttpReply
*anIcapReply
, bool beRetriable
, bool beRepeatable
):
157 icapRequest(anIcapRequest
),
158 icapReply(anIcapReply
),
159 isRetriable(beRetriable
),
160 isRepeatable(beRepeatable
)
163 HTTPMSGLOCK(icapRequest
);
165 HTTPMSGLOCK(icapReply
);
168 Adaptation::Icap::XactAbortInfo::XactAbortInfo(const Adaptation::Icap::XactAbortInfo
&i
):
169 icapRequest(i
.icapRequest
),
170 icapReply(i
.icapReply
),
171 isRetriable(i
.isRetriable
),
172 isRepeatable(i
.isRepeatable
)
175 HTTPMSGLOCK(icapRequest
);
177 HTTPMSGLOCK(icapReply
);
180 Adaptation::Icap::XactAbortInfo::~XactAbortInfo()
182 HTTPMSGUNLOCK(icapRequest
);
183 HTTPMSGUNLOCK(icapReply
);