Skip to content

Commit

Permalink
feat(proxy): Allow to remove the proxy cache headers (#10445)
Browse files Browse the repository at this point in the history
The following headers:
* X-Cache-Status
* X-Cache-Key
* Age

are now set only if the header kong-debug is set to 1
And they are removed from the cache value

Keep previous behavior with default configuration.
Debug header allows to get all info, each header has a configuration field to be or not into the response
  • Loading branch information
utix authored Aug 8, 2023
1 parent e206d00 commit 5e09745
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 505 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@
- Tracing: tracing_sampling_rate defaults to 0.01 (trace one of every 100 requests) instead of the previous 1
(trace all requests). Tracing all requests is inappropriate for most production systems
[#10774](https://github.com/Kong/kong/pull/10774)
- **Proxy Cache**: Add option to remove the proxy cache headers from the response
[#10445](https://github.com/Kong/kong/pull/10445)

### Additions

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 @@ -92,5 +92,8 @@ return {
rate_limiting = {
"sync_rate",
},
proxy_cache = {
"response_headers",
},
},
}
47 changes: 33 additions & 14 deletions kong/plugins/proxy-cache/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ local function overwritable_header(header)
and not ngx_re_match(n_header, "ratelimit-remaining")
end

local function set_header(conf, header, value)
if ngx.var.http_kong_debug or conf.response_headers[header] then
kong.response.set_header(header, value)
end
end

local function reset_res_header(res)
res.headers["Age"] = nil
res.headers["X-Cache-Status"] = nil
res.headers["X-Cache-Key"] = nil
end

local function set_res_header(res, header, value, conf)
if ngx.var.http_kong_debug or conf.response_headers[header] then
res.headers[header] = value
end
end

local function parse_directive_header(h)
if not h then
Expand Down Expand Up @@ -219,12 +236,11 @@ end


-- indicate that we should attempt to cache the response to this request
local function signal_cache_req(ctx, cache_key, cache_status)
local function signal_cache_req(ctx, conf, cache_key, cache_status)
ctx.proxy_cache = {
cache_key = cache_key,
}

kong.response.set_header("X-Cache-Status", cache_status or "Miss")
set_header(conf, "X-Cache-Status", cache_status or "Miss")
end


Expand Down Expand Up @@ -280,7 +296,7 @@ function ProxyCacheHandler:access(conf)

-- if we know this request isnt cacheable, bail out
if not cacheable_request(conf, cc) then
kong.response.set_header("X-Cache-Status", "Bypass")
set_header(conf, "X-Cache-Status", "Bypass")
return
end

Expand All @@ -305,7 +321,7 @@ function ProxyCacheHandler:access(conf)
return
end

kong.response.set_header("X-Cache-Key", cache_key)
set_header(conf, "X-Cache-Key", cache_key)

-- try to fetch the cached object from the computed cache key
local strategy = require(STRATEGY_PATH)({
Expand All @@ -328,7 +344,7 @@ function ProxyCacheHandler:access(conf)
-- this request is cacheable but wasn't found in the data store
-- make a note that we should store it in cache later,
-- and pass the request upstream
return signal_cache_req(ctx, cache_key)
return signal_cache_req(ctx, conf, cache_key)

elseif err then
kong.log.err(err)
Expand All @@ -338,29 +354,29 @@ function ProxyCacheHandler:access(conf)
if res.version ~= CACHE_VERSION then
kong.log.notice("cache format mismatch, purging ", cache_key)
strategy:purge(cache_key)
return signal_cache_req(ctx, cache_key, "Bypass")
return signal_cache_req(ctx, conf, cache_key, "Bypass")
end

-- figure out if the client will accept our cache value
if conf.cache_control then
if cc["max-age"] and time() - res.timestamp > cc["max-age"] then
return signal_cache_req(ctx, cache_key, "Refresh")
return signal_cache_req(ctx, conf, cache_key, "Refresh")
end

if cc["max-stale"] and time() - res.timestamp - res.ttl > cc["max-stale"]
then
return signal_cache_req(ctx, cache_key, "Refresh")
return signal_cache_req(ctx, conf, cache_key, "Refresh")
end

if cc["min-fresh"] and res.ttl - (time() - res.timestamp) < cc["min-fresh"]
then
return signal_cache_req(ctx, cache_key, "Refresh")
return signal_cache_req(ctx, conf, cache_key, "Refresh")
end

else
-- don't serve stale data; res may be stored for up to `conf.storage_ttl` secs
if time() - res.timestamp > conf.cache_ttl then
return signal_cache_req(ctx, cache_key, "Refresh")
return signal_cache_req(ctx, conf, cache_key, "Refresh")
end
end

Expand All @@ -385,8 +401,11 @@ function ProxyCacheHandler:access(conf)
end
end

res.headers["Age"] = floor(time() - res.timestamp)
res.headers["X-Cache-Status"] = "Hit"

reset_res_header(res)
set_res_header(res, "Age", floor(time() - res.timestamp), conf)
set_res_header(res, "X-Cache-Status", "Hit", conf)
set_res_header(res, "X-Cache-Key", cache_key, conf)

return kong.response.exit(res.status, res.body, res.headers)
end
Expand All @@ -411,7 +430,7 @@ function ProxyCacheHandler:header_filter(conf)
proxy_cache.res_ttl = conf.cache_control and resource_ttl(cc) or conf.cache_ttl

else
kong.response.set_header("X-Cache-Status", "Bypass")
set_header(conf, "X-Cache-Status", "Bypass")
ctx.proxy_cache = nil
end

Expand Down
10 changes: 10 additions & 0 deletions kong/plugins/proxy-cache/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ return {
{ vary_headers = { description = "Relevant headers considered for the cache key. If undefined, none of the headers are taken into consideration.", type = "array",
elements = { type = "string" },
}},
{ response_headers = {
type = "record",
fields = {
{ age = {type = "boolean", default = true} },
{ ["X-Cache-Status"] = {type = "boolean", default = true} },
{ ["X-Cache-Key"] = {type = "boolean", default = true} },
},
}},


},
}
},
Expand Down
Loading

1 comment on commit 5e09745

@khcp-gha-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bazel Build

Docker image available kong/kong:5e09745add686a32359201903d12f62138d51489
Artifacts available https://github.com/Kong/kong/actions/runs/5795164055

Please sign in to comment.