Skip to content

Commit 34809d8

Browse files
committed
Add expirevar support for lmdb
1 parent 118e1b3 commit 34809d8

File tree

6 files changed

+363
-24
lines changed

6 files changed

+363
-24
lines changed

src/collection/backend/collection_data.cc

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,105 @@ void CollectionData::setExpiry(int32_t seconds_until_expiry) {
3535
m_hasExpiryTime = true;
3636
}
3737

38+
std::string CollectionData::getSerialized() const {
39+
std::string serialized;
40+
if (hasValue()) {
41+
serialized.reserve(30 + 10 + getValue().size());
42+
} else {
43+
serialized.reserve(16+10);
44+
}
45+
46+
serialized.assign("{");
47+
48+
if (hasExpiry()) {
49+
serialized.append("\"__expire_\":");
50+
uint64_t expiryEpochSeconds = std::chrono::duration_cast<std::chrono::seconds>(m_expiryTime.time_since_epoch()).count();
51+
serialized.append(std::to_string(expiryEpochSeconds));
52+
if (hasValue()) {
53+
serialized.append(",");
54+
}
55+
}
56+
if (hasValue()) {
57+
serialized.append("\"__value_\":\"");
58+
serialized.append(getValue());
59+
serialized.append("\"");
60+
}
61+
62+
serialized.append("}");
63+
64+
return serialized;
65+
}
66+
67+
void CollectionData::setFromSerialized(const char* serializedData, size_t length) {
68+
const static std::string expiryPrefix("\"__expire_\":");
69+
const static std::string valuePrefix("\"__value_\":\"");
70+
m_hasValue = false;
71+
m_hasExpiryTime = false;
72+
73+
std::string serializedString(serializedData, length);
74+
if ((serializedString.find("{") == 0) && (serializedString.substr(serializedString.length()-1) == "}")) {
75+
size_t currentPos = 1;
76+
uint64_t expiryEpochSeconds = 0;
77+
bool invalidSerializedFormat = false;
78+
bool doneParsing = false;
79+
80+
// Extract the expiry time, if it exists
81+
if (serializedString.find(expiryPrefix, currentPos) == currentPos) {
82+
currentPos += expiryPrefix.length();
83+
std::string expiryDigits = serializedString.substr(currentPos, 10);
84+
if (expiryDigits.find_first_not_of("0123456789") == std::string::npos) {
85+
expiryEpochSeconds = strtoll(expiryDigits.c_str(), NULL, 10);
86+
} else {
87+
invalidSerializedFormat = true;
88+
}
89+
currentPos += 10;
90+
}
91+
92+
if ((!invalidSerializedFormat) && (expiryEpochSeconds > 0)) {
93+
if (serializedString.find(",", currentPos) == currentPos) {
94+
currentPos++;
95+
} else if (currentPos == serializedString.length()-1) {
96+
doneParsing = true;
97+
} else {
98+
invalidSerializedFormat = true;
99+
}
100+
}
101+
102+
if ((!invalidSerializedFormat) && (!doneParsing)) {
103+
// Extract the value
104+
if ((serializedString.find(valuePrefix, currentPos) == currentPos)) {
105+
currentPos += valuePrefix.length();
106+
size_t expectedCloseQuotePos = serializedString.length() - 2;
107+
if ((serializedString.substr(expectedCloseQuotePos, 1) == "\"") && (expectedCloseQuotePos >= currentPos)) {
108+
m_value = serializedString.substr(currentPos);
109+
m_value.resize(m_value.length()-2);
110+
m_hasValue = true;
111+
} else {
112+
invalidSerializedFormat = true;
113+
}
114+
} else {
115+
invalidSerializedFormat = true;
116+
}
117+
}
118+
119+
// Set the object's expiry time, if we found one
120+
if ((!invalidSerializedFormat) && (expiryEpochSeconds > 0)) {
121+
std::chrono::seconds expiryDuration(expiryEpochSeconds);
122+
std::chrono::system_clock::time_point expiryTimePoint(expiryDuration);
123+
m_expiryTime = expiryTimePoint;
124+
m_hasExpiryTime = true;
125+
}
126+
if (!invalidSerializedFormat) {
127+
return;
128+
}
129+
}
130+
131+
// this is the residual case; the entire string is a simple value (not JSON-ish encoded)
132+
// the foreseen case here is lmdb content from prior to the serialization support
133+
m_value.assign(serializedData, length);
134+
m_hasValue = true;
135+
return;
136+
}
38137

39138
} // namespace backend
40139
} // namespace collection

src/collection/backend/collection_data.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,10 @@
1616

1717
#ifdef __cplusplus
1818
#include <string>
19-
#include <memory>
2019
#include <chrono>
2120
#endif
2221

2322

24-
#include "modsecurity/collection/collection.h"
25-
2623
#ifndef SRC_COLLECTION_DATA_H_
2724
#define SRC_COLLECTION_DATA_H_
2825

@@ -53,6 +50,9 @@ class CollectionData {
5350
bool hasExpiry() const { return m_hasExpiryTime;}
5451
bool isExpired() const;
5552

53+
std::string getSerialized() const;
54+
void setFromSerialized(const char* serializedData, size_t length);
55+
5656
private:
5757
bool m_hasValue;
5858
bool m_hasExpiryTime;

0 commit comments

Comments
 (0)