]> git.ipfire.org Git - thirdparty/squid.git/blame - src/Store.h
Bug 3870: assertion failed: String.cc: 'len_ + len <65536' in ESI::CustomParser
[thirdparty/squid.git] / src / Store.h
CommitLineData
e6ccf245 1/*
ef57eb7b 2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
e6ccf245 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.
e6ccf245 7 */
bbc27441 8
e6ccf245 9#ifndef SQUID_STORE_H
10#define SQUID_STORE_H
11
0f33a01d 12#include "base/Packable.h"
8bf217bd 13#include "base/RefCount.h"
3e4bebf8 14#include "comm/forward.h"
582c2af2 15#include "CommRead.h"
c6983ec7 16#include "hash.h"
f35c0145 17#include "http/forward.h"
c24f7fb6 18#include "http/RequestMethod.h"
43ca19e0 19#include "HttpReply.h"
04ebce55 20#include "MemObject.h"
582c2af2 21#include "Range.h"
aa839030 22#include "RemovalPolicy.h"
2745fea5
AR
23#include "store/Controller.h"
24#include "store/forward.h"
e1ba42a4 25#include "store_key_md5.h"
582c2af2 26#include "StoreIOBuffer.h"
93bc1434 27#include "StoreStats.h"
528b2c61 28
f41735ea 29#if USE_SQUID_ESI
f99c2cfe 30#include "esi/Element.h"
43ae1d95 31#endif
32
27e059d4 33#include <ostream>
27e059d4 34
65517dc8 35class AsyncCall;
582c2af2 36class HttpRequest;
71b673d4 37class RequestFlags;
c8f4eac4 38
8822ebee
AR
39extern StoreIoStats store_io_stats;
40
0f33a01d 41class StoreEntry : public hash_link, public Packable
62e76326 42{
91574db5 43 MEMPROXY_CLASS(StoreEntry);
62e76326 44
332dafa2 45public:
a46d2c0e 46 static DeferredRead::DeferrableRead DeferReader;
47 bool checkDeferRead(int fd) const;
62e76326 48
528b2c61 49 virtual const char *getMD5Text() const;
c8f4eac4 50 StoreEntry();
6d8d05b5 51 virtual ~StoreEntry();
43ae1d95 52
528b2c61 53 virtual HttpReply const *getReply() const;
54 virtual void write (StoreIOBuffer);
04ebce55
FC
55
56 /** Check if the Store entry is emtpty
57 * \retval true Store contains 0 bytes of data.
58 * \retval false Store contains 1 or more bytes of data.
59 * \retval false Store contains negative content !!!!!!
60 */
61 virtual bool isEmpty() const {
62 assert (mem_obj);
63 return mem_obj->endOffset() == 0;
64 }
aa18a4ca 65 virtual bool isAccepting() const;
384a7590 66 virtual size_t bytesWanted(Range<size_t> const aRange, bool ignoreDelayPool = false) const;
7224ca5a
AR
67 /// flags [truncated or too big] entry with ENTRY_BAD_LENGTH and releases it
68 void lengthWentBad(const char *reason);
528b2c61 69 virtual void complete();
70 virtual store_client_t storeClientType() const;
71 virtual char const *getSerialisedMetaData();
eacfca83
AR
72 /// Store a prepared error response. MemObject locks the reply object.
73 void storeErrorResponse(HttpReply *reply);
3756e5c0
AR
74 void replaceHttpReply(HttpReply *, bool andStartWriting = true);
75 void startWriting(); ///< pack and write reply headers and, maybe, body
5b55f1f1
CT
76 /// whether we may start writing to disk (now or in the future)
77 virtual bool mayStartSwapOut();
78 virtual void trimMemory(const bool preserveSwappable);
0cdcf3d7 79
2da4bfe6 80 // called when a decision to cache in memory has been made
0cdcf3d7
AR
81 void memOutDecision(const bool willCacheInRam);
82 // called when a decision to cache on disk has been made
83 void swapOutDecision(const MemObject::SwapOut::Decision &decision);
84
bfb55b6f 85 void abort();
5ed72359 86 void makePublic();
87 void makePrivate();
d88e3c49 88 void setPublicKey();
89 void setPrivateKey();
90 void expireNow();
91 void releaseRequest();
92 void negativeCache();
f53969cc 93 void cacheNegatively(); /** \todo argh, why both? */
d88e3c49 94 void invokeHandlers();
95 void purgeMem();
9487bae9 96 void cacheInMemory(); ///< start or continue storing in memory cache
c07cbbf4 97 void swapOut();
5b55f1f1
CT
98 /// whether we are in the process of writing this entry to disk
99 bool swappingOut() const { return swap_status == SWAPOUT_WRITING; }
aa1a691e 100 void swapOutFileClose(int how);
3900307b 101 const char *url() const;
7015a149
AR
102 /// Satisfies cachability requirements shared among disk and RAM caches.
103 /// Encapsulates common checks of mayStartSwapOut() and memoryCachable().
104 /// TODO: Rename and make private so only those two methods can call this.
105 bool checkCachable();
3900307b 106 int checkNegativeHit() const;
107 int locked() const;
108 int validToSend() const;
97754f5a 109 bool memoryCachable(); ///< checkCachable() and can be cached in memory
4475555f 110
c877c0bc
AR
111 /// if needed, initialize mem_obj member w/o URI-related information
112 MemObject *makeMemObject();
113
114 /// initialize mem_obj member (if needed) and supply URI-related info
115 void createMemObject(const char *storeId, const char *logUri, const HttpRequestMethod &aMethod);
4475555f 116
3900307b 117 void dump(int debug_lvl) const;
118 void hashDelete();
119 void hashInsert(const cache_key *);
120 void registerAbort(STABH * cb, void *);
121 void reset();
122 void setMemStatus(mem_status_t);
123 void timestampsSet();
124 void unregisterAbort();
125 void destroyMemObject();
126 int checkTooSmall();
528b2c61 127
3e4bebf8 128 void delayAwareRead(const Comm::ConnectionPointer &conn, char *buf, int len, AsyncCall::Pointer callback);
43ae1d95 129
a46d2c0e 130 void setNoDelay (bool const);
190154cf 131 bool modifiedSince(HttpRequest * request) const;
79c8035e
AR
132 /// has ETag matching at least one of the If-Match etags
133 bool hasIfMatchEtag(const HttpRequest &request) const;
134 /// has ETag matching at least one of the If-None-Match etags
135 bool hasIfNoneMatchEtag(const HttpRequest &request) const;
46017fdd
CT
136 /// whether this entry has an ETag; if yes, puts ETag value into parameter
137 bool hasEtag(ETag &etag) const;
63be0a78 138
2745fea5
AR
139 /// the disk this entry is [being] cached on; asserts for entries w/o a disk
140 Store::Disk &disk() const;
a46d2c0e 141
e6ccf245 142 MemObject *mem_obj;
143 RemovalPolicyNode repl;
144 /* START OF ON-DISK STORE_META_STD TLV field */
145 time_t timestamp;
146 time_t lastref;
147 time_t expires;
148 time_t lastmod;
47f6e231 149 uint64_t swap_file_sz;
f45dd259
AJ
150 uint16_t refcount;
151 uint16_t flags;
e6ccf245 152 /* END OF ON-DISK STORE_META_STD */
62e76326 153
051dedf9
AR
154 /// unique ID inside a cache_dir for swapped out entries; -1 for others
155 sfileno swap_filen:25; // keep in sync with SwapFilenMax
d1398b75
HN
156
157 sdirno swap_dirn:7;
62e76326 158
d1398b75 159 mem_status_t mem_status:3;
62e76326 160
d1398b75 161 ping_status_t ping_status:3;
62e76326 162
d1398b75 163 store_status_t store_status:3;
62e76326 164
d1398b75 165 swap_status_t swap_status:3;
62e76326 166
e6ccf245 167public:
168 static size_t inUseCount();
60745f24 169 static void getPublicByRequestMethod(StoreClient * aClient, HttpRequest * request, const HttpRequestMethod& method);
190154cf 170 static void getPublicByRequest(StoreClient * aClient, HttpRequest * request);
60745f24 171 static void getPublic(StoreClient * aClient, const char *uri, const HttpRequestMethod& method);
528b2c61 172
26ac0430 173 virtual bool isNull() {
62e76326 174 return false;
63be0a78 175 };
62e76326 176
43ae1d95 177 void setReleaseFlag();
f41735ea 178#if USE_SQUID_ESI
43ae1d95 179
180 ESIElement::Pointer cachedESITree;
181#endif
47f6e231 182 virtual int64_t objectLen() const;
183 virtual int64_t contentLen() const;
c21ad0f5 184
18994992 185 /// claim shared ownership of this entry (for use in a given context)
acc5dc4c 186 /// matching lock() and unlock() contexts eases leak triage but is optional
18994992 187 void lock(const char *context);
1bfe9ade 188
18994992
AR
189 /// disclaim shared ownership; may remove entry from store and delete it
190 /// returns remaning lock level (zero for unlocked and possibly gone entry)
acc5dc4c 191 int unlock(const char *context);
1bfe9ade
AR
192
193 /// returns a local concurrent use counter, for debugging
194 int locks() const { return static_cast<int>(lock_count); }
195
18994992
AR
196 /// update last reference timestamp and related Store metadata
197 void touch();
198
5f33b71d 199 virtual void release();
62e76326 200
0ad2b63b
CT
201#if USE_ADAPTATION
202 /// call back producer when more buffer space is available
203 void deferProducer(const AsyncCall::Pointer &producer);
204 /// calls back producer registered with deferProducer
205 void kickProducer();
206#endif
207
0f33a01d
AJ
208 /* Packable API */
209 virtual void append(char const *, int);
210 virtual void vappendf(const char *, va_list);
7e10ac87
AJ
211 virtual void buffer();
212 virtual void flush();
0f33a01d 213
0cdcf3d7
AR
214protected:
215 void transientsAbandonmentCheck();
216
e6ccf245 217private:
2be042f6
AR
218 bool checkTooBig() const;
219
04eb0689 220 static MemAllocator *pool;
528b2c61 221
f53969cc 222 unsigned short lock_count; /* Assume < 65536! */
1bfe9ade 223
0ad2b63b
CT
224#if USE_ADAPTATION
225 /// producer callback registered with deferProducer
226 AsyncCall::Pointer deferredProducer;
227#endif
228
528b2c61 229 bool validLength() const;
79c8035e 230 bool hasOneOfEtags(const String &reqETags, const bool allowWeakMatch) const;
e6ccf245 231};
232
2c4cd1ad
AR
233std::ostream &operator <<(std::ostream &os, const StoreEntry &e);
234
63be0a78 235/// \ingroup StoreAPI
3b13a8fd 236class NullStoreEntry:public StoreEntry
e6ccf245 237{
62e76326 238
e6ccf245 239public:
240 static NullStoreEntry *getInstance();
26ac0430 241 bool isNull() {
62e76326 242 return true;
e6ccf245 243 }
62e76326 244
332dafa2 245 const char *getMD5Text() const;
04ebce55 246 HttpReply const *getReply() const { return NULL; }
26ac0430 247 void write (StoreIOBuffer) {}
62e76326 248
528b2c61 249 bool isEmpty () const {return true;}
62e76326 250
ced8def3 251 virtual size_t bytesWanted(Range<size_t> const aRange, bool) const { return aRange.end; }
62e76326 252
e6ccf245 253 void operator delete(void *address);
26ac0430 254 void complete() {}
62e76326 255
256private:
26ac0430 257 store_client_t storeClientType() const {return STORE_MEM_CLIENT;}
62e76326 258
528b2c61 259 char const *getSerialisedMetaData();
97754f5a 260 virtual bool mayStartSwapOut() { return false; }
62e76326 261
ced8def3 262 void trimMemory(const bool) {}
528b2c61 263
e6ccf245 264 static NullStoreEntry _instance;
265};
266
63be0a78 267/// \ingroup StoreAPI
c8f4eac4 268typedef void (*STOREGETCLIENT) (StoreEntry *, void *cbdata);
269
2745fea5 270namespace Store {
7d84d4ca
SM
271void Stats(StoreEntry *output);
272void Maintain(void *unused);
c8f4eac4 273};
274
63be0a78 275/// \ingroup StoreAPI
71b673d4 276size_t storeEntryInUse();
63be0a78 277
278/// \ingroup StoreAPI
71b673d4 279const char *storeEntryFlags(const StoreEntry *);
63be0a78 280
281/// \ingroup StoreAPI
71b673d4 282void storeEntryReplaceObject(StoreEntry *, HttpReply *);
e6ccf245 283
63be0a78 284/// \ingroup StoreAPI
71b673d4 285StoreEntry *storeGetPublic(const char *uri, const HttpRequestMethod& method);
63be0a78 286
287/// \ingroup StoreAPI
71b673d4 288StoreEntry *storeGetPublicByRequest(HttpRequest * request);
63be0a78 289
290/// \ingroup StoreAPI
71b673d4 291StoreEntry *storeGetPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method);
63be0a78 292
293/// \ingroup StoreAPI
1bfe9ade 294/// Like storeCreatePureEntry(), but also locks the entry and sets entry key.
71b673d4 295StoreEntry *storeCreateEntry(const char *, const char *, const RequestFlags &, const HttpRequestMethod&);
63be0a78 296
1bfe9ade
AR
297/// \ingroup StoreAPI
298/// Creates a new StoreEntry with mem_obj and sets initial flags/states.
299StoreEntry *storeCreatePureEntry(const char *storeId, const char *logUrl, const RequestFlags &, const HttpRequestMethod&);
300
63be0a78 301/// \ingroup StoreAPI
71b673d4 302void storeInit(void);
63be0a78 303
63be0a78 304/// \ingroup StoreAPI
71b673d4 305void storeConfigure(void);
63be0a78 306
307/// \ingroup StoreAPI
71b673d4 308void storeFreeMemory(void);
63be0a78 309
310/// \ingroup StoreAPI
71b673d4 311int expiresMoreThan(time_t, time_t);
63be0a78 312
63be0a78 313/// \ingroup StoreAPI
71b673d4 314void storeAppendPrintf(StoreEntry *, const char *,...) PRINTF_FORMAT_ARG2;
63be0a78 315
316/// \ingroup StoreAPI
71b673d4 317void storeAppendVPrintf(StoreEntry *, const char *, va_list ap);
63be0a78 318
319/// \ingroup StoreAPI
71b673d4 320int storeTooManyDiskFilesOpen(void);
63be0a78 321
322/// \ingroup StoreAPI
71b673d4 323void storeHeapPositionUpdate(StoreEntry *, SwapDir *);
63be0a78 324
325/// \ingroup StoreAPI
71b673d4 326void storeSwapFileNumberSet(StoreEntry * e, sfileno filn);
63be0a78 327
328/// \ingroup StoreAPI
71b673d4 329void storeFsInit(void);
63be0a78 330
331/// \ingroup StoreAPI
71b673d4 332void storeFsDone(void);
63be0a78 333
334/// \ingroup StoreAPI
71b673d4 335void storeReplAdd(const char *, REMOVALPOLICYCREATE *);
63be0a78 336
337/// \ingroup StoreAPI
c8f4eac4 338extern FREE destroyStoreEntry;
e6ccf245 339
6d3c2758 340/// \ingroup StoreAPI
71b673d4 341void storeGetMemSpace(int size);
6d3c2758 342
e6ccf245 343#endif /* SQUID_STORE_H */
f53969cc 344