ModXact.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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.
7  */
8 
9 #ifndef SQUID_SRC_ADAPTATION_ICAP_MODXACT_H
10 #define SQUID_SRC_ADAPTATION_ICAP_MODXACT_H
11 
12 #include "AccessLogEntry.h"
13 #include "adaptation/icap/InOut.h"
16 #include "BodyPipe.h"
17 #include "http/one/forward.h"
19 
20 /*
21  * ICAPModXact implements ICAP REQMOD and RESPMOD transaction using
22  * ICAPXaction as the base. The ICAPModXact receives a virgin HTTP message
23  * from an ICAP vecoring point, (a.k.a., initiator), communicates with the
24  * ICAP server, and sends the adapted HTTP message headers back.
25  * Virgin/adapted HTTP message body is reveived/sent using BodyPipe
26  * interface. The initiator (or its associate) is expected to send and/or
27  * receive the HTTP body.
28  */
29 
30 namespace Adaptation
31 {
32 namespace Icap
33 {
34 
35 // estimated future presence and size of something (e.g., HTTP body)
36 
38 {
39 
40 public:
41  SizedEstimate(); // not expected by default
42  void expect(int64_t aSize); // expect with any, even unknown size
43  bool expected() const;
44 
45  /* other members can be accessed iff expected() */
46 
47  bool knownSize() const;
48  uint64_t size() const; // can be accessed iff knownSize()
49 
50 private:
51  enum { dtUnexpected = -2, dtUnknown = -1 };
52  int64_t theData; // combines expectation and size info to save RAM
53 };
54 
55 // Virgin body may be used for two activities: (a) writing preview or prime
56 // body to the ICAP server and (b) sending the body back in the echo mode.
57 // Both activities use the same BodyPipe and may be active at the same time.
58 // This class is used to maintain the state of body writing or sending
59 // activity and to coordinate consumption of the shared virgin body buffer.
61 {
62 
63 public:
64  VirginBodyAct();
65 
66  void plan(); // the activity may happen; do not consume at or above offset
67  void disable(); // the activity will not continue; no consumption restrictions
68 
69  bool active() const { return theState == stActive; }
70  bool disabled() const { return theState == stDisabled; }
71 
72  // methods below require active()
73 
74  uint64_t offset() const; // the absolute beginning of not-yet-acted-on data
75  void progress(size_t size); // note processed body bytes
76 
77 private:
78  int64_t theStart; // unprocessed virgin body data offset
79 
80  typedef enum { stUndecided, stActive, stDisabled } State;
82 };
83 
84 // maintains preview-related sizes
85 
86 class Preview
87 {
88 
89 public:
90  Preview(); // disabled
91  void enable(size_t anAd); // enabled with advertised size
92  bool enabled() const;
93 
94  /* other members can be accessed iff enabled() */
95 
96  size_t ad() const; // advertised preview size
97  size_t debt() const; // remains to write
98  bool done() const; // wrote everything
99  bool ieof() const; // premature EOF
100 
101  void wrote(size_t size, bool wroteEof);
102 
103 private:
104  size_t theWritten;
105  size_t theAd;
107 };
108 
111 {
112 public:
118  bool parse(const char *buf, int len, int atEnd, Http::StatusCode *error);
121  size_t hdr_sz; // pedantic XXX: wrong type dictated by HttpHeader::parse() API
122 };
123 
126 {
127 public:
128  /* Http1::ChunkExtensionValueParser API */
129  void parse(Tokenizer &tok, const SBuf &extName) override;
130 
131  bool sawUseOriginalBody() const { return useOriginalBody_ >= 0; }
132  uint64_t useOriginalBody() const { assert(sawUseOriginalBody()); return static_cast<uint64_t>(useOriginalBody_); }
133 
134 private:
135  static const SBuf UseOriginalBodyName;
136 
138  int64_t useOriginalBody_ = -1;
139 };
140 
141 class ModXact: public Xaction, public BodyProducer, public BodyConsumer
142 {
144 
145 public:
146  ModXact(Http::Message *virginHeader, HttpRequest *virginCause, AccessLogEntry::Pointer &alp, ServiceRep::Pointer &s);
147  ~ModXact() override;
148 
149  // BodyProducer methods
152 
153  // BodyConsumer methods
157 
158  /* Xaction API */
159  void startShoveling() override;
160  void handleCommWrote(size_t size) override;
161  void handleCommRead(size_t size) override;
162 
163  void handleCommWroteHeaders();
164  void handleCommWroteBody();
165 
166  // service waiting
167  void noteServiceReady();
168  void noteServiceAvailable();
169 
170 public:
173 
174  // bypasses exceptions if needed and possible
175  void callException(const std::exception &e) override;
176 
178  void detailError(const ErrorDetail::Pointer &errDetail) override;
179  // Icap::Xaction API
180  void clearError() override;
183 
184 private:
185  void start() override;
186 
188  const HttpRequest &virginRequest() const; // Must always be available
189 
190  void estimateVirginBody();
191  void makeAdaptedBodyPipe(const char *what);
192 
193  void waitForService();
194 
195  // will not send anything [else] on the adapted pipe
196  bool doneSending() const;
197 
198  void startWriting();
199  void writeMore();
200  void writePreviewBody();
201  void writePrimeBody();
202  void writeSomeBody(const char *label, size_t size);
203  void decideWritingAfterPreview(const char *previewKind);
204 
205  void startReading();
206  void readMore();
207  bool doneReading() const override { return commEof || state.doneParsing(); }
208  bool doneWriting() const override { return state.doneWriting(); }
209 
210  size_t virginContentSize(const VirginBodyAct &act) const;
211  const char *virginContentData(const VirginBodyAct &act) const;
212  bool virginBodyEndReached(const VirginBodyAct &act) const;
213 
214  void makeRequestHeaders(MemBuf &buf);
215  void makeAllowHeader(MemBuf &buf);
216  void makeUsernameHeader(const HttpRequest *request, MemBuf &buf);
217  void addLastRequestChunk(MemBuf &buf);
218  void openChunk(MemBuf &buf, size_t chunkSize, bool ieof);
219  void closeChunk(MemBuf &buf);
220  void virginConsume();
222 
223  void decideOnPreview();
224  void decideOnRetries();
225  bool shouldAllow204();
226  bool shouldAllow206any();
227  bool shouldAllow206in();
228  bool shouldAllow206out();
229  bool canBackupEverything() const;
230 
231  void prepBackup(size_t expectedSize);
232  void backup(const MemBuf &buf);
233 
234  void parseMore();
235 
236  void parseHeaders();
237  void parseIcapHead();
238  void parseHttpHead();
240 
241  void decideOnParsingBody();
242  void parseBody();
243  void parseIcapTrailer();
244  void maybeAllocateHttpMsg();
245 
246  void handle100Continue();
247  bool validate200Ok();
248  void handle200Ok();
249  void handle204NoContent();
251  void handleUnknownScode();
252 
253  void bypassFailure();
254 
255  void startSending();
256  void disableBypass(const char *reason, bool includeGroupBypass);
257 
258  void prepEchoing();
259  void prepPartialBodyEchoing(uint64_t pos);
260  void echoMore();
261  void updateSources();
262 
263  bool doneAll() const override;
264  void swanSong() override;
265 
266  void stopReceiving();
267  void stopSending(bool nicely);
268  void stopWriting(bool nicely);
269  void stopParsing(const bool checkUnparsedData = true);
270  void stopBackup();
271 
272  void fillPendingStatus(MemBuf &buf) const override;
273  void fillDoneStatus(MemBuf &buf) const override;
274  bool fillVirginHttpHeader(MemBuf&) const override;
275 
276 private:
281  template<class Part>
282  bool parsePart(Part *part, const char *description);
283 
284  void packHead(MemBuf &httpBuf, const Http::Message *head);
285  void encapsulateHead(MemBuf &icapBuf, const char *section, MemBuf &httpBuf, const Http::Message *head);
286  bool gotEncapsulated(const char *section) const;
288  bool expectHttpHeader() const;
290  bool expectHttpBody() const;
292  bool expectIcapTrailers() const;
293  void checkConsuming();
294 
295  void finalizeLogInfo() override;
296 
298  VirginBodyAct virginBodyWriting; // virgin body writing state
299  VirginBodyAct virginBodySending; // virgin body sending state
300  uint64_t virginConsumed; // virgin data consumed so far
301  Preview preview; // use for creating (writing) the preview
302 
303  Http1::TeChunkedParser *bodyParser; // ICAP response body parser
304 
305  bool canStartBypass; // enables bypass of transaction failures
306  bool protectGroupBypass; // protects ServiceGroup-wide bypass of failures
307 
318 
320 
322 
324 
325  class State
326  {
327 
328  public:
329  State();
330 
331  public:
332 
333  bool serviceWaiting; // waiting for ICAP service options
334  bool allowedPostview204; // mmust handle 204 No Content outside preview
335  bool allowedPostview206; // must handle 206 Partial Content outside preview
336  bool allowedPreview206; // must handle 206 Partial Content inside preview
337  bool readyForUob;
339 
340  // will not write anything [else] to the ICAP server connection
341  bool doneWriting() const { return writing == writingReallyDone; }
342 
343  // will not use virgin.body_pipe
344  bool doneConsumingVirgin() const {
345  return writing >= writingAlmostDone
346  && ((sending == sendingAdapted && !readyForUob) ||
347  sending == sendingDone);
348  }
349 
350  // parsed entire ICAP response from the ICAP server
351  bool doneParsing() const { return parsing == psDone; }
352 
353  // is parsing ICAP or HTTP headers read from the ICAP server
354  bool parsingHeaders() const {
355  return parsing == psIcapHeader ||
357  }
358 
360 
361  // measures ICAP request writing progress
364  writingAlmostDone, // waiting for the last write() call to finish
366  } writing;
367 
370  } sending;
371  } state;
372 
374 };
375 
376 // An Launcher that stores ModXact construction info and
377 // creates ModXact when needed
379 {
381 
382 public:
384 
385 protected:
386  Xaction *createXaction() override;
387 
388  void swanSong() override;
389 
391  void updateHistory(bool start);
392 
394 
396 };
397 
398 } // namespace Icap
399 } // namespace Adaptation
400 
401 #endif /* SQUID_SRC_ADAPTATION_ICAP_MODXACT_H */
402 
void disableBypass(const char *reason, bool includeGroupBypass)
Definition: ModXact.cc:717
void callException(const std::exception &e) override
called when the job throws during an async call
Definition: ModXact.cc:665
void prepPartialBodyEchoing(uint64_t pos)
Definition: ModXact.cc:1022
@ hoReply
Definition: HttpHeader.h:37
AccessLogEntry::Pointer alMaster
Master transaction AccessLogEntry.
Definition: ModXact.h:373
ModXactLauncher(Http::Message *virginHeader, HttpRequest *virginCause, AccessLogEntry::Pointer &alp, Adaptation::ServicePointer s)
Definition: ModXact.cc:2023
ModXact(Http::Message *virginHeader, HttpRequest *virginCause, AccessLogEntry::Pointer &alp, ServiceRep::Pointer &s)
Definition: ModXact.cc:54
void openChunk(MemBuf &buf, size_t chunkSize, bool ieof)
Definition: ModXact.cc:376
common parts of HttpRequest and HttpReply
Definition: Message.h:25
void startShoveling() override
starts sending/receiving ICAP messages
Definition: ModXact.cc:189
void swanSong() override
Definition: ModXact.cc:1293
void progress(size_t size)
Definition: ModXact.cc:1912
void enable(size_t anAd)
Definition: ModXact.cc:1931
size_t virginContentSize(const VirginBodyAct &act) const
Definition: ModXact.cc:404
void prepBackup(size_t expectedSize)
void makeRequestHeaders(MemBuf &buf)
Definition: ModXact.cc:1379
enum Adaptation::Icap::Preview::State theState
void packHead(MemBuf &httpBuf, const Http::Message *head)
Definition: ModXact.cc:1628
Http1::TeChunkedParser * bodyParser
Definition: ModXact.h:303
bool virginBodyEndReached(const VirginBodyAct &act) const
Definition: ModXact.cc:395
VirginBodyAct virginBodyWriting
Definition: ModXact.h:298
void noteMoreBodyDataAvailable(BodyPipe::Pointer) override
Definition: ModXact.cc:1233
Parses and stores ICAP trailer header block.
Definition: ModXact.h:110
bool doneAll() const override
whether positive goal has been reached
Definition: ModXact.cc:528
void backup(const MemBuf &buf)
bool doneReading() const override
Definition: ModXact.h:207
void error(char *format,...)
Definition: SBuf.h:93
void stopParsing(const bool checkUnparsedData=true)
Definition: ModXact.cc:1213
void closeChunk(MemBuf &buf)
Definition: ModXact.cc:381
TrailerParser * trailerParser
Definition: ModXact.h:321
void handleCommWrote(size_t size) override
Definition: ModXact.cc:208
void makeAllowHeader(MemBuf &buf)
Definition: ModXact.cc:1519
bool parsePart(Part *part, const char *description)
Definition: ModXact.cc:1091
StatusCode
Definition: StatusCode.h:20
void start() override
called by AsyncStart; do not call directly
Definition: ModXact.cc:88
void fillDoneStatus(MemBuf &buf) const override
Definition: ModXact.cc:1785
void addLastRequestChunk(MemBuf &buf)
Definition: ModXact.cc:369
void encapsulateHead(MemBuf &icapBuf, const char *section, MemBuf &httpBuf, const Http::Message *head)
Definition: ModXact.cc:1581
void stopSending(bool nicely)
Definition: ModXact.cc:614
void wrote(size_t size, bool wroteEof)
Definition: ModXact.cc:1968
void handleCommRead(size_t size) override
Definition: ModXact.cc:567
bool doneSending() const
Definition: ModXact.cc:608
bool readyForUob
got a 206 response and expect a use-origin-body
Definition: ModXact.h:337
bool waitedForService
true if was queued at least once
Definition: ModXact.h:338
void makeAdaptedBodyPipe(const char *what)
Definition: ModXact.cc:1859
void detailError(const ErrorDetail::Pointer &errDetail) override
record error detail in the virgin request if possible
Definition: ModXact.cc:1992
int size
Definition: ModDevPoll.cc:69
void stopWriting(bool nicely)
Definition: ModXact.cc:486
void parse(Tokenizer &tok, const SBuf &extName) override
Definition: ModXact.cc:2077
void finalizeLogInfo() override
Definition: ModXact.cc:1315
bool expectHttpHeader() const
whether ICAP response header indicates HTTP header presence
Definition: ModXact.cc:1118
Definition: MemBuf.h:23
bool expectHttpBody() const
whether ICAP response header indicates HTTP body presence
Definition: ModXact.cc:1123
void fillPendingStatus(MemBuf &buf) const override
Definition: ModXact.cc:1745
void clearError() override
clear stored error details, if any; used for retries/repeats
Definition: ModXact.cc:2004
void updateSources()
Update the Http::Message sources.
Definition: ModXact.cc:2015
#define assert(EX)
Definition: assert.h:17
void writeSomeBody(const char *label, size_t size)
Definition: ModXact.cc:319
bool fillVirginHttpHeader(MemBuf &) const override
Definition: ModXact.cc:1982
void noteBodyProducerAborted(BodyPipe::Pointer) override
Definition: ModXact.cc:1255
const char * virginContentData(const VirginBodyAct &act) const
Definition: ModXact.cc:416
ChunkExtensionValueParser extensionParser
Definition: ModXact.h:323
enum Adaptation::Icap::ModXact::State::Sending sending
AccessLogEntry::Pointer masterLogEntry() override
The master transaction log entry.
Definition: ModXact.h:182
bool doneWriting() const override
Definition: ModXact.h:208
bool canBackupEverything() const
Definition: ModXact.cc:1694
bool expectIcapTrailers() const
whether ICAP response header indicates ICAP trailers presence
Definition: ModXact.cc:1128
void start() override
called by AsyncStart; do not call directly
Definition: Launcher.cc:35
const HttpRequest & virginRequest() const
locates the request, either as a cause or as a virgin message itself
Definition: ModXact.cc:386
Xaction * createXaction() override
Definition: ModXact.cc:2033
enum Adaptation::Icap::ModXact::State::Writing writing
enum Adaptation::Icap::ModXact::State::Parsing parsing
bool doneConsumingVirgin() const
Definition: ModXact.h:344
void decideWritingAfterPreview(const char *previewKind)
determine state.writing after we wrote the entire preview
Definition: ModXact.cc:292
Definition: parse.c:160
squidaio_request_t * head
Definition: aiops.cc:127
void noteMoreBodySpaceAvailable(BodyPipe::Pointer) override
Definition: ModXact.cc:1268
handles ICAP-specific chunk extensions supported by Squid
Definition: ModXact.h:125
void noteBodyConsumerAborted(BodyPipe::Pointer) override
Definition: ModXact.cc:1279
class Adaptation::Icap::ModXact::State state
VirginBodyAct virginBodySending
Definition: ModXact.h:299
bool gotEncapsulated(const char *section) const
Definition: ModXact.cc:1810
AccessLogEntry::Pointer al
Definition: ModXact.h:395
SizedEstimate virginBody
Definition: ModXact.h:297
int64_t useOriginalBody_
the value of the parsed use-original-body chunk extension (or -1)
Definition: ModXact.h:138
void finishNullOrEmptyBodyPreview(MemBuf &buf)
Definition: ModXact.cc:1731
size_t hdr_sz
parsed trailer size if parse() was successful
Definition: ModXact.h:121
void expect(int64_t aSize)
Definition: ModXact.cc:1875
bool parse(const char *buf, int len, int atEnd, Http::StatusCode *error)
Definition: ModXact.cc:2065
bool parseHead(Http::Message *head)
Definition: ModXact.cc:1109
void noteBodyProductionEnded(BodyPipe::Pointer) override
Definition: ModXact.cc:1242
int adaptHistoryId
adaptation history slot reservation
Definition: ModXact.h:319
void makeUsernameHeader(const HttpRequest *request, MemBuf &buf)
Definition: ModXact.cc:1552
size_t debt() const
Definition: ModXact.cc:1962
void updateHistory(bool start)
starts or stops transaction accounting in ICAP history
Definition: ModXact.cc:2048

 

Introduction

Documentation

Support

Miscellaneous