]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ICAP/ICAPModXact.h
6e4255d26c1465d59c885e6ae7b3bbb2c8d0ff5d
[thirdparty/squid.git] / src / ICAP / ICAPModXact.h
1
2 /*
3 * $Id: ICAPModXact.h,v 1.11 2008/02/12 23:12:45 rousskov Exp $
4 *
5 *
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
8 *
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
31 *
32 */
33
34 #ifndef SQUID_ICAPMODXACT_H
35 #define SQUID_ICAPMODXACT_H
36
37 #include "BodyPipe.h"
38 #include "ICAPXaction.h"
39 #include "ICAPInOut.h"
40 #include "ICAPLauncher.h"
41
42 /*
43 * ICAPModXact implements ICAP REQMOD and RESPMOD transaction using
44 * ICAPXaction as the base. The ICAPModXact receives a virgin HTTP message
45 * from an ICAP vecoring point, (a.k.a., initiator), communicates with the
46 * ICAP server, and sends the adapted HTTP message headers back.
47 * Virgin/adapted HTTP message body is reveived/sent using BodyPipe
48 * interface. The initiator (or its associate) is expected to send and/or
49 * receive the HTTP body.
50 */
51
52
53 class ChunkedCodingParser;
54
55 // estimated future presence and size of something (e.g., HTTP body)
56
57 class SizedEstimate
58 {
59
60 public:
61 SizedEstimate(); // not expected by default
62 void expect(int64_t aSize); // expect with any, even unknown size
63 bool expected() const;
64
65 /* other members can be accessed iff expected() */
66
67 bool knownSize() const;
68 uint64_t size() const; // can be accessed iff knownSize()
69
70 private:
71 enum { dtUnexpected = -2, dtUnknown = -1 };
72 int64_t theData; // combines expectation and size info to save RAM
73 };
74
75 // Virgin body may be used for two activities: (a) writing preview or prime
76 // body to the ICAP server and (b) sending the body back in the echo mode.
77 // Both activities use the same BodyPipe and may be active at the same time.
78 // This class is used to maintain the state of body writing or sending
79 // activity and to coordinate consumption of the shared virgin body buffer.
80 class VirginBodyAct
81 {
82
83 public:
84 VirginBodyAct();
85
86 void plan(); // the activity may happen; do not consume at or above offset
87 void disable(); // the activity wont continue; no consumption restrictions
88
89 bool active() const { return theState == stActive; }
90 bool disabled() const { return theState == stDisabled; }
91
92 // methods below require active()
93
94 uint64_t offset() const; // the absolute beginning of not-yet-acted-on data
95 void progress(size_t size); // note processed body bytes
96
97 private:
98 int64_t theStart; // unprocessed virgin body data offset
99
100 typedef enum { stUndecided, stActive, stDisabled } State;
101 State theState;
102 };
103
104
105 // maintains preview-related sizes
106
107 class ICAPPreview
108 {
109
110 public:
111 ICAPPreview(); // disabled
112 void enable(size_t anAd); // enabled with advertised size
113 bool enabled() const;
114
115 /* other members can be accessed iff enabled() */
116
117 size_t ad() const; // advertised preview size
118 size_t debt() const; // remains to write
119 bool done() const; // wrote everything
120 bool ieof() const; // premature EOF
121
122 void wrote(size_t size, bool wroteEof);
123
124 private:
125 size_t theWritten;
126 size_t theAd;
127 enum State { stDisabled, stWriting, stIeof, stDone } theState;
128 };
129
130 class ICAPModXact: public ICAPXaction, public BodyProducer, public BodyConsumer
131 {
132
133 public:
134 ICAPModXact(Adaptation::Initiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, ICAPServiceRep::Pointer &s);
135
136 // BodyProducer methods
137 virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer);
138 virtual void noteBodyConsumerAborted(BodyPipe::Pointer);
139
140 // BodyConsumer methods
141 virtual void noteMoreBodyDataAvailable(BodyPipe::Pointer);
142 virtual void noteBodyProductionEnded(BodyPipe::Pointer);
143 virtual void noteBodyProducerAborted(BodyPipe::Pointer);
144
145 // comm handlers
146 virtual void handleCommConnected();
147 virtual void handleCommWrote(size_t size);
148 virtual void handleCommRead(size_t size);
149 void handleCommWroteHeaders();
150 void handleCommWroteBody();
151
152 // service waiting
153 void noteServiceReady();
154
155 public:
156 ICAPInOut virgin;
157 ICAPInOut adapted;
158
159 protected:
160 // bypasses exceptions if needed and possible
161 virtual void callException(const std::exception &e);
162
163 private:
164 virtual void start();
165
166 void estimateVirginBody();
167 void makeAdaptedBodyPipe(const char *what);
168
169 void waitForService();
170
171 // will not send anything [else] on the adapted pipe
172 bool doneSending() const;
173
174 void startWriting();
175 void writeMore();
176 void writePreviewBody();
177 void writePrimeBody();
178 void writeSomeBody(const char *label, size_t size);
179
180 void startReading();
181 void readMore();
182 virtual bool doneReading() const { return commEof || state.doneParsing(); }
183 virtual bool doneWriting() const { return state.doneWriting(); }
184
185 size_t virginContentSize(const VirginBodyAct &act) const;
186 const char *virginContentData(const VirginBodyAct &act) const;
187 bool virginBodyEndReached(const VirginBodyAct &act) const;
188
189 void makeRequestHeaders(MemBuf &buf);
190 void makeUsernameHeader(const HttpRequest *request, MemBuf &buf);
191 void addLastRequestChunk(MemBuf &buf);
192 void openChunk(MemBuf &buf, size_t chunkSize, bool ieof);
193 void closeChunk(MemBuf &buf);
194 void virginConsume();
195 void finishNullOrEmptyBodyPreview(MemBuf &buf);
196
197 void decideOnPreview();
198 void decideOnRetries();
199 bool shouldAllow204();
200 bool canBackupEverything() const;
201
202 void prepBackup(size_t expectedSize);
203 void backup(const MemBuf &buf);
204
205 void parseMore();
206
207 void parseHeaders();
208 void parseIcapHead();
209 void parseHttpHead();
210 bool parseHead(HttpMsg *head);
211
212 void decideOnParsingBody();
213 void parseBody();
214 void maybeAllocateHttpMsg();
215
216 void handle100Continue();
217 bool validate200Ok();
218 void handle200Ok();
219 void handle204NoContent();
220 void handleUnknownScode();
221
222 void bypassFailure();
223
224 void startSending();
225 void disableBypass(const char *reason);
226
227 void prepEchoing();
228 void echoMore();
229
230 virtual bool doneAll() const;
231 virtual void swanSong();
232
233 void stopReceiving();
234 void stopSending(bool nicely);
235 void stopWriting(bool nicely);
236 void stopParsing();
237 void stopBackup();
238
239 virtual void fillPendingStatus(MemBuf &buf) const;
240 virtual void fillDoneStatus(MemBuf &buf) const;
241 virtual bool fillVirginHttpHeader(MemBuf&) const;
242
243 private:
244 void packHead(MemBuf &httpBuf, const HttpMsg *head);
245 void encapsulateHead(MemBuf &icapBuf, const char *section, MemBuf &httpBuf, const HttpMsg *head);
246 bool gotEncapsulated(const char *section) const;
247 void checkConsuming();
248
249
250 HttpReply *icapReply;
251
252 SizedEstimate virginBody;
253 VirginBodyAct virginBodyWriting; // virgin body writing state
254 VirginBodyAct virginBodySending; // virgin body sending state
255 uint64_t virginConsumed; // virgin data consumed so far
256 ICAPPreview preview; // use for creating (writing) the preview
257
258 ChunkedCodingParser *bodyParser; // ICAP response body parser
259
260 bool canStartBypass; // enables bypass of transaction failures
261
262 class State
263 {
264
265 public:
266 State();
267
268 public:
269
270 bool serviceWaiting; // waiting for ICAP service options
271 bool allowedPostview204; // mmust handle 204 No Content outside preview
272
273 // will not write anything [else] to the ICAP server connection
274 bool doneWriting() const { return writing == writingReallyDone; }
275
276 // will not use virgin.body_pipe
277 bool doneConsumingVirgin() const {
278 return writing >= writingAlmostDone
279 && (sending == sendingAdapted || sending == sendingDone);
280 }
281
282 // parsed entire ICAP response from the ICAP server
283 bool doneParsing() const { return parsing == psDone; }
284
285 // is parsing ICAP or HTTP headers read from the ICAP server
286 bool parsingHeaders() const {
287 return parsing == psIcapHeader ||
288 parsing == psHttpHeader;
289 }
290
291 enum Parsing { psIcapHeader, psHttpHeader, psBody, psDone } parsing;
292
293 // measures ICAP request writing progress
294 enum Writing { writingInit, writingConnect, writingHeaders,
295 writingPreview, writingPaused, writingPrime,
296 writingAlmostDone, // waiting for the last write() call to finish
297 writingReallyDone
298 } writing;
299
300 enum Sending { sendingUndecided, sendingVirgin, sendingAdapted,
301 sendingDone
302 } sending;
303 } state;
304
305 CBDATA_CLASS2(ICAPModXact);
306 };
307
308 // An ICAPLauncher that stores ICAPModXact construction info and
309 // creates ICAPModXact when needed
310 class ICAPModXactLauncher: public ICAPLauncher
311 {
312 public:
313 ICAPModXactLauncher(Adaptation::Initiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, Adaptation::ServicePointer s);
314
315 protected:
316 virtual ICAPXaction *createXaction();
317
318 ICAPInOut virgin;
319
320 private:
321 CBDATA_CLASS2(ICAPModXactLauncher);
322 };
323
324 #endif /* SQUID_ICAPMOD_XACT_H */