Files
2026-07-13 12:32:21 +08:00

169 lines
5.6 KiB
Lua

local client = require "resty.websocket.client"
local helpers = require "spec.helpers"
local cjson = require "cjson"
for _, enable_buffering in ipairs({ false, true }) do
for _, strategy in helpers.each_strategy() do
describe("Websockets [#" .. strategy .. "]" .. (enable_buffering and " with buffering on" or ""), function()
lazy_setup(function()
local bp = helpers.get_db_utils(strategy, {
"routes",
"services",
enable_buffering and "plugins"
}, enable_buffering and { "enable-buffering" } or nil)
local service = bp.services:insert {
name = "ws",
path = "/ws",
}
bp.routes:insert {
protocols = { "http" },
paths = { "/up-ws" },
service = service,
strip_path = true,
}
if enable_buffering then
bp.plugins:insert({
name = "enable-buffering",
protocols = { "http", "https", "grpc", "grpcs" },
service = ngx.null,
consumer = ngx.null,
route = ngx.null,
})
end
assert(helpers.start_kong({
database = strategy,
plugins = enable_buffering and "bundled,enable-buffering",
nginx_conf = "spec/fixtures/custom_nginx.template",
}))
end)
lazy_teardown(function()
helpers.stop_kong()
end)
local function open_socket(uri)
local wc = assert(client:new())
assert(wc:connect(uri))
return wc
end
local function check_headers(host, port)
local is_kong = (host == helpers.get_proxy_ip(false) and
port == helpers.get_proxy_port(false)) or
(host == helpers.get_proxy_ip(true) and
port == helpers.get_proxy_port(true))
local encode_base64 = ngx.encode_base64
local rand = math.random
local char = string.char
local sock = assert(ngx.socket.tcp())
local path = is_kong and "/up-ws" or "/ws"
assert(sock:connect(host, port))
local bytes = char(rand(256) - 1, rand(256) - 1, rand(256) - 1,
rand(256) - 1, rand(256) - 1, rand(256) - 1,
rand(256) - 1, rand(256) - 1, rand(256) - 1,
rand(256) - 1, rand(256) - 1, rand(256) - 1,
rand(256) - 1, rand(256) - 1, rand(256) - 1,
rand(256) - 1)
local key = encode_base64(bytes)
local req = "GET " .. path .. " HTTP/1.1\r\nUpgrade: websocket\r\nHost: "
.. host .. ":" .. port
.. "\r\nSec-WebSocket-Key: " .. key
.. "\r\nSec-WebSocket-Version: 13"
.. "\r\nConnection: Upgrade\r\n\r\n"
assert(sock:send(req))
local header_reader = sock:receiveuntil("\r\n\r\n")
local header = assert(header_reader())
assert(sock:close())
assert.equal(true, string.find(header, "HTTP/1.1 101 Switching Protocols") ~= nil, 1, true)
assert.equal(true, string.find(header, "Connection: upgrade") ~= nil, 1, true)
assert.equal(true, string.find(header, "Upgrade: websocket") ~= nil, 1, true)
if is_kong then
assert.equal(true, string.find(header, "Via: 1.1 kong") ~= nil, 1, true)
end
end
describe("headers", function()
it("returns correct headers on handshake without Kong", function()
check_headers("127.0.0.1", "15555")
end)
it("returns correct headers on handshake with Kong", function()
check_headers(helpers.get_proxy_ip(false), helpers.get_proxy_port(false))
end)
end)
describe("text", function()
local function send_text_and_get_echo(uri)
local payload = { message = "hello websocket" }
local wc = open_socket(uri)
assert(wc:send_text(cjson.encode(payload)))
local frame, typ, err = wc:recv_frame()
assert.is_nil(wc.fatal)
assert(frame, err)
assert.equal("text", typ)
assert.same(payload, cjson.decode(frame))
assert(wc:send_close())
end
it("sends and gets text without Kong", function()
send_text_and_get_echo("ws://127.0.0.1:15555/ws")
end)
it("sends and gets text with Kong", function()
send_text_and_get_echo("ws://" .. helpers.get_proxy_ip(false) ..
":" .. helpers.get_proxy_port(false) .. "/up-ws")
end)
it("sends and gets text with kong under HTTPS", function()
send_text_and_get_echo("wss://" .. helpers.get_proxy_ip(true) ..
":" .. helpers.get_proxy_port(true) .. "/up-ws")
end)
end)
describe("ping pong", function()
local function send_ping_and_get_pong(uri)
local payload = { message = "give me a pong" }
local wc = open_socket(uri)
assert(wc:send_ping(cjson.encode(payload)))
local frame, typ, err = wc:recv_frame()
assert.is_nil(wc.fatal)
assert(frame, err)
assert.equal("pong", typ)
assert.same(payload, cjson.decode(frame))
assert(wc:send_close())
end
it("plays ping-pong without Kong", function()
send_ping_and_get_pong("ws://127.0.0.1:15555/ws")
end)
it("plays ping-pong with Kong", function()
send_ping_and_get_pong("ws://" .. helpers.get_proxy_ip(false) ..
":" .. helpers.get_proxy_port(false) .. "/up-ws")
end)
it("plays ping-pong with kong under HTTPS", function()
send_ping_and_get_pong("wss://" .. helpers.get_proxy_ip(true) ..
":" .. helpers.get_proxy_port(true) .. "/up-ws")
end)
end)
end)
end
end