]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/icap/Launcher.cc
2 * Copyright (C) 1996-2016 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"
21 #include "HttpReply.h"
22 #include "HttpRequest.h"
24 Adaptation::Icap::Launcher::Launcher(const char *aTypeName
,
25 Adaptation::ServicePointer
&aService
):
27 Adaptation::Initiate(aTypeName
),
28 theService(aService
), theXaction(0), theLaunches(0)
32 Adaptation::Icap::Launcher::~Launcher()
37 void Adaptation::Icap::Launcher::start()
39 Adaptation::Initiate::start();
41 Must(theInitiator
.set());
42 launchXaction("first");
45 void Adaptation::Icap::Launcher::launchXaction(const char *xkind
)
49 debugs(93,4, HERE
<< "launching " << xkind
<< " xaction #" << theLaunches
);
50 Adaptation::Icap::Xaction
*x
= createXaction();
51 x
->attempts
= theLaunches
;
52 if (theLaunches
> 1) {
56 if (theLaunches
>= TheConfig
.repeat_limit
)
57 x
->disableRepeats("over icap_retry_limit");
58 theXaction
= initiateAdaptation(x
);
59 Must(initiated(theXaction
));
62 void Adaptation::Icap::Launcher::noteAdaptationAnswer(const Answer
&answer
)
64 debugs(93,5, HERE
<< "launches: " << theLaunches
<< " answer: " << answer
);
66 // XXX: akError is unused by ICAPXaction in favor of noteXactAbort()
67 Must(answer
.kind
!= Answer::akError
);
70 clearAdaptation(theXaction
);
74 void Adaptation::Icap::Launcher::noteInitiatorAborted()
77 announceInitiatorAbort(theXaction
); // propogate to the transaction
79 Must(done()); // should be nothing else to do
83 void Adaptation::Icap::Launcher::noteXactAbort(XactAbortInfo info
)
85 debugs(93,5, HERE
<< "theXaction:" << theXaction
<< " launches: " << theLaunches
);
87 // TODO: add more checks from FwdState::checkRetry()?
89 clearAdaptation(theXaction
);
90 launchXaction("retry");
91 } else if (canRepeat(info
)) {
92 clearAdaptation(theXaction
);
93 launchXaction("repeat");
95 debugs(93,3, HERE
<< "cannot retry or repeat a failed transaction");
96 clearAdaptation(theXaction
);
97 tellQueryAborted(false); // caller decides based on bypass, consumption
102 bool Adaptation::Icap::Launcher::doneAll() const
104 return (!theInitiator
|| !theXaction
) && Adaptation::Initiate::doneAll();
107 void Adaptation::Icap::Launcher::swanSong()
109 if (theInitiator
.set())
110 tellQueryAborted(true); // always final here because abnormal
112 if (theXaction
.set())
113 clearAdaptation(theXaction
);
115 Adaptation::Initiate::swanSong();
118 bool Adaptation::Icap::Launcher::canRetry(Adaptation::Icap::XactAbortInfo
&info
) const
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
;
125 bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo
&info
) const
127 debugs(93,9, HERE
<< shutting_down
);
128 if (theLaunches
>= TheConfig
.repeat_limit
|| shutting_down
)
131 debugs(93,9, HERE
<< info
.isRepeatable
); // TODO: update and use status()
132 if (!info
.isRepeatable
)
135 debugs(93,9, HERE
<< info
.icapReply
);
136 if (!info
.icapReply
) // did not get to read an ICAP reply; a timeout?
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
145 ACLFilledChecklist
*cl
=
146 new ACLFilledChecklist(TheConfig
.repeat
, info
.icapRequest
, dash_str
);
147 cl
->reply
= info
.icapReply
;
148 HTTPMSGLOCK(cl
->reply
);
150 bool result
= cl
->fastCheck() == ACCESS_ALLOWED
;
155 /* ICAPXactAbortInfo */
157 Adaptation::Icap::XactAbortInfo::XactAbortInfo(HttpRequest
*anIcapRequest
,
158 HttpReply
*anIcapReply
, bool beRetriable
, bool beRepeatable
):
159 icapRequest(anIcapRequest
),
160 icapReply(anIcapReply
),
161 isRetriable(beRetriable
),
162 isRepeatable(beRepeatable
)
165 HTTPMSGLOCK(icapRequest
);
167 HTTPMSGLOCK(icapReply
);
170 Adaptation::Icap::XactAbortInfo::XactAbortInfo(const Adaptation::Icap::XactAbortInfo
&i
):
171 icapRequest(i
.icapRequest
),
172 icapReply(i
.icapReply
),
173 isRetriable(i
.isRetriable
),
174 isRepeatable(i
.isRepeatable
)
177 HTTPMSGLOCK(icapRequest
);
179 HTTPMSGLOCK(icapReply
);
182 Adaptation::Icap::XactAbortInfo::~XactAbortInfo()
184 HTTPMSGUNLOCK(icapRequest
);
185 HTTPMSGUNLOCK(icapReply
);