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

feat(proxy-cache): add ignore_uri_case to configuring cache-key uri to be handled as lowercase #10453

Merged
merged 12 commits into from
Mar 15, 2023
Merged
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@

- **ACME**: acme plugin now supports configuring an `account_key` in `keys` and `key_sets`
[#9746](https://github.com/Kong/kong/pull/9746)
- **Proxy-Cache**: add `ignore_uri_case` to configuring cache-key uri to be handled as lowercase
[#10453](https://github.com/Kong/kong/pull/10453)

### Fixes

Expand Down
3 changes: 3 additions & 0 deletions kong/clustering/compat/removed_fields.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ return {
[3003000000] = {
acme = {
"account_key",
},
proxy_cache = {
"ignore_uri_case",
}
},
}
6 changes: 6 additions & 0 deletions kong/plugins/proxy-cache/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,12 @@ function ProxyCacheHandler:access(conf)
local consumer = kong.client.get_consumer()
local route = kong.router.get_route()
local uri = ngx_re_sub(ngx.var.request, "\\?.*", "", "oj")

-- if we want the cache-key uri only to be lowercase
if conf.ignore_uri_case then
uri = lower(uri)
end

local cache_key, err = cache_key.build_cache_key(consumer and consumer.id,
route and route.id,
kong.request.get_method(),
Expand Down
5 changes: 5 additions & 0 deletions kong/plugins/proxy-cache/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ return {
default = false,
required = true,
}},
{ ignore_uri_case = {
type = "boolean",
default = false,
required = false,
}},
{ storage_ttl = {
type = "integer",
}},
Expand Down
114 changes: 104 additions & 10 deletions spec/03-plugins/31-proxy-cache/02-access_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,27 @@ do
local route14 = assert(bp.routes:insert {
hosts = { "route-14.com" },
})
local route15 = assert(bp.routes:insert({
local route15 = assert(bp.routes:insert {
hosts = { "route-15.com" },
}))
local route16 = assert(bp.routes:insert({
})
local route16 = assert(bp.routes:insert {
hosts = { "route-16.com" },
}))
local route17 = assert(bp.routes:insert({
})
local route17 = assert(bp.routes:insert {
hosts = { "route-17.com" },
}))
local route18 = assert(bp.routes:insert({
})
local route18 = assert(bp.routes:insert {
hosts = { "route-18.com" },
}))
local route19 = assert(bp.routes:insert({
})
local route19 = assert(bp.routes:insert {
hosts = { "route-19.com" },
}))
})
local route20 = assert(bp.routes:insert {
hosts = { "route-20.com" },
})
local route21 = assert(bp.routes:insert {
hosts = { "route-21.com" },
})


local consumer1 = assert(bp.consumers:insert {
Expand Down Expand Up @@ -282,6 +288,30 @@ do
},
})

assert(bp.plugins:insert {
name = "proxy-cache",
route = { id = route20.id },
config = {
strategy = policy,
response_code = {404},
ignore_uri_case = true,
content_type = { "text/plain", "application/json" },
[policy] = policy_config,
},
})

assert(bp.plugins:insert {
name = "proxy-cache",
route = { id = route21.id },
config = {
strategy = policy,
response_code = {404},
ignore_uri_case = false,
content_type = { "text/plain", "application/json" },
[policy] = policy_config,
},
})

assert(helpers.start_kong({
plugins = "bundled",
nginx_conf = "spec/fixtures/custom_nginx.template",
Expand Down Expand Up @@ -1346,5 +1376,69 @@ do
assert.same("Bypass", res.headers["X-Cache-Status"])
end)
end)

it("ignore uri case in cache_key", function()
tobiasehlert marked this conversation as resolved.
Show resolved Hide resolved
local res = assert(client:send {
method = "GET",
path = "/ignore-case/kong",
headers = {
host = "route-20.com",
},
})

local body1 = assert.res_status(404, res)
assert.same("Miss", res.headers["X-Cache-Status"])

local cache_key1 = res.headers["X-Cache-Key"]
assert.matches("^[%w%d]+$", cache_key1)
assert.equals(64, #cache_key1)

local res = client:send {
method = "GET",
path = "/ignore-case/KONG",
headers = {
host = "route-20.com",
},
}

local body2 = assert.res_status(404, res)
assert.same("Hit", res.headers["X-Cache-Status"])
local cache_key2 = res.headers["X-Cache-Key"]
assert.same(cache_key1, cache_key2)

assert.same(body1, body2)
end)

it("acknowledge uri case in cache_key", function()
local res = assert(client:send {
method = "GET",
path = "/acknowledge-case/kong",
headers = {
host = "route-21.com",
},
})

assert.res_status(404, res)
local x_cache_status = assert.response(res).has_header("X-Cache-Status")
assert.same("Miss", x_cache_status)

local cache_key1 = res.headers["X-Cache-Key"]
assert.matches("^[%w%d]+$", cache_key1)
assert.equals(64, #cache_key1)

res = assert(client:send {
method = "GET",
path = "/acknowledge-case/KONG",
headers = {
host = "route-21.com",
},
})

x_cache_status = assert.response(res).has_header("X-Cache-Status")
local cache_key2 = assert.response(res).has_header("X-Cache-Key")
assert.same("Miss", x_cache_status)
assert.not_same(cache_key1, cache_key2)
end)

end)
end