]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ICAP/ICAPModXact.h
Author: wessels & Christos Tsantilas
[thirdparty/squid.git] / src / ICAP / ICAPModXact.h
CommitLineData
774c051c 1
2/*
47f6e231 3 * $Id: ICAPModXact.h,v 1.10 2007/08/13 17:20:53 hno Exp $
774c051c 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
33ff9dbf 16 * sources; see the CREDITS file for full details.
774c051c 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
c824c43b 37#include "BodyPipe.h"
774c051c 38#include "ICAPXaction.h"
5f8252d2 39#include "ICAPInOut.h"
c824c43b 40#include "ICAPLauncher.h"
5f8252d2 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 */
774c051c 51
774c051c 52
53class ChunkedCodingParser;
54
55// estimated future presence and size of something (e.g., HTTP body)
56
57class SizedEstimate
58{
59
60public:
61 SizedEstimate(); // not expected by default
47f6e231 62 void expect(int64_t aSize); // expect with any, even unknown size
774c051c 63 bool expected() const;
64
65 /* other members can be accessed iff expected() */
66
67 bool knownSize() const;
47f6e231 68 uint64_t size() const; // can be accessed iff knownSize()
774c051c 69
70private:
71 enum { dtUnexpected = -2, dtUnknown = -1 };
47f6e231 72 int64_t theData; // combines expectation and size info to save RAM
774c051c 73};
74
5f8252d2 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.
80class VirginBodyAct
774c051c 81{
82
83public:
478cfe99 84 VirginBodyAct();
774c051c 85
5f8252d2 86 void plan(); // the activity may happen; do not consume at or above offset
87 void disable(); // the activity wont continue; no consumption restrictions
478cfe99 88
89 bool active() const { return theState == stActive; }
90 bool disabled() const { return theState == stDisabled; }
774c051c 91
92 // methods below require active()
93
47f6e231 94 uint64_t offset() const; // the absolute beginning of not-yet-acted-on data
5f8252d2 95 void progress(size_t size); // note processed body bytes
774c051c 96
97private:
47f6e231 98 int64_t theStart; // unprocessed virgin body data offset
478cfe99 99
100 typedef enum { stUndecided, stActive, stDisabled } State;
101 State theState;
774c051c 102};
103
5f8252d2 104
774c051c 105// maintains preview-related sizes
106
107class ICAPPreview
108{
109
110public:
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
c99de607 122 void wrote(size_t size, bool wroteEof);
774c051c 123
124private:
125 size_t theWritten;
126 size_t theAd;
127 enum State { stDisabled, stWriting, stIeof, stDone } theState;
128};
129
5f8252d2 130class ICAPInitiator;
131
132class ICAPModXact: public ICAPXaction, public BodyProducer, public BodyConsumer
774c051c 133{
134
774c051c 135public:
5f8252d2 136 ICAPModXact(ICAPInitiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, ICAPServiceRep::Pointer &s);
774c051c 137
5f8252d2 138 // BodyProducer methods
139 virtual void noteMoreBodySpaceAvailable(BodyPipe &);
140 virtual void noteBodyConsumerAborted(BodyPipe &);
774c051c 141
5f8252d2 142 // BodyConsumer methods
143 virtual void noteMoreBodyDataAvailable(BodyPipe &);
144 virtual void noteBodyProductionEnded(BodyPipe &);
145 virtual void noteBodyProducerAborted(BodyPipe &);
774c051c 146
147 // comm handlers
148 virtual void handleCommConnected();
149 virtual void handleCommWrote(size_t size);
150 virtual void handleCommRead(size_t size);
151 void handleCommWroteHeaders();
152 void handleCommWroteBody();
153
154 // service waiting
155 void noteServiceReady();
156
5f8252d2 157public:
158 ICAPInOut virgin;
159 ICAPInOut adapted;
160
478cfe99 161protected:
162 // bypasses exceptions if needed and possible
163 virtual void callException(const TextException &e);
164
774c051c 165private:
5f8252d2 166 virtual void start();
167
774c051c 168 void estimateVirginBody();
5f8252d2 169 void makeAdaptedBodyPipe(const char *what);
774c051c 170
171 void waitForService();
172
173 // will not send anything [else] on the adapted pipe
174 bool doneSending() const;
175
176 void startWriting();
177 void writeMore();
5f8252d2 178 void writePreviewBody();
774c051c 179 void writePrimeBody();
180 void writeSomeBody(const char *label, size_t size);
181
182 void startReading();
183 void readMore();
184 virtual bool doneReading() const { return commEof || state.doneParsing(); }
c99de607 185 virtual bool doneWriting() const { return state.doneWriting(); }
774c051c 186
5f8252d2 187 size_t virginContentSize(const VirginBodyAct &act) const;
188 const char *virginContentData(const VirginBodyAct &act) const;
189 bool virginBodyEndReached(const VirginBodyAct &act) const;
190
774c051c 191 void makeRequestHeaders(MemBuf &buf);
5f8252d2 192 void makeUsernameHeader(const HttpRequest *request, MemBuf &buf);
774c051c 193 void addLastRequestChunk(MemBuf &buf);
c99de607 194 void openChunk(MemBuf &buf, size_t chunkSize, bool ieof);
195 void closeChunk(MemBuf &buf);
774c051c 196 void virginConsume();
5f8252d2 197 void finishNullOrEmptyBodyPreview(MemBuf &buf);
774c051c 198
c824c43b 199 void decideOnPreview();
200 void decideOnRetries();
774c051c 201 bool shouldAllow204();
c824c43b 202 bool canBackupEverything() const;
203
774c051c 204 void prepBackup(size_t expectedSize);
205 void backup(const MemBuf &buf);
206
207 void parseMore();
208
209 void parseHeaders();
210 void parseIcapHead();
211 void parseHttpHead();
212 bool parseHead(HttpMsg *head);
5f8252d2 213 void inheritVirginProperties(HttpRequest &newR, const HttpRequest &oldR);
774c051c 214
5f8252d2 215 void decideOnParsingBody();
774c051c 216 void parseBody();
774c051c 217 void maybeAllocateHttpMsg();
218
219 void handle100Continue();
b559db5d 220 bool validate200Ok();
774c051c 221 void handle200Ok();
222 void handle204NoContent();
223 void handleUnknownScode();
224
478cfe99 225 void bypassFailure();
226
227 void startSending();
228 void disableBypass(const char *reason);
229
230 void prepEchoing();
774c051c 231 void echoMore();
232
233 virtual bool doneAll() const;
5f8252d2 234 virtual void swanSong();
774c051c 235
774c051c 236 void stopReceiving();
237 void stopSending(bool nicely);
c99de607 238 void stopWriting(bool nicely);
774c051c 239 void stopParsing();
240 void stopBackup();
241
242 virtual void fillPendingStatus(MemBuf &buf) const;
243 virtual void fillDoneStatus(MemBuf &buf) const;
3cfc19b3 244 virtual bool fillVirginHttpHeader(MemBuf&) const;
774c051c 245
246private:
247 void packHead(MemBuf &httpBuf, const HttpMsg *head);
248 void encapsulateHead(MemBuf &icapBuf, const char *section, MemBuf &httpBuf, const HttpMsg *head);
249 bool gotEncapsulated(const char *section) const;
5f8252d2 250 void checkConsuming();
774c051c 251
774c051c 252
253 HttpReply *icapReply;
254
255 SizedEstimate virginBody;
5f8252d2 256 VirginBodyAct virginBodyWriting; // virgin body writing state
257 VirginBodyAct virginBodySending; // virgin body sending state
47f6e231 258 uint64_t virginConsumed; // virgin data consumed so far
774c051c 259 ICAPPreview preview; // use for creating (writing) the preview
260
261 ChunkedCodingParser *bodyParser; // ICAP response body parser
262
478cfe99 263 bool canStartBypass; // enables bypass of transaction failures
264
774c051c 265 class State
266 {
267
268 public:
269 State();
270
271 public:
272
5f8252d2 273 bool serviceWaiting; // waiting for ICAP service options
274 bool allowedPostview204; // mmust handle 204 No Content outside preview
774c051c 275
276 // will not write anything [else] to the ICAP server connection
c99de607 277 bool doneWriting() const { return writing == writingReallyDone; }
774c051c 278
5f8252d2 279 // will not use virgin.body_pipe
280 bool doneConsumingVirgin() const { return writing >= writingAlmostDone
281 && (sending == sendingAdapted || sending == sendingDone); }
282
774c051c 283 // parsed entire ICAP response from the ICAP server
284 bool doneParsing() const { return parsing == psDone; }
285
286 // is parsing ICAP or HTTP headers read from the ICAP server
287 bool parsingHeaders() const
288 {
289 return parsing == psIcapHeader ||
290 parsing == psHttpHeader;
291 }
292
293 enum Parsing { psIcapHeader, psHttpHeader, psBody, psDone } parsing;
294
295 // measures ICAP request writing progress
296 enum Writing { writingInit, writingConnect, writingHeaders,
c99de607 297 writingPreview, writingPaused, writingPrime,
298 writingAlmostDone, // waiting for the last write() call to finish
299 writingReallyDone } writing;
774c051c 300
301 enum Sending { sendingUndecided, sendingVirgin, sendingAdapted,
302 sendingDone } sending;
303 }
304
305 state;
306
307 CBDATA_CLASS2(ICAPModXact);
308};
309
c824c43b 310// An ICAPLauncher that stores ICAPModXact construction info and
311// creates ICAPModXact when needed
312class ICAPModXactLauncher: public ICAPLauncher
313{
314public:
315 ICAPModXactLauncher(ICAPInitiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, ICAPServiceRep::Pointer &s);
316
317protected:
318 virtual ICAPXaction *createXaction();
319
320 ICAPInOut virgin;
321
322private:
323 CBDATA_CLASS2(ICAPModXactLauncher);
324};
774c051c 325
326#endif /* SQUID_ICAPMOD_XACT_H */