Files
bunkerweb/deps/src/lua-resty-ipmatcher/t/sanity.t
2022-06-03 17:24:14 +02:00

492 lines
11 KiB
Perl

# vim:set ft= ts=4 sw=4 et fdm=marker:
use t::IP 'no_plan';
repeat_each(1);
run_tests();
__DATA__
=== TEST 1: ipv4 address
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new({
"127.0.0.1",
"127.0.0.2",
"192.168.0.0/16",
})
ngx.say(ip:match("127.0.0.1"))
ngx.say(ip:match("127.0.0.2"))
ngx.say(ip:match("127.0.0.3"))
ngx.say(ip:match("192.168.1.1"))
ngx.say(ip:match("192.168.1.100"))
ngx.say(ip:match("192.100.1.100"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
true
true
false
true
true
false
=== TEST 2: ipv6 address
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new({
"::1",
"fe80::/32",
})
ngx.say(ip:match("::1"))
ngx.say(ip:match("::2"))
ngx.say(ip:match("fe80::"))
ngx.say(ip:match("fe80:1::"))
ngx.say(ip:match("127.0.0.1"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
true
false
true
false
false
=== TEST 3: invalid ip address
--- config
location /t {
content_by_lua_block {
local ip, err = require("resty.ipmatcher").new({
"127.0.0.ffff",
})
ngx.say("ip: ", ip)
ngx.say("err:", err)
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
ip: nil
err:invalid ip address: 127.0.0.ffff
=== TEST 4: invalid ip address
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new({
"127.0.0.1",
})
local ok, err = ip:match("127.0.0.ffff")
ngx.say("ok: ", ok)
ngx.say("err:", err)
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
ok: false
err:invalid ip address, not ipv4 and ipv6
=== TEST 5: ipv6 address (short mask)
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new({
"fe80::/8",
})
ngx.say(ip:match("fe81::"))
ngx.say(ip:match("ff80::"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
true
false
=== TEST 6: parse ipv6 address
--- config
location /t {
content_by_lua_block {
local cases = {
{ip = "127.0.0.ffff"},
{ip = ""},
{ip = "["},
{ip = "[]"},
{ip = "[:1:]"},
{ip = "[::1x"},
{ip = "127.0.0.1"},
}
for _, case in ipairs(cases) do
local valid = require("resty.ipmatcher").parse_ipv6(case.ip)
if valid then
ngx.log(ngx.ERR, "expect invalid IPv6 ", case.ip)
end
end
local cases = {
{ip = "::1"},
{ip = "[::1]"},
{ip = "ff80::"},
}
for _, case in ipairs(cases) do
local valid = require("resty.ipmatcher").parse_ipv6(case.ip)
if not valid then
ngx.log(ngx.ERR, "expect IPv6 ", case.ip)
end
end
}
}
--- request
GET /t
--- no_error_log
[error]
=== TEST 7: match binary ip
This test requires building Nginx with --with-http_realip_module
--- config
location /foo {
set_real_ip_from 127.0.0.1;
content_by_lua_block {
ngx.log(ngx.INFO, ngx.var.http_x_real_ip, " ", ngx.var.binary_remote_addr)
ngx.print(ngx.var.binary_remote_addr)
}
}
location /t {
content_by_lua_block {
local function get_bin_ip(ip)
local sock = ngx.socket.tcp()
sock:settimeout(500)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
if not ok then
ngx.log(ngx.ERR, "failed to connect: ", err)
return
end
local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\nX-Real-IP:" .. ip .. "\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.log(ngx.ERR, "failed to send http request: ", err)
return
end
-- skip http header
while true do
local data, err, _ = sock:receive('*l')
if err then
ngx.log(ngx.ERR, 'unexpected error occurs when receiving http head: ' .. err)
return
end
if #data == 0 then -- read last line of head
break
end
end
local data, err = sock:receive('*a')
sock:close()
if not data then
ngx.log(ngx.ERR, "failed to receive body: ", err)
end
return data
end
local ip = require("resty.ipmatcher").new({
"127.0.0.1",
"192.168.0.0/16",
"::1",
"fe80::/8",
})
local cases = {
{ip = "127.0.0.1", matched = true},
{ip = "127.0.0.2", matched = false},
{ip = "192.168.0.22", matched = true},
{ip = "182.168.0.22", matched = false},
{ip = "::1", matched = true},
{ip = "::2", matched = false},
{ip = "fe80::1", matched = true},
}
for _, case in ipairs(cases) do
local res = ip:match_bin(get_bin_ip(case.ip))
if res ~= case.matched then
ngx.say("unexpected result for ", case.ip)
end
end
ngx.say("ok")
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
ok
=== TEST 8: zero mask
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new({
"::/0",
"0.0.0.0/0",
})
ngx.say(ip:match("127.0.0.1"))
ngx.say(ip:match("0.0.0.0"))
ngx.say(ip:match("fe81::"))
ngx.say(ip:match("ff80::"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
true
true
true
true
=== TEST 9: ipv6 special notation
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new({
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
})
ngx.say(ip:match("2001:0db8:85a3:0000:0000:8a2e:0370:7334"))
-- zero in some occasions can be omitted
ngx.say(ip:match("2001:db8:85a3:0:0:8a2e:370:7334"))
ngx.say(ip:match("2001:db8:85a3::8a2e:370:7334"))
local ip = require("resty.ipmatcher").new({
"::ffff:192.0.2.128",
})
ngx.say(ip:match("::ffff:192.0.2.128"))
-- ipv4-mapped address
ngx.say(ip:match("::ffff:c000:0280"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
true
true
true
true
true
=== TEST 10: match with new_with_value
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new_with_value({
["127.0.0.1"] = 1,
["192.168.0.0/16"] = "2",
["::1"] = 3,
["fe80::/32"] = {value = 4},
["fe81::/32"] = false,
})
ngx.say(ip:match("127.0.0.1"))
ngx.say(ip:match("127.0.0.2"))
ngx.say(ip:match("192.168.1.1"))
ngx.say(ip:match("192.168.1.100"))
ngx.say(ip:match("192.100.1.100"))
ngx.say(ip:match("::1"))
ngx.say(ip:match("::2"))
ngx.say(ip:match("fe80::").value)
ngx.say(ip:match("fe80:1::"))
ngx.say(ip:match("fe81::"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
1
false
2
2
false
3
false
4
false
false
=== TEST 11: new_with_value and zero mask
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new_with_value({
["::/0"] = 1,
["0.0.0.0/0"] = 2,
})
ngx.say(ip:match("127.0.0.1"))
ngx.say(ip:match("0.0.0.0"))
ngx.say(ip:match("fe81::"))
ngx.say(ip:match("ff80::"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
2
2
1
1
=== TEST 12: bug: ipv4 address overrided with the same mask
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new({
"192.168.0.0/16",
"192.0.0.0/16",
})
ngx.say(ip:match("192.168.1.1"))
ngx.say(ip:match("192.0.1.100"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
true
true
=== TEST 13: bug fixing: same ipv6 prefix with the same mask
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new({
'2409:8928:6a00::/39',
'2409:8928:a000::/39', -- 2409:8928:a000:: - 2409:8928:a1ff:ffff:ffff:ffff:ffff:ffff
})
ngx.say(ip:match("2409:8928:6a00:2a57:1:1:d823:4521"))
ngx.say(ip:match("2409:8928:6a01::"))
ngx.say(ip:match("2409:8928:a0f8:2a57:1:1:d823:4521"))
ngx.say(ip:match("2409:8928:a100::"))
ngx.say(ip:match("2409:8928:a200::"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
true
true
true
true
false
=== TEST 14: accurate match with new_with_value
--- config
location /t {
content_by_lua_block {
local ip = require("resty.ipmatcher").new_with_value({
["192.168.1.1/24"] = "level3",
["192.168.1.1/16"] = "level2",
["192.168.1.1/8"] = "level1",
})
ngx.say(ip:match("192.168.1.2"))
ngx.say(ip:match("192.168.2.2"))
ngx.say(ip:match("192.2.2.2"))
local ip = require("resty.ipmatcher").new_with_value({
["192.168.1.1/16"] = "level2",
["192.168.1.1/8"] = "level1",
["192.168.1.1/24"] = "level3",
})
ngx.say(ip:match("192.168.1.2"))
ngx.say(ip:match("192.168.2.2"))
ngx.say(ip:match("192.2.2.2"))
local ip = require("resty.ipmatcher").new_with_value({
["192.168.1.1/8"] = "level1",
["192.168.1.1/16"] = "level2",
["192.168.1.1/24"] = "level3",
})
ngx.say(ip:match("192.168.1.2"))
ngx.say(ip:match("192.168.2.2"))
ngx.say(ip:match("192.2.2.2"))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
level3
level2
level1
level3
level2
level1
level3
level2
level1