1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
--[[
Copyright (c) 2016, Andrew Lewis <nerf@judo.za.org>
Copyright (c) 2016, Vsevolod Stakhov <vsevolod@highsecure.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
-- A plugin that pushes metadata (or whole messages) to external services
local rspamd_http
local rspamd_logger = require "rspamd_logger"
local settings = {
format = function(task)
return task:get_content()
end,
mime_type = 'text/plain',
}
local opts = rspamd_config:get_all_opt('metadata_exporter')
if not opts then return end
local redis_params
local channel = opts['channel']
local url = opts['url']
if not (url or channel) then
rspamd_logger.errx('No backends configured')
end
if channel then
redis_params = rspamd_parse_redis_server('metadata_exporter')
if not redis_params then
rspamd_logger.errx(rspamd_config, 'No redis servers are specified')
return
end
end
if url then
rspamd_http = require "rspamd_http"
end
if opts['select'] then
settings.select = assert(load(opts['select']))()
end
if opts['format'] then
settings.format = assert(load(opts['format']))()
end
if opts['mime_type'] then
settings['mime_type'] = opts['mime_type']
end
local function metadata_exporter(task)
local _,ret,upstream
local function http_callback(err, code)
if err then
rspamd_logger.errx(task, 'got error %s in http callback', err)
end
if code ~= 200 then
rspamd_logger.errx(task, 'got unexpected http status: %s', code)
end
end
local function redis_set_cb(err)
if err then
rspamd_logger.errx(task, 'got error %s when publishing record on server %s',
err, upstream:get_addr())
end
end
if settings.select then
if not settings.select(task) then return end
rspamd_logger.debugx(task, 'Message selected for processing')
end
local data = settings.format(task)
if not data then
rspamd_logger.debugx(task, 'Format returned non-truthy value: %1', data)
return
end
if channel then
ret,_,upstream = rspamd_redis_make_request(task,
redis_params, -- connect params
nil, -- hash key
true, -- is write
redis_set_cb, --callback
'PUBLISH', -- command
{channel, data} -- arguments
)
if not ret then
rspamd_logger.errx(task, 'error connecting to redis')
end
end
if url then
rspamd_http.request({
task=task,
url=url,
body=data,
callback=http_callback,
mime_type=settings['mime_type'],
})
end
end
rspamd_config:register_symbol({
name = 'EXPORT_METADATA',
type = 'postfilter',
callback = metadata_exporter,
priority = 10
})
|