aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstat/backends
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2022-06-26 14:18:03 +0100
committerVsevolod Stakhov <vsevolod@rspamd.com>2022-06-26 14:18:03 +0100
commite872e68c0de7443592bc50cac6f484a1ce41a038 (patch)
treef96257ad4aeda093d25fa8375d530eb6e0989881 /src/libstat/backends
parent3c9e8f048b8317f02839b3069fa3420bf528222e (diff)
downloadrspamd-e872e68c0de7443592bc50cac6f484a1ce41a038.tar.gz
rspamd-e872e68c0de7443592bc50cac6f484a1ce41a038.zip
[Minor] Add a helper to serialize stats tokens to a messagepack request
Diffstat (limited to 'src/libstat/backends')
-rw-r--r--src/libstat/backends/http_backend.cxx68
1 files changed, 64 insertions, 4 deletions
diff --git a/src/libstat/backends/http_backend.cxx b/src/libstat/backends/http_backend.cxx
index eaf2b1804..3f4f1abd0 100644
--- a/src/libstat/backends/http_backend.cxx
+++ b/src/libstat/backends/http_backend.cxx
@@ -84,6 +84,11 @@ public:
auto notice_statfile(int id, const struct rspamd_statfile_config *st) -> void {
seen_statfiles[id] = st;
}
+
+ auto process_tokens(struct rspamd_task* task,
+ GPtrArray* tokens,
+ gint id,
+ bool learn) -> bool;
private:
http_backends_collection *all_backends;
robin_hood::unordered_flat_map<int, const struct rspamd_statfile_config *> seen_statfiles;
@@ -99,6 +104,41 @@ private:
}
};
+/*
+ * Efficient way to make a messagepack payload from stat tokens,
+ * avoiding any intermediate libraries, as we would send many tokens
+ * all together
+ */
+static auto
+stat_tokens_to_msgpack(GPtrArray *tokens) -> std::vector<std::uint8_t>
+{
+ std::vector<std::uint8_t> ret;
+ rspamd_token_t *cur;
+ int i;
+
+ /*
+ * We define array, it's size and N elements each is uint64_t
+ * Layout:
+ * 0xdd - array marker
+ * [4 bytes be] - size of the array
+ * [ 0xcf + <8 bytes BE integer>] * N - array elements
+ */
+ ret.resize(tokens->len * (sizeof(std::uint64_t) + 1) + 5);
+ ret.push_back('\xdd');
+ std::uint32_t ulen = GUINT32_TO_BE(tokens->len);
+ std::copy((const std::uint8_t *)&ulen,
+ ((const std::uint8_t *)&ulen) + sizeof(ulen), std::back_inserter(ret));
+
+ PTR_ARRAY_FOREACH(tokens, i, cur) {
+ ret.push_back('\xcf');
+ std::uint64_t val = GUINT64_TO_BE(cur->data);
+ std::copy((const std::uint8_t *)&val,
+ ((const std::uint8_t *)&val) + sizeof(val), std::back_inserter(ret));
+ }
+
+ return ret;
+}
+
auto http_backend_runtime::create(struct rspamd_task *task, bool is_learn) -> http_backend_runtime *
{
/* Alloc type provide proper size and alignment */
@@ -110,6 +150,28 @@ auto http_backend_runtime::create(struct rspamd_task *task, bool is_learn) -> ht
}
auto
+http_backend_runtime::process_tokens(struct rspamd_task *task, GPtrArray *tokens, gint id, bool learn) -> bool
+{
+ if (!learn) {
+ if (id == seen_statfiles.size() - 1) {
+ /* Emit http request on the last statfile */
+ }
+ }
+ else {
+ /* On learn we need to learn all statfiles that we were requested to learn */
+ if (seen_statfiles.empty()) {
+ /* Request has been already set, or nothing to learn */
+ return true;
+ }
+ else {
+ seen_statfiles.clear();
+ }
+ }
+
+ return true;
+}
+
+auto
http_backends_collection::add_backend(struct rspamd_stat_ctx *ctx,
struct rspamd_config *cfg,
struct rspamd_statfile *st) -> bool
@@ -284,8 +346,7 @@ rspamd_http_process_tokens(struct rspamd_task* task,
auto real_runtime = (rspamd::stat::http::http_backend_runtime *)runtime;
if (real_runtime) {
- /* TODO */
- return true;
+ return real_runtime->process_tokens(task, tokens, id, false);
}
@@ -310,8 +371,7 @@ rspamd_http_learn_tokens(struct rspamd_task* task,
auto real_runtime = (rspamd::stat::http::http_backend_runtime *)runtime;
if (real_runtime) {
- /* TODO */
- return true;
+ return real_runtime->process_tokens(task, tokens, id, true);
}