summaryrefslogtreecommitdiffstats
path: root/test/functional/lua/tcp.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/lua/tcp.lua')
-rw-r--r--test/functional/lua/tcp.lua279
1 files changed, 279 insertions, 0 deletions
diff --git a/test/functional/lua/tcp.lua b/test/functional/lua/tcp.lua
new file mode 100644
index 0000000..e5c765b
--- /dev/null
+++ b/test/functional/lua/tcp.lua
@@ -0,0 +1,279 @@
+--[[[
+-- Just a test for TCP API
+--]]
+
+local rspamd_tcp = require "rspamd_tcp"
+local logger = require "rspamd_logger"
+local tcp_sync = require "lua_tcp_sync"
+
+-- [[ old fashioned callback api ]]
+local function http_simple_tcp_async_symbol(task)
+ logger.errx(task, 'http_tcp_symbol: begin')
+ local function http_get_cb(err, data, conn)
+ logger.errx(task, 'http_get_cb: got reply: %s, error: %s, conn: %s', data, err, conn)
+ task:insert_result('HTTP_ASYNC_RESPONSE_2', 1.0, data)
+ end
+ local function http_read_post_cb(err, conn)
+ logger.errx(task, 'http_read_post_cb: write done: error: %s, conn: %s', err, conn)
+ conn:add_read(http_get_cb)
+ end
+ local function http_read_cb(err, data, conn)
+ logger.errx(task, 'http_read_cb: got reply: %s, error: %s, conn: %s', data, err, conn)
+ conn:add_write(http_read_post_cb, "POST /request2 HTTP/1.1\r\n\r\n")
+ task:insert_result('HTTP_ASYNC_RESPONSE', 1.0, data or err)
+ end
+ rspamd_tcp:request({
+ task = task,
+ callback = http_read_cb,
+ host = '127.0.0.1',
+ data = {'GET /request HTTP/1.1\r\nConnection: keep-alive\r\n\r\n'},
+ read = true,
+ port = 18080,
+ })
+end
+
+local function http_simple_tcp_ssl_symbol(task)
+ logger.errx(task, 'ssl_tcp_symbol: begin')
+ local function ssl_get_cb(err, data, conn)
+ logger.errx(task, 'ssl_get_cb: got reply: %s, error: %s, conn: %s', data, err, conn)
+ task:insert_result('TCP_SSL_RESPONSE_2', 1.0, tostring(data):gsub('%s', ''))
+ end
+ local function ssl_read_post_cb(err, conn)
+ logger.errx(task, 'ssl_read_post_cb: write done: error: %s, conn: %s', err, conn)
+ conn:add_read(ssl_get_cb)
+ end
+ local function ssl_read_cb(err, data, conn)
+ logger.errx(task, 'ssl_read_cb: got reply: %s, error: %s, conn: %s', data, err, conn)
+ conn:add_write(ssl_read_post_cb, "test2\n")
+ task:insert_result('TCP_SSL_RESPONSE', 1.0, tostring(data):gsub('%s', ''))
+ end
+ rspamd_tcp:request({
+ task = task,
+ callback = ssl_read_cb,
+ host = '127.0.0.1',
+ data = {'test\n'},
+ read = true,
+ ssl = true,
+ ssl_noverify = true,
+ port = 18081,
+ })
+end
+
+local function http_large_tcp_ssl_symbol(task)
+ local data = {}
+
+ local function ssl_get_cb(err, rep, conn)
+ logger.errx(task, 'ssl_get_cb: got reply: %s, error: %s, conn: %s', rep, err, conn)
+ task:insert_result('TCP_SSL_LARGE_2', 1.0)
+ end
+ local function ssl_read_post_cb(err, conn)
+ logger.errx(task, 'ssl_large_read_post_cb: write done: error: %s, conn: %s', err, conn)
+ conn:add_read(ssl_get_cb)
+ end
+ local function ssl_read_cb(err, rep, conn)
+ logger.errx(task, 'ssl_large_read_cb: got reply: %s, error: %s, conn: %s', rep, err, conn)
+ conn:add_write(ssl_read_post_cb, 'foo\n')
+ task:insert_result('TCP_SSL_LARGE', 1.0)
+ end
+
+ if task:get_queue_id() == 'SSL Large TCP request' then
+ logger.errx(task, 'ssl_large_tcp_symbol: begin')
+ for i = 1,2 do
+ local st = {}
+ for j=1,300000 do
+ st[j] = 't'
+ end
+ data[i] = table.concat(st)
+ end
+ data[#data + 1] = '\n'
+
+ rspamd_tcp:request({
+ task = task,
+ callback = ssl_read_cb,
+ host = '127.0.0.1',
+ data = data,
+ read = true,
+ ssl = true,
+ stop_pattern = '\n',
+ ssl_noverify = true,
+ port = 18081,
+ timeout = 20,
+ })
+ else
+ logger.errx(task, 'ssl_large_tcp_symbol: skip')
+ end
+end
+
+local function http_simple_tcp_symbol(task)
+ logger.errx(task, 'connect_sync, before')
+
+ local err
+ local is_ok, connection = tcp_sync.connect {
+ task = task,
+ host = '127.0.0.1',
+ timeout = 20,
+ port = 18080,
+ }
+
+ if not is_ok then
+ task:insert_result('HTTP_SYNC_WRITE_ERROR', 1.0, connection)
+ logger.errx(task, 'write error: %1', connection)
+ end
+
+ logger.errx(task, 'connect_sync %1, %2', is_ok, tostring(connection))
+
+ is_ok, err = connection:write('GET /request HTTP/1.1\r\nConnection: keep-alive\r\n\r\n')
+
+ logger.errx(task, 'write %1, %2', is_ok, err)
+ if not is_ok then
+ task:insert_result('HTTP_SYNC_WRITE_ERROR', 1.0, err)
+ logger.errx(task, 'write error: %1', err)
+ end
+
+ local data
+ local got_content = ''
+ repeat
+ is_ok, data = connection:read_once();
+ logger.errx(task, 'read_once: is_ok: %1, data: %2', is_ok, data)
+ if not is_ok then
+ task:insert_result('HTTP_SYNC_ERROR', 1.0, data)
+ return
+ else
+ got_content = got_content .. data
+ end
+ if got_content:find('hello') then
+ -- dummy_http.py responds with either hello world or hello post
+ break
+ end
+ until false
+
+ task:insert_result('HTTP_SYNC_RESPONSE', 1.0, got_content)
+
+ is_ok, err = connection:write("POST /request HTTP/1.1\r\n\r\n")
+ logger.errx(task, 'write[2] %1, %2', is_ok, err)
+
+ got_content = ''
+ repeat
+ is_ok, data = connection:read_once();
+ logger.errx(task, 'read_once[2]: is_ok %1, data: %2', is_ok, data)
+ if not is_ok then
+ task:insert_result('HTTP_SYNC_ERROR_2', 1.0, data)
+ return
+ else
+ got_content = got_content .. data
+ end
+ if got_content:find('hello') then
+ break
+ end
+ until false
+
+ task:insert_result('HTTP_SYNC_RESPONSE_2', 1.0, data)
+
+ connection:close()
+end
+
+local function http_tcp_symbol(task)
+ local url = tostring(task:get_request_header('url'))
+ local method = tostring(task:get_request_header('method'))
+
+ if url == 'nil' then
+ return
+ end
+
+ local err
+ local is_ok, connection = tcp_sync.connect {
+ task = task,
+ host = '127.0.0.1',
+ timeout = 20,
+ port = 18080,
+ }
+
+ logger.errx(task, 'connect_sync %1, %2', is_ok, tostring(connection))
+ if not is_ok then
+ logger.errx(task, 'connect error: %1', connection)
+ return
+ end
+
+ is_ok, err = connection:write(string.format('%s %s HTTP/1.1\r\nConnection: close\r\n\r\n', method:upper(), url))
+
+ logger.errx(task, 'write %1, %2', is_ok, err)
+ if not is_ok then
+ logger.errx(task, 'write error: %1', err)
+ return
+ end
+
+ local content_length, content
+
+ while true do
+ local header_line
+ is_ok, header_line = connection:read_until("\r\n")
+ if not is_ok then
+ logger.errx(task, 'failed to get header: %1', header_line)
+ return
+ end
+
+ if header_line == "" then
+ logger.errx(task, 'headers done')
+ break
+ end
+
+ local value
+ local header = header_line:gsub("([%w-]+): (.*)",
+ function (h, v) value = v; return h:lower() end)
+
+ logger.errx(task, 'parsed header: %1 -> "%2"', header, value)
+
+ if header == "content-length" then
+ content_length = tonumber(value)
+ end
+
+ end
+
+ if content_length then
+ is_ok, content = connection:read_bytes(content_length)
+ if is_ok then
+ task:insert_result('HTTP_SYNC_CONTENT_' .. method, 1.0, content)
+ end
+ else
+ is_ok, content = connection:read_until_eof()
+ if is_ok then
+ task:insert_result('HTTP_SYNC_EOF_' .. method, 1.0, content)
+ end
+ end
+ logger.errx(task, '(is_ok: %1) content [%2 bytes] %3', is_ok, content_length, content)
+end
+
+rspamd_config:register_symbol({
+ name = 'SIMPLE_TCP_ASYNC_TEST',
+ score = 1.0,
+ callback = http_simple_tcp_async_symbol,
+ no_squeeze = true
+})
+rspamd_config:register_symbol({
+ name = 'SIMPLE_TCP_ASYNC_SSL_TEST',
+ score = 1.0,
+ callback = http_simple_tcp_ssl_symbol,
+ no_squeeze = true
+})
+rspamd_config:register_symbol({
+ name = 'LARGE_TCP_ASYNC_SSL_TEST',
+ score = 1.0,
+ callback = http_large_tcp_ssl_symbol,
+ no_squeeze = true
+})
+rspamd_config:register_symbol({
+ name = 'SIMPLE_TCP_TEST',
+ score = 1.0,
+ callback = http_simple_tcp_symbol,
+ no_squeeze = true,
+ flags = 'coro',
+})
+
+rspamd_config:register_symbol({
+ name = 'HTTP_TCP_TEST',
+ score = 1.0,
+ callback = http_tcp_symbol,
+ no_squeeze = true,
+ flags = 'coro',
+})
+-- ]]