]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ICAP/ICAPClientVector.cc
- Replaced BodyReader with BodyPipe. BodyReader was a
[thirdparty/squid.git] / src / ICAP / ICAPClientVector.cc
CommitLineData
c99de607 1#include "squid.h"
2#include "MsgPipe.h"
3#include "MsgPipeData.h"
4#include "MsgPipeSource.h"
5#include "MsgPipeSink.h"
6#include "HttpRequest.h"
7#include "ICAPClientVector.h"
8#include "ICAPClient.h"
9
10ICAPClientVector::ICAPClientVector(ICAPServiceRep::Pointer aService, const char *aPoint):
11 theOwner(0), vPoint(aPoint),
12 service(aService), virgin(NULL), adapted(NULL)
13{
14 debug(93,3)("%s constructed, this=%p\n", vPoint, this);
15}
16
17ICAPClientVector::~ICAPClientVector()
18{
19 stop(notifyNone);
20 debug(93,3)("%s destructed, this=%p\n", vPoint, this);
21}
22
23void ICAPClientVector::startMod(void *anOwner, HttpRequest *cause, HttpMsg *header)
24{
25 debug(93,5)("%s starting, this=%p\n", vPoint, this);
26
27 theOwner = anOwner;
28
29 virgin = new MsgPipe("virgin"); // this is the place to create a refcount ptr
30 virgin->source = this;
31 virgin->data = new MsgPipeData;
32 virgin->data->setCause(cause);
33 virgin->data->setHeader(header);
34 virgin->data->body = new MemBuf;
35 virgin->data->body->init(ICAP::MsgPipeBufSizeMin, ICAP::MsgPipeBufSizeMax);
36
37 adapted = new MsgPipe("adapted");
38 adapted->sink = this;
39
40#if ICAP_ANCHOR_LOOPBACK
41 adapted->data = new MsgPipeData;
42 adapted->data->setCause(request); // should not hurt
43#else
44 ICAPInitXaction(service, virgin, adapted);
45#endif
46
47 virgin->sendSourceStart(); // we may have virgin data to provide
48 adapted->sendSinkNeed(); // we want adapted response, eventially
49}
50
51void ICAPClientVector::sendMoreData(StoreIOBuffer buf)
52{
53 debug(93,7)("%s::sendMoreData(%p)\n", vPoint, this);
54 //debugs(93,0,HERE << "appending " << buf.length << " bytes");
55 //debugs(93,0,HERE << "body.contentSize = " << virgin->data->body->contentSize());
56 //buf.dump();
57 /*
58 * The caller is responsible for not giving us more data
59 * than will fit in body MemBuf. Caller should use
60 * potentialSpaceSize() to find out how much we can hold.
61 */
62 virgin->data->body->append(buf.data, buf.length);
63 virgin->sendSourceProgress();
64}
65
66int
67ICAPClientVector::potentialSpaceSize()
68{
69 if (virgin == NULL)
70 return 0;
71
72 return (int) virgin->data->body->potentialSpaceSize();
73}
74
75// Owner says we have the entire HTTP message
76void ICAPClientVector::doneSending()
77{
78 debug(93,3)("%s::doneSending(%p)\n", vPoint, this);
79
80#if ICAP_ANCHOR_LOOPBACK
81 /* simple assignments are not the right way to do this */
82 adapted->data->setHeader(virgin->data->header);
83 adapted->data->body = virgin->data->body;
84 noteSourceFinish(adapted);
85 // checkDoneAdapting() does not support loopback mode
86 return;
87#else
88 virgin->sendSourceFinish();
89 checkDoneAdapting(); // may call the owner back, unfortunately
90#endif
91}
92
93// Owner tells us to abort
94void ICAPClientVector::ownerAbort()
95{
96 debug(93,3)("%s::ownerAbort(%p)\n", vPoint, this);
97 stop(notifyIcap);
98}
99
100// ICAP client needs more virgin response data
101void ICAPClientVector::noteSinkNeed(MsgPipe *p)
102{
103 debug(93,3)("%s::noteSinkNeed(%p)\n", vPoint, this);
104
105 if (virgin->data->body->potentialSpaceSize())
106 tellSpaceAvailable();
107}
108
109// ICAP client aborting
110void ICAPClientVector::noteSinkAbort(MsgPipe *p)
111{
112 debug(93,3)("%s::noteSinkAbort(%p)\n", vPoint, this);
113 stop(notifyOwner); // deletes us
114}
115
116// ICAP client is done sending adapted response
117void ICAPClientVector::noteSourceFinish(MsgPipe *p)
118{
119 debug(93,3)("%s::noteSourceFinish(%p)\n", vPoint, this);
120 checkDoneAdapting(); // may delete us
121}
122
123void ICAPClientVector::checkDoneAdapting() {
124 debug(93,5)("%s::checkDoneAdapting(%p): %d & %d\n", vPoint, this,
125 (int)!virgin->source, (int)!adapted->source);
126 // done if we are not sending and are not receiving
127 if (!virgin->source && !adapted->source)
128 tellDoneAdapting(); // deletes us
129}
130
131// ICAP client is aborting
132void ICAPClientVector::noteSourceAbort(MsgPipe *p)
133{
134 debug(93,3)("%s::noteSourceAbort(%p)\n", vPoint, this);
135 stop(notifyOwner); // deletes us
136}
137
138void ICAPClientVector::stop(Notify notify)
139{
140 debug(93,3)("%s::stop(%p, %d)\n", vPoint, this, (int)notify);
141 clean(notify, true);
142}
143
144void ICAPClientVector::clean(Notify notify, bool cleanAdapted)
145{
146 if (virgin != NULL) {
147 if (notify == notifyIcap)
148 virgin->sendSourceAbort();
149 else
150 virgin->source = NULL;
151 virgin = NULL; // refcounted
152 }
153
154 if (cleanAdapted && adapted != NULL) {
155 if (notify == notifyIcap)
156 adapted->sendSinkAbort();
157 else
158 adapted->sink = NULL;
159 adapted = NULL; // refcounted
160 }
161
162 service = NULL;
163
164 if (theOwner) {
165 if (notify == notifyOwner)
166 tellAbortAdapting(); // deletes us
167 else
168 cbdataReferenceDone(theOwner);
169 }
170
171 // not safe to do anything here because we may have been deleted.
172}