Squid Web Cache master
Loading...
Searching...
No Matches
ModXact.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 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"
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 vectoring 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 received/sent using BodyPipe
26 * interface. The initiator (or its associate) is expected to send and/or
27 * receive the HTTP body.
28 */
29
30namespace Adaptation
31{
32namespace Icap
33{
34
35// estimated future presence and size of something (e.g., HTTP body)
36
38{
39
40public:
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
50private:
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
63public:
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
77private:
78 int64_t theStart; // unprocessed virgin body data offset
79
82};
83
84// maintains preview-related sizes
85
87{
88
89public:
90 Preview(); // disabled
91 void enable(size_t anAdvertisedSize); // 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
103private:
105 size_t theAd;
107};
108
111{
112public:
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{
127public:
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
134private:
136
138 int64_t useOriginalBody_ = -1;
139};
140
141class ModXact: public Xaction, public BodyProducer, public BodyConsumer
142{
144
145public:
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
164 void handleCommWroteBody();
165
166 // service waiting
167 void noteServiceReady();
169
170public:
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
184private:
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();
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
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
276private:
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
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) ||
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
367
372
374};
375
376// An Launcher that stores ModXact construction info and
377// creates ModXact when needed
379{
381
382public:
384
385protected:
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
@ hoReply
Definition HttpHeader.h:37
int size
Definition ModDevPoll.cc:70
void error(char *format,...)
squidaio_request_t * head
Definition aiops.cc:129
#define assert(EX)
Definition assert.h:17
handles ICAP-specific chunk extensions supported by Squid
Definition ModXact.h:126
int64_t useOriginalBody_
the value of the parsed use-original-body chunk extension (or -1)
Definition ModXact.h:138
void parse(Tokenizer &tok, const SBuf &extName) override
extracts and then interprets (or ignores) the extension value
Definition ModXact.cc:2072
void start() override
called by AsyncStart; do not call directly
Definition Launcher.cc:35
AccessLogEntry::Pointer al
Definition ModXact.h:395
void updateHistory(bool start)
starts or stops transaction accounting in ICAP history
Definition ModXact.cc:2043
Xaction * createXaction() override
Definition ModXact.cc:2028
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
enum Adaptation::Icap::ModXact::State::Sending sending
enum Adaptation::Icap::ModXact::State::Parsing parsing
enum Adaptation::Icap::ModXact::State::Writing writing
void swanSong() override
Definition ModXact.cc:1289
const char * virginContentData(const VirginBodyAct &act) const
Definition ModXact.cc:416
void openChunk(MemBuf &buf, size_t chunkSize, bool ieof)
Definition ModXact.cc:376
void noteMoreBodyDataAvailable(BodyPipe::Pointer) override
Definition ModXact.cc:1229
void start() override
called by AsyncStart; do not call directly
Definition ModXact.cc:88
void packHead(MemBuf &httpBuf, const Http::Message *head)
Definition ModXact.cc:1624
TrailerParser * trailerParser
Definition ModXact.h:321
void stopWriting(bool nicely)
Definition ModXact.cc:482
void noteBodyProductionEnded(BodyPipe::Pointer) override
Definition ModXact.cc:1238
Http1::TeChunkedParser * bodyParser
Definition ModXact.h:303
bool doneAll() const override
whether positive goal has been reached
Definition ModXact.cc:524
void makeAllowHeader(MemBuf &buf)
Definition ModXact.cc:1515
void clearError() override
clear stored error details, if any; used for retries/repeats
Definition ModXact.cc:1999
void writeSomeBody(const char *label, size_t size)
Definition ModXact.cc:319
void callException(const std::exception &e) override
called when the job throws during an async call
Definition ModXact.cc:661
bool expectHttpBody() const
whether ICAP response header indicates HTTP body presence
Definition ModXact.cc:1119
bool parseHead(Http::Message *head)
Definition ModXact.cc:1105
bool fillVirginHttpHeader(MemBuf &) const override
Definition ModXact.cc:1977
void stopSending(bool nicely)
Definition ModXact.cc:610
SizedEstimate virginBody
Definition ModXact.h:297
bool virginBodyEndReached(const VirginBodyAct &act) const
Definition ModXact.cc:395
bool gotEncapsulated(const char *section) const
Definition ModXact.cc:1805
AccessLogEntry::Pointer alMaster
Master transaction AccessLogEntry.
Definition ModXact.h:373
void updateSources()
Update the Http::Message sources.
Definition ModXact.cc:2010
VirginBodyAct virginBodySending
Definition ModXact.h:299
void stopParsing(const bool checkUnparsedData=true)
Definition ModXact.cc:1209
bool parsePart(Part *part, const char *description)
Definition ModXact.cc:1087
void startShoveling() override
starts sending/receiving ICAP messages
Definition ModXact.cc:189
bool doneSending() const
Definition ModXact.cc:604
void backup(const MemBuf &buf)
void detailError(const ErrorDetail::Pointer &errDetail) override
record error detail in the virgin request if possible
Definition ModXact.cc:1987
AccessLogEntry::Pointer masterLogEntry() override
The master transaction log entry.
Definition ModXact.h:182
int adaptHistoryId
adaptation history slot reservation
Definition ModXact.h:319
class Adaptation::Icap::ModXact::State state
void closeChunk(MemBuf &buf)
Definition ModXact.cc:381
void addLastRequestChunk(MemBuf &buf)
Definition ModXact.cc:369
void disableBypass(const char *reason, bool includeGroupBypass)
Definition ModXact.cc:713
VirginBodyAct virginBodyWriting
Definition ModXact.h:298
bool canBackupEverything() const
Definition ModXact.cc:1689
void prepBackup(size_t expectedSize)
bool expectHttpHeader() const
whether ICAP response header indicates HTTP header presence
Definition ModXact.cc:1114
void noteBodyConsumerAborted(BodyPipe::Pointer) override
Definition ModXact.cc:1275
size_t virginContentSize(const VirginBodyAct &act) const
Definition ModXact.cc:404
void handleCommRead(size_t size) override
Definition ModXact.cc:563
void fillDoneStatus(MemBuf &buf) const override
Definition ModXact.cc:1780
void prepPartialBodyEchoing(uint64_t pos)
Definition ModXact.cc:1018
bool expectIcapTrailers() const
whether ICAP response header indicates ICAP trailers presence
Definition ModXact.cc:1124
void fillPendingStatus(MemBuf &buf) const override
Definition ModXact.cc:1740
void noteMoreBodySpaceAvailable(BodyPipe::Pointer) override
Definition ModXact.cc:1264
void makeRequestHeaders(MemBuf &buf)
Definition ModXact.cc:1375
bool doneWriting() const override
Definition ModXact.h:208
ChunkExtensionValueParser extensionParser
Definition ModXact.h:323
void encapsulateHead(MemBuf &icapBuf, const char *section, MemBuf &httpBuf, const Http::Message *head)
Definition ModXact.cc:1577
void finishNullOrEmptyBodyPreview(MemBuf &buf)
Definition ModXact.cc:1726
void noteBodyProducerAborted(BodyPipe::Pointer) override
Definition ModXact.cc:1251
bool doneReading() const override
Definition ModXact.h:207
void makeAdaptedBodyPipe(const char *what)
Definition ModXact.cc:1854
void makeUsernameHeader(const HttpRequest *request, MemBuf &buf)
Definition ModXact.cc:1548
void handleCommWrote(size_t size) override
Definition ModXact.cc:208
void finalizeLogInfo() override
Definition ModXact.cc:1311
void decideWritingAfterPreview(const char *previewKind)
determine state.writing after we wrote the entire preview
Definition ModXact.cc:292
const HttpRequest & virginRequest() const
locates the request, either as a cause or as a virgin message itself
Definition ModXact.cc:386
void enable(size_t anAdvertisedSize)
Definition ModXact.cc:1926
void wrote(size_t size, bool wroteEof)
Definition ModXact.cc:1963
enum Adaptation::Icap::Preview::State theState
void expect(int64_t aSize)
Definition ModXact.cc:1870
Parses and stores ICAP trailer header block.
Definition ModXact.h:111
size_t hdr_sz
parsed trailer size if parse() was successful
Definition ModXact.h:121
bool parse(const char *buf, int len, int atEnd, Http::StatusCode *error)
Definition ModXact.cc:2060
common parts of HttpRequest and HttpReply
Definition Message.h:26
Definition SBuf.h:94
StatusCode
Definition StatusCode.h:20
Definition parse.c:160