74 debugs(93,5,
'#' << iterations <<
" plan: " << thePlan);
78 if (thePlan.exhausted()) {
93 "\tPossible service loop with " <<
94 theGroup->kind <<
" " << theGroup->id <<
", plan=" << thePlan);
95 throw TexcHere(
"too many adaptations");
99 Must(service !=
nullptr);
100 debugs(93,5,
"using adaptation service: " << service->
cfg().
key);
108 theLauncher = initiateAdaptation(
110 Must(initiated(theLauncher));
117 switch (answer.
kind) {
123 handleAdaptationBlock(answer);
127 handleAdaptationError(answer.
final);
142 debugs(93,3,
"in request satisfaction mode");
153 clearAdaptation(theLauncher);
154 if (!updatePlan(
true))
155 thePlan.next(filter());
161 announceInitiatorAbort(theLauncher);
163 mustStop(
"initiator gone");
168 debugs(93,5,
"blocked by " << answer);
169 clearAdaptation(theLauncher);
177 debugs(93,5,
"final: " <<
final <<
" plan: " << thePlan);
178 clearAdaptation(theLauncher);
182 const bool srcIntact = !theMsg->body_pipe ||
183 !theMsg->body_pipe->consumedSize();
185 Must(!thePlan.exhausted());
186 const bool canIgnore = thePlan.current()->cfg().bypass;
187 debugs(85,5,
"flags: " << srcIntact << canIgnore << adapted);
190 if (thePlan.replacement(filter()) !=
nullptr) {
191 debugs(93,3,
"trying a replacement service");
197 if (canIgnore && srcIntact && adapted) {
198 debugs(85,3,
"responding with older adapted msg");
200 mustStop(
"sent older adapted msg");
205 const bool useVirgin = canIgnore && !adapted && srcIntact;
206 tellQueryAborted(!useVirgin);
207 mustStop(
"group failure");
217 if (theInitiator.set())
218 tellQueryAborted(
true);
220 if (initiated(theLauncher))
221 clearAdaptation(theLauncher);
233 debugs(85,9,
"no history to store a service-proposed plan");
239 debugs(85,9,
"no service-proposed plan received");
244 debugs(85,3,
"rejecting service-proposed plan");
248 debugs(85,3,
"retiring old plan: " << thePlan);
254 if (!future.
empty()) {
256 debugs(85,3,
"noted future service-proposed plan: " << future);
262 debugs(85,3,
"adopted service-proposed plan: " << thePlan);
SBuf StringToSBuf(const String &s)
create a new SBuf from a String by copying contents
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
#define CBDATA_NAMESPACED_CLASS_INIT(namespace, type)
summarizes adaptation service answer for the noteAdaptationAnswer() API
static Answer Forward(Http::Message *aMsg)
create an akForward answer
Kind kind
the type of the answer
Http::MessagePointer message
HTTP request or response to forward.
bool final
whether the error, if any, cannot be bypassed
@ akForward
forward the supplied adapted HTTP message
@ akBlock
block or deny the master xaction; see authority
@ akError
no adapted message will come; see bypassable
static bool needHistory
HttpRequest adaptation history should recorded.
static int service_iteration_limit
DynamicServiceGroup configuration to remember future dynamic chains.
bool empty() const
no services added
a temporary service chain built upon another service request
static void Split(const ServiceFilter &filter, const String &ids, DynamicGroupCfg ¤t, DynamicGroupCfg &future)
separates dynamic services matching current location from future ones
bool extractNextServices(String &value)
returns true, fills the value, and resets iff next services were set
void setFutureServices(const DynamicGroupCfg &services)
sets future services for the Adaptation::AccessCheck to notice
void recordAdaptationService(SBuf &srvId)
void start() override
called by AsyncStart; do not call directly
void step()
launches adaptation for the service selected by the plan
ServiceFilter filter() const
creates service filter for the current step
Iterator(Http::Message *virginHeader, HttpRequest *virginCause, const AccessLogEntryPointer &, const Adaptation::ServiceGroupPointer &aGroup)
bool updatePlan(bool adopt)
replace the current group and plan with service-proposed ones if needed
void handleAdaptedHeader(Http::Message *msg)
void noteAdaptationAnswer(const Answer &answer) override
void handleAdaptationError(bool final)
HttpRequest * theCause
the cause of the original virgin message
Http::Message * theMsg
the message being adapted (virgin for each step)
void handleAdaptationBlock(const Answer &answer)
bool doneAll() const override
whether positive goal has been reached
void noteInitiatorAborted() override
a group of services that must be used one after another
information used to search for adaptation services
const ServiceConfig & cfg() const
virtual Initiate * makeXactLauncher(Http::Message *virginHeader, HttpRequest *virginCause, AccessLogEntry::Pointer &alp)=0
virtual bool doneAll() const
whether positive goal has been reached
virtual void start()
called by AsyncStart; do not call directly
Adaptation::History::Pointer adaptHistory(bool createIfNone=false) const
Returns possibly nil history, creating it if requested.
void clearError()
clear error details, useful for retries/repeats
common parts of HttpRequest and HttpReply
#define debugs(SECTION, LEVEL, CONTENT)
void HTTPMSGUNLOCK(M *&a)
void HTTPMSGLOCK(Http::Message *a)