{
clearAdaptation(adaptedHeadSource); // we do not expect more messages
- if (abortOnBadEntry("entry went bad while waiting for adapted headers"))
+ if (abortOnBadEntry("entry went bad while waiting for adapted headers")) {
+ // If the adapted response has a body, the ICAP side needs to know
+ // that nobody will consume that body. We will be destroyed upon
+ // return. Tell the ICAP side that it is on its own.
+ HttpReply *rep = dynamic_cast<HttpReply*>(msg);
+ assert(rep);
+ if (rep->body_pipe != NULL)
+ rep->body_pipe->expectNoConsumption();
+
return;
+ }
HttpReply *rep = dynamic_cast<HttpReply*>(msg);
assert(rep);
AnswerDialer &operator =(const AnswerDialer &); // not implemented
};
+/// Calls expectNoConsumption() if noteAdaptationAnswer async call is
+/// scheduled but never fired (e.g., because the HTTP transaction aborts).
+class AnswerCall: public AsyncCallT<AnswerDialer>{
+ AnswerCall(const char *aName, const AnswerDialer &aDialer) :
+ AsyncCallT<AnswerDialer>(93, 5, aName, aDialer), fired(false) {}
+ virtual void fire() {
+ fired = true;
+ AsyncCallT<AnswerDialer>::fire();
+ }
+ virtual ~AnswerCall() {
+ if (!fired && dialer.arg1.message != NULL && dialer.arg1.message->body_pipe != NULL)
+ dialer.arg1.message->body_pipe->expectNoConsumption();
+ }
+ bool fired; ///< whether we fired the call
+};
+
} // namespace Adaptation
void Adaptation::Initiate::sendAnswer(HttpMsg *msg)
{
assert(msg);
- CallJob(93, 5, __FILE__, __LINE__, "Initiator::noteAdaptationAnswer",
- AnswerDialer(theInitiator, &Initiator::noteAdaptationAnswer, msg));
+ AsyncCall::Pointer call = new AnswerCall("Initiator::noteAdaptationAnswer",
+ AnswerDialer(theInitiator, &Initiator::noteAdaptationAnswer, answer));
+ ScheduleCallHere(call);
clearInitiator();
}