SwapMetaOut.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2022 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#include "squid.h"
10#include "md5.h"
11#include "MemObject.h"
12#include "sbuf/Stream.h"
13#include "SquidMath.h"
14#include "Store.h"
15#include "store/SwapMeta.h"
16#include "store/SwapMetaOut.h"
17
18namespace Store {
19
21static void
22PackField(std::ostream &os, const SwapMetaType type, const size_t length, const void *value)
23{
24 // Outside of packing/unpacking code, we correctly use SwapMetaType for
25 // valid swap meta types, but we store these values as RawSwapMetaType.
26 const auto rawType = NaturalCast<RawSwapMetaType>(type);
27
28 if (length > SwapMetaFieldValueLengthMax)
29 throw TextException("swap meta field value too big to store", Here());
30
31 // Outside of packing/unpacking code, we correctly use size_t for value
32 // sizes, we still store these values using RawSwapMetaLength.
33 const auto rawLength = NaturalCast<RawSwapMetaLength>(length);
34
35 CheckSwapMetaSerialization(rawType, rawLength, value);
36
37 if (!os.write(&rawType, sizeof(rawType)) ||
38 !os.write(reinterpret_cast<const char*>(&rawLength), sizeof(rawLength)) ||
39 (length && !os.write(static_cast<const char*>(value), length)))
40 throw TextException("cannot pack a swap meta field", Here());
41}
42
44static void
45PackFields(const StoreEntry &entry, std::ostream &os)
46{
47 const auto &emem = entry.mem();
48 const auto objsize = emem.expectedReplySize();
49
50 SBuf url;
51 if (emem.request)
52 url = emem.request->storeId();
53 else
54 url = entry.url();
55
56 debugs(20, 3, entry << " URL: " << url);
57
59
61
62 // XXX: Performance regression, c_str() may reallocate.
63 // XXX: do TLV without the c_str() termination. check readers first though
64 PackField(os, STORE_META_URL, url.length() + 1U, url.c_str());
65
66 if (objsize >= 0)
67 PackField(os, STORE_META_OBJSIZE, sizeof(objsize), &objsize);
68
69 const auto &vary = emem.vary_headers;
70 if (!vary.isEmpty())
71 PackField(os, STORE_META_VARY_HEADERS, vary.length(), vary.rawContent());
72}
73
74} // namespace Store
75
77Store::PackSwapMeta(const StoreEntry &entry, size_t &totalLength)
78{
79 SBufStream os;
80 PackFields(entry, os);
81 const auto metas = os.buf();
82
83 // TODO: Optimize this allocation away by returning (and swapping out) SBuf.
84 const auto bufSize = NaturalSum<size_t>(sizeof(SwapMetaMagic), sizeof(RawSwapMetaPrefixLength), metas.length()).value();
85 AllocedBuf buf(xmalloc(bufSize));
86 const auto bufStart = static_cast<char*>(buf.get());
87
88 auto pos = bufStart; // buf writing position
89
90 *pos = SwapMetaMagic;
91 pos += sizeof(SwapMetaMagic);
92
93 const auto metaSize = NaturalCast<RawSwapMetaLength>(bufSize);
94 memcpy(pos, &metaSize, sizeof(metaSize));
95 pos += sizeof(metaSize);
96
97 Assure(pos + metas.length() == bufStart + bufSize); // paranoid
98 memcpy(pos, metas.rawContent(), metas.length());
99 pos += metas.length();
100
101 totalLength = bufSize;
102 return buf;
103}
104
#define Assure(condition)
Definition: Assure.h:35
#define Here()
source code location of the caller
Definition: Here.h:15
std::unique_ptr< void, HardFun< void, const void *, &xfree_cpp > > AllocedBuf
memory allocated by xmalloc() or xcalloc(), to be freed by xfree()
Definition: SwapMetaOut.h:24
int64_t expectedReplySize() const
Definition: MemObject.cc:238
SBuf buf()
bytes written so far
Definition: Stream.h:41
Definition: SBuf.h:94
const char * c_str()
Definition: SBuf.cc:516
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:415
MemObject & mem()
Definition: Store.h:51
const char * url() const
Definition: store.cc:1533
time_t timestamp
Definition: Store.h:224
an std::runtime_error with thrower location info
Definition: TextException.h:21
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
int type
Definition: errorpage.cc:152
#define SQUID_MD5_DIGEST_LENGTH
Definition: md5.h:66
const size_t SwapMetaFieldValueLengthMax
Definition: SwapMeta.h:107
static void PackField(std::ostream &os, const SwapMetaType type, const size_t length, const void *value)
writes a single swap meta field to the given stream
Definition: SwapMetaOut.cc:22
SwapMetaType
Definition: SwapMeta.h:52
@ STORE_META_URL
Definition: SwapMeta.h:65
@ STORE_META_VARY_HEADERS
Stores Vary request headers.
Definition: SwapMeta.h:83
@ STORE_META_OBJSIZE
Definition: SwapMeta.h:90
@ STORE_META_KEY_MD5
Definition: SwapMeta.h:61
@ STORE_META_STD_LFS
Definition: SwapMeta.h:87
void CheckSwapMetaSerialization(RawSwapMetaType, RawSwapMetaLength, const void *)
Definition: SwapMeta.cc:13
AllocedBuf PackSwapMeta(const StoreEntry &, size_t &size)
Definition: SwapMetaOut.cc:77
const char SwapMetaMagic
the start of the swap meta section
Definition: SwapMeta.h:113
static void PackFields(const StoreEntry &entry, std::ostream &os)
writes all swap meta fields of the given Store entry to the given stream
Definition: SwapMetaOut.cc:45
const auto STORE_HDR_METASIZE
Definition: SwapMeta.h:228
int RawSwapMetaPrefixLength
Definition: SwapMeta.h:119
#define xmalloc

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors