169 lines
5.6 KiB
Lua
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
|