]>
Commit | Line | Data |
---|---|---|
2e4a5466 | 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. | |
2e4a5466 AR |
7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 93 ICAP (RFC 3507) Client */ |
10 | ||
582c2af2 | 11 | #include "squid.h" |
1adcebc3 | 12 | #include "adaptation/Answer.h" |
2e4a5466 | 13 | #include "adaptation/Initiate.h" |
602d9612 | 14 | #include "adaptation/Initiator.h" |
4299f876 | 15 | #include "base/AsyncJobCalls.h" |
602d9612 | 16 | #include "HttpMsg.h" |
2e4a5466 | 17 | |
1733bbba CT |
18 | namespace Adaptation |
19 | { | |
20 | typedef UnaryMemFunT<Initiator, Answer, const Answer &> AnswerDialer; | |
21 | /// Calls expectNoConsumption() if noteAdaptationAnswer async call is | |
22 | /// scheduled but never fired (e.g., because the HTTP transaction aborts). | |
a9336c23 A |
23 | class AnswerCall: public AsyncCallT<AnswerDialer> |
24 | { | |
1733bbba CT |
25 | public: |
26 | AnswerCall(const char *aName, const AnswerDialer &aDialer) : | |
f53969cc | 27 | AsyncCallT<AnswerDialer>(93, 5, aName, aDialer), fired(false) {} |
1733bbba | 28 | virtual void fire() { |
a9336c23 | 29 | fired = true; |
1733bbba CT |
30 | AsyncCallT<AnswerDialer>::fire(); |
31 | } | |
32 | virtual ~AnswerCall() { | |
33 | if (!fired && dialer.arg1.message != NULL && dialer.arg1.message->body_pipe != NULL) | |
34 | dialer.arg1.message->body_pipe->expectNoConsumption(); | |
35 | } | |
36 | ||
37 | private: | |
38 | bool fired; ///< whether we fired the call | |
39 | }; | |
40 | } | |
2e4a5466 | 41 | |
4299f876 | 42 | Adaptation::Initiate::Initiate(const char *aTypeName): AsyncJob(aTypeName) |
2e4a5466 | 43 | { |
2e4a5466 AR |
44 | } |
45 | ||
46 | Adaptation::Initiate::~Initiate() | |
47 | { | |
b8af5c82 AR |
48 | // TODO: we cannot assert(!theInitiator) because that fails if a child |
49 | // constructor fails. AsyncJob should have wasStarted flag so that we | |
50 | // can assert(!(wasStarted && theInitiator)). | |
2e4a5466 AR |
51 | } |
52 | ||
4299f876 AR |
53 | void |
54 | Adaptation::Initiate::initiator(const CbcPointer<Initiator> &i) | |
55 | { | |
56 | Must(!theInitiator); | |
57 | Must(i.valid()); | |
58 | theInitiator = i; | |
59 | } | |
60 | ||
2e4a5466 AR |
61 | // internal cleanup |
62 | void Adaptation::Initiate::swanSong() | |
63 | { | |
64 | debugs(93, 5, HERE << "swan sings" << status()); | |
65 | ||
4299f876 | 66 | if (theInitiator.set()) { |
2e4a5466 AR |
67 | debugs(93, 3, HERE << "fatal failure; sending abort notification"); |
68 | tellQueryAborted(true); // final by default | |
69 | } | |
70 | ||
71 | debugs(93, 5, HERE << "swan sang" << status()); | |
72 | } | |
73 | ||
74 | void Adaptation::Initiate::clearInitiator() | |
75 | { | |
4299f876 | 76 | theInitiator.clear(); |
2e4a5466 AR |
77 | } |
78 | ||
3af10ac0 | 79 | void Adaptation::Initiate::sendAnswer(const Answer &answer) |
2e4a5466 | 80 | { |
1733bbba | 81 | AsyncCall::Pointer call = new AnswerCall("Initiator::noteAdaptationAnswer", |
a9336c23 | 82 | AnswerDialer(theInitiator, &Initiator::noteAdaptationAnswer, answer)); |
1733bbba | 83 | ScheduleCallHere(call); |
2e4a5466 AR |
84 | clearInitiator(); |
85 | } | |
86 | ||
2e4a5466 AR |
87 | void Adaptation::Initiate::tellQueryAborted(bool final) |
88 | { | |
3af10ac0 | 89 | sendAnswer(Answer::Error(final)); |
2e4a5466 AR |
90 | } |
91 | ||
26ac0430 AJ |
92 | const char *Adaptation::Initiate::status() const |
93 | { | |
a0b91cde | 94 | return AsyncJob::status(); // for now |
2e4a5466 | 95 | } |
f53969cc | 96 |