kong/spec/02-integration/05-proxy/03-upstream_headers_spec.lua (886 lines of code) (raw):
local helpers = require "spec.helpers"
local cjson = require "cjson"
local stop_kong = helpers.stop_kong
for _, strategy in helpers.each_strategy() do
describe("Upstream header(s) [#" .. strategy .. "]", function()
local proxy_client
local bp, db
local function insert_routes(arr)
if type(arr) ~= "table" then
return error("expected arg #1 to be a table", 2)
end
for i = 1, #arr do
local service = assert(bp.services:insert())
local route = arr[i]
route.service = service
bp.routes:insert(route)
end
end
local function request_headers(headers, path)
local res = assert(proxy_client:send {
method = "GET",
path = path or "/",
headers = headers,
})
local json = assert.res_status(200, res)
return cjson.decode(json).headers
end
local function start_kong(config)
return function()
assert(db:truncate("routes"))
assert(db:truncate("services"))
insert_routes {
{
protocols = { "http" },
hosts = { "headers-inspect.com" },
},
{
protocols = { "http" },
hosts = { "preserved.com" },
preserve_host = true,
},
{
protocols = { "http" },
paths = { "/foo" },
strip_path = true,
},
{
protocols = { "http" },
paths = { "/status/200" },
strip_path = false,
},
{
protocols = { "http" },
paths = { "/" },
strip_path = true,
},
}
local service = assert(bp.services:insert())
local route = bp.routes:insert({
service = service,
protocols = { "http" },
paths = { "/proxy-authorization" },
strip_path = true,
})
bp.plugins:insert({
route = route,
name = "request-transformer",
config = {
add = {
headers = {
"Proxy-Authorization:Basic ZGVtbzp0ZXN0",
},
},
replace = {
headers = {
"Proxy-Authorization:Basic ZGVtbzp0ZXN0",
},
},
},
})
assert(helpers.start_kong(config))
end
end
lazy_setup(function()
bp, db = helpers.get_db_utils(strategy, {
"routes",
"services",
})
end)
before_each(function()
proxy_client = helpers.proxy_client()
end)
after_each(function()
if proxy_client then
proxy_client:close()
end
end)
describe("hop-by-hop headers", function()
lazy_setup(start_kong {
database = strategy,
nginx_conf = "spec/fixtures/custom_nginx.template",
lua_package_path = "?/init.lua;./kong/?.lua;./spec/fixtures/?.lua",
})
lazy_teardown(stop_kong)
it("are removed from request", function()
local headers = request_headers({
["Connection"] = "X-Foo, X-Bar",
["Host"] = "headers-inspect.com",
["Keep-Alive"] = "timeout=5, max=1000",
["Proxy"] = "Remove-Me", -- See: https://httpoxy.org/
["Proxy-Connection"] = "close",
-- This is a response header, so we don't remove it, should we?
["Proxy-Authenticate"] = "Basic",
["Proxy-Authorization"] = "Basic YWxhZGRpbjpvcGVuc2VzYW1l",
["TE"] = "trailers, deflate;q=0.5",
--["Transfer-Encoding"] = "identity", -- Removed with OpenResty 1.19.3.1 as Nginx errors with:
-- client sent unknown "Transfer-Encoding": "identity"
-- This is a response header, so we don't remove it, should we?
--["Trailer"] = "Expires",
["Upgrade"] = "example/1, foo/2",
["X-Foo"] = "Remove-Me",
["X-Bar"] = "Remove-Me",
["X-Foo-Bar"] = "Keep-Me",
["Close"] = "Keep-Me",
})
assert.is_nil(headers["keep-alive"])
assert.is_nil(headers["proxy"])
assert.is_nil(headers["proxy-connection"])
assert.is_nil(headers["upgrade"])
assert.is_nil(headers["x-boo"])
assert.is_nil(headers["x-bar"])
assert.equal("Basic", headers["proxy-authenticate"])
assert.equal("Basic YWxhZGRpbjpvcGVuc2VzYW1l", headers["proxy-authorization"])
assert.equal("trailers", headers["te"]) -- trailers are kept
assert.equal("Keep-Me", headers["x-foo-bar"])
assert.equal("Keep-Me", headers["close"])
end)
it("are removed from response", function()
local res = assert(proxy_client:send {
method = "GET",
headers = {
["Host"] = "headers-inspect.com",
},
path = "/hop-by-hop",
})
assert.res_status(200, res)
local headers = res.headers
assert.is_nil(headers["keep-alive"])
-- This needs to be cleared only on requests (https://httpoxy.org/)
--assert.is_nil(headers["proxy"])
-- This is a request header, so we don't remove it, should we?
--assert.is_nil(headers["proxy-connection"])
--assert.is_nil(headers["proxy-authenticate"])
-- This is a request header, so we don't remove it, should we?
--assert.is_nil(headers["proxy-authorization"])
-- This is a request header, so we don't remove it, should we?
--assert.is_nil(headers["te"])
assert.is_nil(headers["trailer"])
assert.is_nil(headers["upgrade"])
assert.equal("chunked", headers["transfer-encoding"])
end)
it("keeps trailer when requested", function()
local res = assert(proxy_client:send {
method = "GET",
headers = {
["Host"] = "headers-inspect.com",
["TE"] = "trailers"
},
path = "/hop-by-hop",
})
assert.res_status(200, res)
local headers = res.headers
assert.equal("Expires", headers["Trailer"])
end)
it("keeps upgrade when upgrading", function()
local res = assert(proxy_client:send {
method = "GET",
headers = {
["Host"] = "headers-inspect.com",
["Connection"] = "keep-alive, Upgrade",
["Upgrade"] = "websocket"
},
path = "/get",
})
local json = cjson.decode(assert.res_status(200, res))
assert.equal("keep-alive, Upgrade", json.headers.connection)
assert.equal("websocket", json.headers.upgrade)
end)
it("keeps proxy-authorization header when a plugin specifies it", function()
local headers = request_headers({
["Proxy-Authorization"] = "Basic YWxhZGRpbjpvcGVuc2VzYW1l",
}, "/proxy-authorization")
assert.equal("Basic ZGVtbzp0ZXN0", headers["proxy-authorization"])
local headers = request_headers({}, "/proxy-authorization")
assert.equal("Basic ZGVtbzp0ZXN0", headers["proxy-authorization"])
end)
it("keeps proxy-authorization header if plugin specifies same value as in requests", function()
local headers = request_headers({
["Proxy-Authorization"] = "Basic ZGVtbzp0ZXN0",
}, "/proxy-authorization")
assert.equal("Basic ZGVtbzp0ZXN0", headers["proxy-authorization"])
end)
end)
describe("(using the default configuration values)", function()
lazy_setup(start_kong {
database = strategy,
nginx_conf = "spec/fixtures/custom_nginx.template",
lua_package_path = "?/init.lua;./kong/?.lua;./spec/fixtures/?.lua",
})
lazy_teardown(stop_kong)
describe("X-Real-IP", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Real-IP"] = "10.0.0.1",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
end)
end)
describe("X-Forwarded-For", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("127.0.0.1", headers["x-forwarded-for"])
end)
it("should be appended if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-For"] = "10.0.0.1",
}
assert.equal("10.0.0.1, 127.0.0.1", headers["x-forwarded-for"])
end)
end)
describe("X-Forwarded-Proto", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("http", headers["x-forwarded-proto"])
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Proto"] = "https",
}
assert.equal("http", headers["x-forwarded-proto"])
end)
end)
describe("X-Forwarded-Host", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("headers-inspect.com", headers["x-forwarded-host"])
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Host"] = "example.com",
}
assert.equal("headers-inspect.com", headers["x-forwarded-host"])
end)
end)
describe("X-Forwarded-Port", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Port"] = "80",
}
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
end)
end)
describe("X-Forwarded-Path", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("/", headers["x-forwarded-path"])
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Path"] = "/replaced",
}
assert.equal("/", headers["x-forwarded-path"])
end)
end)
describe("X-Forwarded-Prefix", function()
it("should be added if path was stripped", function()
local headers = request_headers({}, "/foo/status/200")
assert.equal("/foo", headers["x-forwarded-prefix"])
end)
it("should be replaced if present in request and path was stripped", function()
local headers = request_headers({
["X-Forwarded-Prefix"] = "/replaced",
}, "/foo")
assert.equal("/foo", headers["x-forwarded-prefix"])
end)
it("should not be added if path was not stripped", function()
local headers = request_headers({}, "/status/200")
assert.is_nil(headers["x-forwarded-prefix"])
end)
it("should not be added if / was stripped", function()
local headers = request_headers({}, "/")
assert.is_nil(headers["x-forwarded-prefix"])
end)
end)
describe("with the downstream host preserved", function()
it("should be added if not present in request while preserving the downstream host", function()
local headers = request_headers {
["Host"] = "preserved.com",
}
assert.equal("preserved.com", headers["host"])
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1", headers["x-forwarded-for"])
assert.equal("http", headers["x-forwarded-proto"])
assert.equal("preserved.com", headers["x-forwarded-host"])
assert.equal("/", headers["x-forwarded-path"])
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
end)
it("should be added if present in request while preserving the downstream host", function()
local headers = request_headers {
["Host"] = "preserved.com",
["X-Real-IP"] = "10.0.0.1",
["X-Forwarded-For"] = "10.0.0.1",
["X-Forwarded-Proto"] = "https",
["X-Forwarded-Host"] = "example.com",
["X-Forwarded-Port"] = "80",
}
assert.equal("preserved.com", headers["host"])
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("10.0.0.1, 127.0.0.1", headers["x-forwarded-for"])
assert.equal("http", headers["x-forwarded-proto"])
assert.equal("preserved.com", headers["x-forwarded-host"])
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
assert.equal("/", headers["x-forwarded-path"])
end)
end)
describe("with the downstream host discarded", function()
it("should be added if not present in request while discarding the downstream host", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal(helpers.mock_upstream_host .. ":" ..
helpers.mock_upstream_port,
headers["host"])
assert.equal(helpers.mock_upstream_host, headers["x-real-ip"])
assert.equal(helpers.mock_upstream_host, headers["x-forwarded-for"])
assert.equal("http", headers["x-forwarded-proto"])
assert.equal("headers-inspect.com", headers["x-forwarded-host"])
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
assert.equal("/", headers["x-forwarded-path"])
end)
it("if present in request while discarding the downstream host", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Real-IP"] = "10.0.0.1",
["X-Forwarded-For"] = "10.0.0.1",
["X-Forwarded-Proto"] = "https",
["X-Forwarded-Host"] = "example.com",
["X-Forwarded-Port"] = "80",
}
assert.equal(helpers.mock_upstream_host .. ":" ..
helpers.mock_upstream_port,
headers["host"])
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("10.0.0.1, 127.0.0.1", headers["x-forwarded-for"])
assert.equal("http", headers["x-forwarded-proto"])
assert.equal("headers-inspect.com", headers["x-forwarded-host"])
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
assert.equal("/", headers["x-forwarded-path"])
end)
end)
end)
describe("(using the trusted configuration values)", function()
lazy_setup(start_kong {
database = strategy,
trusted_ips = "127.0.0.1",
nginx_conf = "spec/fixtures/custom_nginx.template",
lua_package_path = "?/init.lua;./kong/?.lua;./spec/fixtures/?.lua",
})
lazy_teardown(stop_kong)
describe("X-Real-IP", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
end)
it("should be forwarded if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Real-IP"] = "10.0.0.1",
}
assert.equal("10.0.0.1", headers["x-real-ip"])
end)
end)
describe("X-Forwarded-For", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("127.0.0.1", headers["x-forwarded-for"])
end)
it("should be appended if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-For"] = "10.0.0.1",
}
assert.equal("10.0.0.1, 127.0.0.1", headers["x-forwarded-for"])
end)
end)
describe("X-Forwarded-Proto", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("http", headers["x-forwarded-proto"])
end)
it("should be forwarded if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Proto"] = "https",
}
assert.equal("https", headers["x-forwarded-proto"])
end)
end)
describe("X-Forwarded-Host", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("headers-inspect.com", headers["x-forwarded-host"])
end)
it("should be forwarded if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Host"] = "example.com",
}
assert.equal("example.com", headers["x-forwarded-host"])
end)
end)
describe("X-Forwarded-Port", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
end)
it("should be forwarded if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Port"] = "80",
}
assert.equal("80", headers["x-forwarded-port"])
end)
end)
describe("X-Forwarded-Path", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("/", headers["x-forwarded-path"])
end)
it("should be forwarded if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Path"] = "/original-path",
}
assert.equal("/original-path", headers["x-forwarded-path"])
end)
end)
describe("X-Forwarded-Prefix", function()
it("should be preserved even if path was stripped", function()
local headers = request_headers({
["x-forwarded-prefix"] = "/preserved",
}, "/foo/status/200")
assert.equal("/preserved", headers["x-forwarded-prefix"])
end)
it("should be preserved even if path was stripped", function()
local headers = request_headers({
["x-forwarded-prefix"] = "/preserved",
}, "/status/200")
assert.equal("/preserved", headers["x-forwarded-prefix"])
end)
end)
end)
describe("(using the non-trusted configuration values)", function()
lazy_setup(start_kong {
database = strategy,
trusted_ips = "10.0.0.1",
nginx_conf = "spec/fixtures/custom_nginx.template",
lua_package_path = "?/init.lua;./kong/?.lua;./spec/fixtures/?.lua",
})
lazy_teardown(stop_kong)
describe("X-Real-IP", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Real-IP"] = "10.0.0.1",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
end)
end)
describe("X-Forwarded-For", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("127.0.0.1", headers["x-forwarded-for"])
end)
it("should be appended if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-For"] = "10.0.0.1",
}
assert.equal("10.0.0.1, 127.0.0.1", headers["x-forwarded-for"])
end)
end)
describe("X-Forwarded-Proto", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("http", headers["x-forwarded-proto"])
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Proto"] = "https",
}
assert.equal("http", headers["x-forwarded-proto"])
end)
end)
describe("X-Forwarded-Host", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("headers-inspect.com", headers["x-forwarded-host"])
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Host"] = "example.com",
}
assert.equal("headers-inspect.com", headers["x-forwarded-host"])
end)
end)
describe("X-Forwarded-Port", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Port"] = "80",
}
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
end)
end)
describe("X-Forwarded-Path", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("/", headers["x-forwarded-path"])
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Path"] = "/untrusted",
}
assert.equal("/", headers["x-forwarded-path"])
end)
end)
describe("X-Forwarded-Prefix", function()
it("should be added if path was stripped", function()
local headers = request_headers({}, "/foo/status/200")
assert.equal("/foo", headers["x-forwarded-prefix"])
end)
it("should be replaced if present in request and path was stripped", function()
local headers = request_headers({
["X-Forwarded-Prefix"] = "/replaced",
}, "/foo")
assert.equal("/foo", headers["x-forwarded-prefix"])
end)
it("should not be added if path was not stripped", function()
local headers = request_headers({}, "/status/200")
assert.is_nil(headers["x-forwarded-prefix"])
end)
it("should not be added if / was stripped", function()
local headers = request_headers({}, "/")
assert.is_nil(headers["x-forwarded-prefix"])
end)
end)
end)
describe("(using the recursive trusted configuration values)", function()
lazy_setup(start_kong {
database = strategy,
real_ip_header = "X-Forwarded-For",
real_ip_recursive = "on",
trusted_ips = "127.0.0.1,172.16.0.1,192.168.0.1",
nginx_conf = "spec/fixtures/custom_nginx.template",
lua_package_path = "?/init.lua;./kong/?.lua;./spec/fixtures/?.lua",
})
lazy_teardown(stop_kong)
describe("X-Real-IP and X-Forwarded-For", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1", headers["x-forwarded-for"])
end)
it("should be changed according to rules if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-For"] = "127.0.0.1, 10.0.0.1, 192.168.0.1, 127.0.0.1, 172.16.0.1",
["X-Real-IP"] = "10.0.0.2",
}
assert.equal("10.0.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1, 10.0.0.1, 192.168.0.1, 127.0.0.1, 172.16.0.1, 127.0.0.1", headers["x-forwarded-for"])
end)
end)
describe("X-Forwarded-Port", function()
it("should be forwarded even if X-Forwarded-For header has a port in it", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-For"] = "127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18",
["X-Real-IP"] = "10.0.0.2",
["X-Forwarded-Port"] = "14",
}
assert.equal("10.0.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18, 127.0.0.1", headers["x-forwarded-for"])
assert.equal(14, tonumber(headers["x-forwarded-port"]))
end)
pending("should take a port from X-Forwarded-For header if it has a port in it", function()
-- local headers = request_headers {
-- ["Host"] = "headers-inspect.com",
-- ["X-Forwarded-For"] = "127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18",
-- ["X-Real-IP"] = "10.0.0.2",
-- }
--
-- assert.equal("10.0.0.1", headers["x-real-ip"])
-- assert.equal("127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18, 127.0.0.1", headers["x-forwarded-for"])
-- assert.equal(16, tonumber(headers["x-forwarded-port"]))
end)
end)
end)
describe("(using the recursive non-trusted configuration values)", function()
lazy_setup(start_kong {
database = strategy,
real_ip_header = "X-Forwarded-For",
real_ip_recursive = "on",
trusted_ips = "10.0.0.1,172.16.0.1,192.168.0.1",
nginx_conf = "spec/fixtures/custom_nginx.template",
lua_package_path = "?/init.lua;./kong/?.lua;./spec/fixtures/?.lua",
})
lazy_teardown(stop_kong)
describe("X-Real-IP and X-Forwarded-For", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1", headers["x-forwarded-for"])
end)
it("should be changed according to rules if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-For"] = "10.0.0.1, 127.0.0.2, 10.0.0.1, 192.168.0.1, 172.16.0.1",
["X-Real-IP"] = "10.0.0.2",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("10.0.0.1, 127.0.0.2, 10.0.0.1, 192.168.0.1, 172.16.0.1, 127.0.0.1", headers["x-forwarded-for"])
end)
end)
describe("X-Forwarded-Port", function()
it("should be replaced even if X-Forwarded-Port and X-Forwarded-For headers have a port in it", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-For"] = "127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18",
["X-Real-IP"] = "10.0.0.2",
["X-Forwarded-Port"] = "14",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18, 127.0.0.1", headers["x-forwarded-for"])
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
end)
it("should not take a port from X-Forwarded-For header if it has a port in it", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-For"] = "127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18",
["X-Real-IP"] = "10.0.0.2",
}
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18, 127.0.0.1", headers["x-forwarded-for"])
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
end)
end)
end)
describe("(using trusted proxy protocol configuration values)", function()
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
lazy_setup(start_kong {
database = strategy,
proxy_listen = proxy_ip .. ":" .. proxy_port .. " proxy_protocol",
real_ip_header = "proxy_protocol",
real_ip_recursive = "on",
trusted_ips = "127.0.0.1,172.16.0.1,192.168.0.1",
nginx_conf = "spec/fixtures/custom_nginx.template",
lua_package_path = "?/init.lua;./kong/?.lua;./spec/fixtures/?.lua",
})
lazy_teardown(stop_kong)
describe("X-Real-IP, X-Forwarded-For and X-Forwarded-Port", function()
it("should be added if not present in request", function()
local sock = ngx.socket.tcp()
local request = "PROXY TCP4 192.168.0.1 " .. helpers.get_proxy_ip(false) .. " 56324 " .. helpers.get_proxy_port(false) .. "\r\n" ..
"GET / HTTP/1.1\r\n" ..
"Host: headers-inspect.com\r\n" ..
"Connection: close\r\n" ..
"\r\n"
assert(sock:connect(helpers.get_proxy_ip(false), helpers.get_proxy_port(false)))
assert(sock:send(request))
local response, err = sock:receive "*a"
assert(response, err)
local json = string.match(response, "%b{}")
assert.is_not_nil(json)
local headers = cjson.decode(json).headers
assert.equal("192.168.0.1", headers["x-real-ip"])
assert.equal("192.168.0.1", headers["x-forwarded-for"])
assert.equal(helpers.get_proxy_port(false), tonumber(headers["x-forwarded-port"]))
assert(sock:close())
end)
it("should be changed according to rules if present in request", function()
local sock = ngx.socket.tcp()
local request = "PROXY TCP4 192.168.0.1 " .. helpers.get_proxy_ip(false) .. " 56324 " .. helpers.get_proxy_port(false) .. "\r\n" ..
"GET / HTTP/1.1\r\n" ..
"Host: headers-inspect.com\r\n" ..
"Connection: close\r\n" ..
"X-Real-IP: 10.0.0.2\r\n" ..
"X-Forwarded-For: 10.0.0.1, 127.0.0.2, 10.0.0.1, 192.168.0.1, 172.16.0.1\r\n" ..
"\r\n"
assert(sock:connect(helpers.get_proxy_ip(false), helpers.get_proxy_port(false)))
assert(sock:send(request))
local response, err = sock:receive "*a"
assert(response, err)
local json = string.match(response, "%b{}")
assert.is_not_nil(json)
local headers = cjson.decode(json).headers
assert.equal("192.168.0.1", headers["x-real-ip"])
assert.equal("10.0.0.1, 127.0.0.2, 10.0.0.1, 192.168.0.1, 172.16.0.1, 127.0.0.1", headers["x-forwarded-for"])
assert(sock:close())
end)
end)
describe("X-Forwarded-Port", function()
it("should be forwarded even if proxy protocol and X-Forwarded-For header has a port in it", function()
local sock = ngx.socket.tcp()
local request = "PROXY TCP4 192.168.0.1 " .. helpers.get_proxy_ip(false) .. " 56324 " .. helpers.get_proxy_port(false) .. "\r\n" ..
"GET / HTTP/1.1\r\n" ..
"Host: headers-inspect.com\r\n" ..
"Connection: close\r\n" ..
"X-Real-IP: 10.0.0.2\r\n" ..
"X-Forwarded-For: 127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18\r\n" ..
"X-Forwarded-Port: 14\r\n" ..
"\r\n"
assert(sock:connect(helpers.get_proxy_ip(false), helpers.get_proxy_port(false)))
assert(sock:send(request))
local response, err = sock:receive "*a"
assert(response, err)
local json = string.match(response, "%b{}")
assert.is_not_nil(json)
local headers = cjson.decode(json).headers
assert.equal("192.168.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18, 127.0.0.1", headers["x-forwarded-for"])
assert.equal(14, tonumber(headers["x-forwarded-port"]))
assert(sock:close())
end)
end)
end)
describe("(using non-trusted proxy protocol configuration values)", function()
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
lazy_setup(start_kong {
database = strategy,
proxy_listen = "0.0.0.0:" .. proxy_port .. " proxy_protocol",
real_ip_header = "proxy_protocol",
real_ip_recursive = "on",
trusted_ips = "10.0.0.1,172.16.0.1,192.168.0.1",
nginx_conf = "spec/fixtures/custom_nginx.template",
lua_package_path = "?/init.lua;./kong/?.lua;./spec/fixtures/?.lua",
})
lazy_teardown(stop_kong)
describe("X-Real-IP, X-Forwarded-For and X-Forwarded-Port", function()
it("should be added if not present in request", function()
local sock = ngx.socket.tcp()
local request = "PROXY TCP4 192.168.0.1 " .. proxy_ip .. " 56324 " .. proxy_port .. "\r\n" ..
"GET / HTTP/1.1\r\n" ..
"Host: headers-inspect.com\r\n" ..
"Connection: close\r\n" ..
"\r\n"
assert(sock:connect(proxy_ip, tonumber(proxy_port)))
assert(sock:send(request))
local response, err = sock:receive "*a"
assert(response, err)
local json = string.match(response, "%b{}")
assert.is_not_nil(json)
local headers = cjson.decode(json).headers
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1", headers["x-forwarded-for"])
assert.equal(proxy_port, tonumber(headers["x-forwarded-port"]))
assert(sock:close())
end)
it("should be changed according to rules if present in request", function()
local sock = ngx.socket.tcp()
local request = "PROXY TCP4 192.168.0.1 " .. proxy_ip .. " 56324 " .. proxy_port .. "\r\n" ..
"GET / HTTP/1.1\r\n" ..
"Host: headers-inspect.com\r\n" ..
"Connection: close\r\n" ..
"X-Real-IP: 10.0.0.2\r\n" ..
"X-Forwarded-For: 10.0.0.1, 127.0.0.2, 10.0.0.1, 192.168.0.1, 172.16.0.1\r\n" ..
"\r\n"
assert(sock:connect(proxy_ip, proxy_port))
assert(sock:send(request))
local response, err = sock:receive "*a"
assert(response, err)
local json = string.match(response, "%b{}")
assert.is_not_nil(json)
local headers = cjson.decode(json).headers
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("10.0.0.1, 127.0.0.2, 10.0.0.1, 192.168.0.1, 172.16.0.1, 127.0.0.1", headers["x-forwarded-for"])
assert(sock:close())
end)
end)
describe("X-Forwarded-Port", function()
it("should be replaced even if proxy protocol, X-Forwarded-Port and X-Forwarded-For headers have a port in it", function()
local sock = ngx.socket.tcp()
local request = "PROXY TCP4 192.168.0.1 " .. proxy_ip .. " 56324 " .. proxy_port .. "\r\n" ..
"GET / HTTP/1.1\r\n" ..
"Host: headers-inspect.com\r\n" ..
"Connection: close\r\n" ..
"X-Real-IP: 10.0.0.2\r\n" ..
"X-Forwarded-For: 127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18\r\n" ..
"X-Forwarded-Port: 14\r\n" ..
"\r\n"
assert(sock:connect(proxy_ip, tonumber(proxy_port)))
assert(sock:send(request))
local response, err = sock:receive "*a"
assert(response, err)
local json = string.match(response, "%b{}")
assert.is_not_nil(json)
local headers = cjson.decode(json).headers
assert.equal("127.0.0.1", headers["x-real-ip"])
assert.equal("127.0.0.1:14, 10.0.0.1:15, 192.168.0.1:16, 127.0.0.1:17, 172.16.0.1:18, 127.0.0.1", headers["x-forwarded-for"])
assert.equal(proxy_port, tonumber(headers["x-forwarded-port"]))
assert(sock:close())
end)
end)
end)
describe("(using port maps configuration)", function()
local proxy_port = helpers.get_proxy_port(false)
lazy_setup(start_kong {
database = strategy,
nginx_conf = "spec/fixtures/custom_nginx.template",
lua_package_path = "?/init.lua;./kong/?.lua;./spec/fixtures/?.lua",
port_maps = "80:" .. proxy_port,
})
lazy_teardown(stop_kong)
describe("X-Forwarded-Port", function()
it("should be added if not present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
}
assert.equal(80, tonumber(headers["x-forwarded-port"]))
end)
it("should be replaced if present in request", function()
local headers = request_headers {
["Host"] = "headers-inspect.com",
["X-Forwarded-Port"] = "81",
}
assert.equal(80, tonumber(headers["x-forwarded-port"]))
end)
end)
end)
end)
end