Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closing #1150 #1180

Merged
merged 1 commit into from
Apr 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion kong/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ return {
CREDENTIAL_USERNAME = "X-Credential-Username",
RATELIMIT_LIMIT = "X-RateLimit-Limit",
RATELIMIT_REMAINING = "X-RateLimit-Remaining",
CONSUMER_GROUPS = "X-Consumer-Groups"
CONSUMER_GROUPS = "X-Consumer-Groups",
FORWARDED_HOST = "X-Forwarded-Host",
FORWARDED_PREFIX = "X-Forwarded-Prefix"
},
RATELIMIT = {
PERIODS = {
Expand Down
2 changes: 2 additions & 0 deletions kong/core/resolver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ local function find_api(uri, headers)
api, matched_host, hosts_list = _M.find_api_by_request_host(headers, apis_dics)
-- If it was found by Host, return
if api then
ngx.req.set_header(constants.HEADERS.FORWARDED_HOST, matched_host)
return nil, api, matched_host, hosts_list
end

Expand Down Expand Up @@ -240,6 +241,7 @@ function _M.execute(request_uri, request_headers)
-- If API was retrieved by request_path and the request_path needs to be stripped
if strip_request_path_pattern and api.strip_request_path then
uri = _M.strip_request_path(uri, strip_request_path_pattern, url_has_path(upstream_url))
ngx.req.set_header(constants.HEADERS.FORWARDED_PREFIX, api.request_path)
end

upstream_url = upstream_url..uri
Expand Down
57 changes: 47 additions & 10 deletions spec/integration/05-proxy/resolver_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ describe("Resolver", function()
{name = "tests-trailing-slash-path3", request_path = "/test-trailing-slash3", strip_request_path = true, upstream_url = "http://www.mockbin.org"},
{name = "tests-trailing-slash-path4", request_path = "/test-trailing-slash4", strip_request_path = true, upstream_url = "http://www.mockbin.org/"},
{name = "tests-deep-path", request_path = "/hello/world", strip_request_path = true, upstream_url = "http://mockbin.com"},
{name = "tests-deep-path-two", request_path = "/hello/world/wot", strip_request_path = true, upstream_url = "http://httpbin.org"}
{name = "tests-deep-path-two", request_path = "/hello/world/wot", strip_request_path = true, upstream_url = "http://httpbin.org"},
{name = "tests-request_path-resolver2", upstream_url = "http://mockbin.com", request_path = "/headers"}
},
plugin = {
{name = "key-auth", config = {key_names = {"apikey"} }, __api = 2}
Expand All @@ -63,8 +64,10 @@ describe("Resolver", function()
local response, status, headers = http_client.get(spec_helper.STUB_GET_URL, nil, {host = "foo.com"})
assert.equal(404, status)
assert.equal('{"request_path":"\\/request","message":"API not found with these values","request_host":["foo.com"]}\n', response)
assert.falsy(headers[constants.HEADERS.PROXY_LATENCY])
assert.falsy(headers[constants.HEADERS.UPSTREAM_LATENCY])
assert.falsy(headers[constants.HEADERS.PROXY_LATENCY:lower()])
assert.falsy(headers[constants.HEADERS.UPSTREAM_LATENCY:lower()])
assert.falsy(headers[constants.HEADERS.FORWARDED_HOST:lower()])
assert.falsy(headers[constants.HEADERS.FORWARDED_PREFIX:lower()])
end)
end)

Expand Down Expand Up @@ -114,8 +117,12 @@ describe("Resolver", function()
describe("Existing API", function()
describe("By Host", function()
it("should proxy when the API is in Kong", function()
local _, status = http_client.get(STUB_GET_URL, nil, {host = "mockbin.com"})
local response, status = http_client.get(STUB_GET_URL, nil, {host = "mockbin.com"})
assert.equal(200, status)

local body = cjson.decode(response)
assert.equal("mockbin.com", body.headers[constants.HEADERS.FORWARDED_HOST:lower()])
assert.falsy(body.headers[constants.HEADERS.FORWARDED_PREFIX:lower()])
end)
it("should proxy when the Host header is not trimmed", function()
local _, status = http_client.get(STUB_GET_URL, nil, {host = " mockbin.com "})
Expand All @@ -126,8 +133,12 @@ describe("Resolver", function()
assert.equal(200, status)
end)
it("should proxy when the Host header contains a port", function()
local _, status = http_client.get(STUB_GET_URL, nil, {host = "mockbin.com:80"})
local response, status = http_client.get(STUB_GET_URL, nil, {host = "mockbin.com:80"})
assert.equal(200, status)

local body = cjson.decode(response)
assert.equal("mockbin.com", body.headers[constants.HEADERS.FORWARDED_HOST:lower()])
assert.falsy(body.headers[constants.HEADERS.FORWARDED_PREFIX:lower()])
end)
describe("with wildcard subdomain", function()
it("should proxy when the request_host is a wildcard subdomain", function()
Expand All @@ -150,6 +161,25 @@ describe("Resolver", function()

local _, status = http_client.get(spec_helper.PROXY_URL.."/mockbin")
assert.equal(200, status)


local response, status = http_client.get(spec_helper.PROXY_URL.."/mockbin/request")
assert.equal(200, status)

local body = cjson.decode(response)
assert.equal("/mockbin", body.headers[constants.HEADERS.FORWARDED_PREFIX:lower()])
assert.falsy(body.headers[constants.HEADERS.FORWARDED_HOST:lower()])

-- There should be no X-Forwarded-Prefix if no prefix is being stripped
local response, status = http_client.get(spec_helper.PROXY_URL.."/headers")
assert.equal(200, status)
local body = cjson.decode(response)
assert.falsy(body.headers[constants.HEADERS.FORWARDED_HOST:lower()])
for _, v in ipairs(body.headers) do
if v.name == constants.HEADERS.FORWARDED_PREFIX:lower() then
error(constants.HEADERS.FORWARDED_PREFIX.." should not be set")
end
end
end)
it("should not proxy when the request_path does not match the start of the request_uri", function()
local response, status = http_client.get(spec_helper.PROXY_URL.."/somerequest_path/status/200")
Expand All @@ -161,6 +191,13 @@ describe("Resolver", function()
it("should proxy when the request_path has a deep level", function()
local _, status = http_client.get(spec_helper.PROXY_URL.."/deep/request_path/status/200")
assert.equal(200, status)

local response, status = http_client.get(spec_helper.PROXY_URL.."/deep/request_path/request")
assert.equal(200, status)

local body = cjson.decode(response)
assert.equal("/deep/request_path", body.headers[constants.HEADERS.FORWARDED_PREFIX:lower()])
assert.falsy(body.headers[constants.HEADERS.FORWARDED_HOST:lower()])
end)
it("should not care about querystring parameters", function()
local _, status = http_client.get(spec_helper.PROXY_URL.."/mockbin?foo=bar")
Expand Down Expand Up @@ -277,27 +314,27 @@ describe("Resolver", function()
it("should leave percent-encoded values in URI untouched", function()
local response, status = http_client.get(spec_helper.STUB_GET_URL.."/hello%2Fworld", {}, {host = "mockbin-uri.com"})
assert.equal(200, status)
assert.equal("http://mockbin.org/request/hello%2fworld", cjson.decode(response).url)
assert.equal("http://mockbin-uri.com/request/hello%2fworld", cjson.decode(response).url)
end)
it("should leave untouched percent-encoded values in querystring", function()
local response, status = http_client.get(spec_helper.STUB_GET_URL, {foo = "abc%7Cdef%2c%20world"}, {host = "mockbin-uri.com"})
assert.equal(200, status)
assert.equal("http://mockbin.org/request?foo=abc%7cdef%2c%20world", cjson.decode(response).url)
assert.equal("http://mockbin-uri.com/request?foo=abc%7cdef%2c%20world", cjson.decode(response).url)
end)
it("should leave untouched percent-encoded keys in querystring", function()
local response, status = http_client.get(spec_helper.STUB_GET_URL, {["hello%20world"] = "foo"}, {host = "mockbin-uri.com"})
assert.equal(200, status)
assert.equal("http://mockbin.org/request?hello%20world=foo", cjson.decode(response).url)
assert.equal("http://mockbin-uri.com/request?hello%20world=foo", cjson.decode(response).url)
end)
it("should percent-encoded keys in querystring", function()
local response, status = http_client.get(spec_helper.STUB_GET_URL, {["hello world"] = "foo"}, {host = "mockbin-uri.com"})
assert.equal(200, status)
assert.equal("http://mockbin.org/request?hello%20world=foo", cjson.decode(response).url)
assert.equal("http://mockbin-uri.com/request?hello%20world=foo", cjson.decode(response).url)
end)
it("should percent-encoded keys in querystring", function()
local response, status = http_client.get(spec_helper.STUB_GET_URL, {foo = "abc|def, world"}, {host = "mockbin-uri.com"})
assert.equal(200, status)
assert.equal("http://mockbin.org/request?foo=abc%7cdef%2c%20world", cjson.decode(response).url)
assert.equal("http://mockbin-uri.com/request?foo=abc%7cdef%2c%20world", cjson.decode(response).url)
end)
end)
end)