]> git.ipfire.org Git - thirdparty/squid.git/blame - src/StoreClient.h
Simplify appending SBuf to String (#2108)
[thirdparty/squid.git] / src / StoreClient.h
CommitLineData
c8be6d7b 1/*
1f7b830e 2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
c8be6d7b 3 *
bbc27441
AJ
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.
c8be6d7b 7 */
8
ff9d9458
FC
9#ifndef SQUID_SRC_STORECLIENT_H
10#define SQUID_SRC_STORECLIENT_H
c8be6d7b 11
e227da8d 12#include "acl/ChecklistFiller.h"
1fa761af 13#include "base/AsyncCall.h"
f925268a 14#include "base/forward.h"
582c2af2 15#include "dlink.h"
122a6e3c 16#include "store/ParsingBuffer.h"
c8be6d7b 17#include "StoreIOBuffer.h"
e877aaac 18#include "StoreIOState.h"
c8be6d7b 19
122a6e3c
AR
20/// A storeClientCopy() callback function.
21///
22/// Upon storeClientCopy() success, StoreIOBuffer::flags.error is zero, and
23/// * HTTP response headers (if any) are available via MemObject::freshestReply();
24/// * HTTP response body bytes (if any) are available via StoreIOBuffer.
25///
26/// STCB callbacks may use response semantics to detect certain EOF conditions.
27/// Callbacks that expect HTTP headers may call store_client::atEof(). Similar
28/// to clientStreamCallback() callbacks, callbacks dedicated to receiving HTTP
29/// bodies may use zero StoreIOBuffer::length as an EOF condition.
30///
31/// Errors are indicated by setting StoreIOBuffer flags.error.
32using STCB = void (void *, StoreIOBuffer);
c8be6d7b 33
3b13a8fd 34class StoreEntry;
819be284 35class ACLFilledChecklist;
d2a6dcba 36class LogTags;
e6ccf245 37
ee989932 38// TODO: Merge store_client into StoreClient.
7976fed3 39/// a storeGetPublic*() caller
e227da8d 40class StoreClient: public Acl::ChecklistFiller
62e76326 41{
42
e6ccf245 43public:
337b9aa4 44 ~StoreClient () override {}
62e76326 45
d2a6dcba 46 /// \return LogTags (if the class logs transactions) or nil (otherwise)
7976fed3 47 virtual LogTags *loggingTags() const = 0;
d2a6dcba 48
819be284 49protected:
d2a6dcba
EB
50 /// \returns whether the caller must collapse on the given entry
51 /// Before returning true, updates common collapsing-related stats.
52 /// See also: StoreEntry::hittingRequiresCollapsing().
7976fed3 53 bool startCollapsingOn(const StoreEntry &, const bool doingRevalidation) const;
d2a6dcba 54
819be284
EB
55 // These methods only interpret Squid configuration. Their allowances are
56 // provisional -- other factors may prevent collapsed forwarding. The first
57 // two exist primarily to distinguish two major CF cases in callers code.
58 /// whether Squid configuration allows us to become a CF initiator
59 bool mayInitiateCollapsing() const { return onCollapsingPath(); }
819be284
EB
60 /// whether Squid configuration allows collapsing for this transaction
61 bool onCollapsingPath() const;
ee989932
AR
62
63 /// whether startCollapsingOn() was called and returned true
64 mutable bool didCollapse = false;
e6ccf245 65};
e6ccf245 66
9a0a18de 67#if USE_DELAY_POOLS
b67e2c8c 68#include "DelayId.h"
69#endif
70
c8be6d7b 71/* keep track each client receiving data from that particular StoreEntry */
62e76326 72
73class store_client
74{
5c2f68b7 75 CBDATA_CLASS(store_client);
62e76326 76
528b2c61 77public:
836d3c0b 78 explicit store_client(StoreEntry *);
2f44bd34 79 ~store_client();
1fa761af 80
3a5c8b44
AR
81 /// the client will not use HTTP response bytes with lower offsets (if any)
82 auto discardableHttpEnd() const { return discardableHttpEnd_; }
1fa761af 83
528b2c61 84 int getType() const;
1fa761af
EB
85
86 /// React to the end of reading the response from disk. There will be no
87 /// more readHeader() and readBody() callbacks for the current storeRead()
88 /// swapin after this notification.
89 void noteSwapInDone(bool error);
90
528b2c61 91 void doCopy (StoreEntry *e);
92 void readHeader(const char *buf, ssize_t len);
beae59b0 93 void readBody(const char *buf, ssize_t len);
1fa761af
EB
94
95 /// Request StoreIOBuffer-described response data via an asynchronous STCB
96 /// callback. At most one outstanding request is allowed per store_client.
528b2c61 97 void copy(StoreEntry *, StoreIOBuffer, STCB *, void *);
1fa761af 98
fcc35180 99 void dumpStats(MemBuf * output, int clientNumber) const;
528b2c61 100
122a6e3c
AR
101 // TODO: When STCB gets a dedicated Answer type, move this info there.
102 /// Whether the last successful storeClientCopy() answer was known to
103 /// contain the last body bytes of the HTTP response
104 /// \retval true requesting bytes at higher offsets is futile
105 /// \sa STCB
106 bool atEof() const { return atEof_; }
107
c8be6d7b 108#if STORE_CLIENT_LIST_DEBUG
62e76326 109
c8be6d7b 110 void *owner;
111#endif
62e76326 112
f53969cc 113 StoreEntry *entry; /* ptr to the parent StoreEntry, argh! */
d3b3ab85 114 StoreIOState::Pointer swapin_sio;
62e76326 115
26ac0430 116 struct {
1fa761af
EB
117 /// whether we are expecting a response to be swapped in from disk
118 /// (i.e. whether async storeRead() is currently in progress)
119 // TODO: a better name reflecting the 'in' scope of the flag
3dd52a0b 120 bool disk_io_pending;
1fa761af
EB
121
122 /// whether the store_client::doCopy()-initiated STCB sequence is
123 /// currently in progress
3dd52a0b 124 bool store_copying;
3d0ac046 125 } flags;
62e76326 126
9a0a18de 127#if USE_DELAY_POOLS
b67e2c8c 128 DelayId delayId;
1fa761af
EB
129
130 /// The maximum number of bytes the Store client can read/copy next without
131 /// overflowing its buffer and without violating delay pool limits. Store
132 /// I/O is not rate-limited, but we assume that the same number of bytes may
133 /// be read from the Squid-to-server connection that may be rate-limited.
134 int bytesWanted() const;
135
b67e2c8c 136 void setDelayId(DelayId delay_id);
c8be6d7b 137#endif
62e76326 138
c8be6d7b 139 dlink_node node;
62e76326 140
528b2c61 141private:
122a6e3c
AR
142 bool moreToRead() const;
143 bool canReadFromMemory() const;
144 bool answeredOnce() const { return answers >= 1; }
145 bool sendingHttpHeaders() const;
146 int64_t nextHttpReadOffset() const;
f25d697f 147
528b2c61 148 void fileRead();
4e70dae3 149 void scheduleDiskRead();
122a6e3c 150 void readFromMemory();
4e70dae3 151 void scheduleRead();
0cdcf3d7 152 bool startSwapin();
122a6e3c
AR
153 void handleBodyFromDisk();
154 void maybeWriteFromDiskToMemory(const StoreIOBuffer &);
155
156 bool parseHttpHeadersFromDisk();
157 bool tryParsingHttpHeaders();
158 void skipHttpHeadersFromDisk();
62e76326 159
1fa761af
EB
160 void fail();
161 void callback(ssize_t);
162 void noteCopiedBytes(size_t);
1fa761af
EB
163 void noteNews();
164 void finishCallback();
165 static void FinishCallback(store_client *);
166
528b2c61 167 int type;
168 bool object_ok;
62e76326 169
122a6e3c
AR
170 /// \copydoc atEof()
171 bool atEof_;
172
1fa761af
EB
173 /// Storage and metadata associated with the current copy() request. Ought
174 /// to be ignored when not answering a copy() request.
3a5c8b44
AR
175 /// * copyInto.offset is the requested HTTP response body offset;
176 /// * copyInto.data is the client-owned, client-provided result buffer;
177 /// * copyInto.length is the size of the .data result buffer;
178 /// * copyInto.flags are unused by this class.
1fa761af
EB
179 StoreIOBuffer copyInto;
180
3a5c8b44
AR
181 // TODO: Convert to uint64_t after fixing mem_hdr::endOffset() and friends.
182 /// \copydoc discardableHttpEnd()
183 int64_t discardableHttpEnd_ = 0;
184
122a6e3c
AR
185 /// the total number of finishCallback() calls
186 uint64_t answers;
187
188 /// Accumulates raw bytes read from Store while answering the current copy()
189 /// request. Buffer contents depends on the source and parsing stage; it may
190 /// hold (parts of) swap metadata, HTTP response headers, and/or HTTP
191 /// response body bytes.
192 std::optional<Store::ParsingBuffer> parsingBuffer;
193
194 StoreIOBuffer lastDiskRead; ///< buffer used for the last storeRead() call
1fa761af 195
90703668 196 /* Until we finish stuffing code into store_client */
197
198public:
199
26ac0430 200 struct Callback {
6ec49cda 201 Callback() = default;
62e76326 202
203 Callback (STCB *, void *);
1fa761af
EB
204
205 /// Whether the copy() answer is needed/expected (by the client) and has
206 /// not been computed (by us). False during (asynchronous) answer
207 /// delivery to the STCB callback_handler.
90703668 208 bool pending() const;
1fa761af 209
6ec49cda
AR
210 STCB *callback_handler = nullptr; ///< where to deliver the answer
211 CallbackData cbData; ///< the first STCB callback parameter
f925268a 212 CodeContextPointer codeContext; ///< Store client context
1fa761af
EB
213
214 /// a scheduled asynchronous finishCallback() call (or nil)
215 AsyncCall::Pointer notifier;
2fadd50d 216 } _callback;
c8be6d7b 217};
218
122a6e3c
AR
219/// Asynchronously read HTTP response headers and/or body bytes from Store.
220///
221/// The requested zero-based HTTP body offset is specified via the
222/// StoreIOBuffer::offset field. The first call (for a given store_client
223/// object) must specify zero offset.
224///
225/// The requested HTTP body portion size is specified via the
226/// StoreIOBuffer::length field. The function may return fewer body bytes.
227///
228/// See STCB for result delivery details.
8a648e8d 229void storeClientCopy(store_client *, StoreEntry *, StoreIOBuffer, STCB *, void *);
122a6e3c 230
8a648e8d 231store_client* storeClientListAdd(StoreEntry * e, void *data);
8a648e8d
FC
232int storeUnregister(store_client * sc, StoreEntry * e, void *data);
233int storePendingNClients(const StoreEntry * e);
234int storeClientIsThisAClient(store_client * sc, void *someClient);
e87137f1 235
ff9d9458 236#endif /* SQUID_SRC_STORECLIENT_H */
f53969cc 237