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(core): support inbound and outbound Via header #12733

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 6 additions & 0 deletions changelog/unreleased/kong/feat-via.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
message: |
Append gateway info to upstream `Via` header like `1.1 kong/3.8.0`, and optionally to
response `Via` header if it is present in the `headers` config of "kong.conf", like `2 kong/3.8.0`,
according to `RFC7230` and `RFC9110`.
type: feature
scope: Core
6 changes: 4 additions & 2 deletions kong/plugins/aws-lambda/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ local meta = require "kong.meta"
local constants = require "kong.constants"
local aws_config = require "resty.aws.config" -- reads environment variables, thus specified here
local VIA_HEADER = constants.HEADERS.VIA
local VIA_HEADER_VALUE = meta._NAME .. "/" .. meta._VERSION
local server_tokens = meta._SERVER_TOKENS

local request_util = require "kong.plugins.aws-lambda.request-util"
local build_request_payload = request_util.build_request_payload
Expand Down Expand Up @@ -238,7 +238,9 @@ function AWSLambdaHandler:access(conf)
headers = kong.table.merge(headers) -- create a copy of headers

if kong.configuration.enabled_headers[VIA_HEADER] then
headers[VIA_HEADER] = VIA_HEADER_VALUE
local outbound_via = (ngx_var.http2 and "2 " or "1.1 ") .. server_tokens
headers[VIA_HEADER] = headers[VIA_HEADER] and headers[VIA_HEADER] .. ", " .. outbound_via
or outbound_via
end

-- TODO: remove this in the next major release
Expand Down
13 changes: 8 additions & 5 deletions kong/plugins/azure-functions/handler.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
local constants = require "kong.constants"
local meta = require "kong.meta"
local http = require "resty.http"
local kong_meta = require "kong.meta"

Expand All @@ -9,7 +8,9 @@ local fmt = string.format
local byte = string.byte
local match = string.match
local var = ngx.var
local server_header = meta._SERVER_TOKENS

local server_tokens = kong_meta._SERVER_TOKENS
local VIA_HEADER = constants.HEADERS.VIA


local SLASH = byte("/")
Expand Down Expand Up @@ -77,9 +78,11 @@ function azure:access(conf)
response_headers["Transfer-Encoding"] = nil
end

if kong.configuration.enabled_headers[constants.HEADERS.VIA] then
response_headers[constants.HEADERS.VIA] = server_header
end
if kong.configuration.enabled_headers[VIA_HEADER] then
local outbound_via = (var.http2 and "2 " or "1.1 ") .. server_tokens
response_headers[VIA_HEADER] = response_headers[VIA_HEADER] and response_headers[VIA_HEADER] .. ", " .. outbound_via
or outbound_via
end

return kong.response.exit(res.status, res.body, response_headers)
end
Expand Down
38 changes: 37 additions & 1 deletion kong/runloop/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ local gsub = string.gsub
local find = string.find
local lower = string.lower
local fmt = string.format

local ngx = ngx
local var = ngx.var
local log = ngx.log
Expand Down Expand Up @@ -71,6 +72,9 @@ local ROUTER_CACHE = lrucache.new(ROUTER_CACHE_SIZE)
local ROUTER_CACHE_NEG = lrucache.new(ROUTER_CACHE_SIZE)


local DEFAULT_PROXY_HTTP_VERSION = "1.1"
chronolaw marked this conversation as resolved.
Show resolved Hide resolved


local NOOP = function() end


Expand Down Expand Up @@ -1288,6 +1292,14 @@ return {
var.upstream_x_forwarded_path = forwarded_path
var.upstream_x_forwarded_prefix = forwarded_prefix

do
local req_via = get_header(constants.HEADERS.VIA, ctx)
local kong_inbound_via = protocol_version and protocol_version .. " " .. SERVER_HEADER
or SERVER_HEADER
var.upstream_via = req_via and req_via .. ", " .. kong_inbound_via
or kong_inbound_via
end

-- At this point, the router and `balancer_setup_stage1` have been
-- executed; detect requests that need to be redirected from `proxy_pass`
-- to `grpc_pass`. After redirection, this function will return early
Expand Down Expand Up @@ -1477,7 +1489,31 @@ return {
end

if enabled_headers[headers.VIA] then
outsinre marked this conversation as resolved.
Show resolved Hide resolved
header[headers.VIA] = SERVER_HEADER
-- Kong does not support injected directives like 'nginx_location_proxy_http_version',
-- so we skip checking them.

local proxy_http_version

local upstream_scheme = var.upstream_scheme
if upstream_scheme == "grpc" or upstream_scheme == "grpcs" then
proxy_http_version = "2"
end
if not proxy_http_version then
proxy_http_version = ctx.proxy_http_version or
kong.configuration.proxy_http_version or
DEFAULT_PROXY_HTTP_VERSION
end

local kong_outbound_via = proxy_http_version .. " " .. SERVER_HEADER
local resp_via = var["upstream_http_"..lower(headers.VIA)]
outsinre marked this conversation as resolved.
Show resolved Hide resolved
header[headers.VIA] = resp_via and resp_via .. ", " .. kong_outbound_via
or kong_outbound_via
end

-- If upstream does not provide the 'Server' header, an 'openresty' header
-- would be inserted by default. We override it with the Kong server header.
if not header[headers.SERVER] and enabled_headers[headers.SERVER] then
header[headers.SERVER] = SERVER_HEADER
end

else
Expand Down
7 changes: 7 additions & 0 deletions kong/templates/nginx_kong.lua
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ server {

set $ctx_ref '';
set $upstream_te '';
set $upstream_via '';
set $upstream_host '';
set $upstream_upgrade '';
set $upstream_connection '';
Expand All @@ -178,6 +179,7 @@ server {
> end

proxy_set_header TE $upstream_te;
proxy_set_header Via $upstream_via;
proxy_set_header Host $upstream_host;
proxy_set_header Upgrade $upstream_upgrade;
proxy_set_header Connection $upstream_connection;
Expand Down Expand Up @@ -212,6 +214,7 @@ server {
proxy_request_buffering off;

proxy_set_header TE $upstream_te;
proxy_set_header Via $upstream_via;
proxy_set_header Host $upstream_host;
proxy_set_header Upgrade $upstream_upgrade;
proxy_set_header Connection $upstream_connection;
Expand Down Expand Up @@ -246,6 +249,7 @@ server {
proxy_request_buffering off;

proxy_set_header TE $upstream_te;
proxy_set_header Via $upstream_via;
proxy_set_header Host $upstream_host;
proxy_set_header Upgrade $upstream_upgrade;
proxy_set_header Connection $upstream_connection;
Expand Down Expand Up @@ -280,6 +284,7 @@ server {
proxy_request_buffering on;

proxy_set_header TE $upstream_te;
proxy_set_header Via $upstream_via;
proxy_set_header Host $upstream_host;
proxy_set_header Upgrade $upstream_upgrade;
proxy_set_header Connection $upstream_connection;
Expand Down Expand Up @@ -310,6 +315,7 @@ server {
set $kong_proxy_mode 'grpc';

grpc_set_header TE $upstream_te;
grpc_set_header Via $upstream_via;
grpc_set_header X-Forwarded-For $upstream_x_forwarded_for;
grpc_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
grpc_set_header X-Forwarded-Host $upstream_x_forwarded_host;
Expand Down Expand Up @@ -353,6 +359,7 @@ server {

proxy_http_version 1.1;
proxy_set_header TE $upstream_te;
proxy_set_header Via $upstream_via;
proxy_set_header Host $upstream_host;
proxy_set_header Upgrade $upstream_upgrade;
proxy_set_header Connection $upstream_connection;
Expand Down
2 changes: 1 addition & 1 deletion spec/02-integration/05-proxy/09-websockets_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ for _, strategy in helpers.each_strategy() do
assert.equal(true, string.find(header, "Upgrade: websocket") ~= nil, 1, true)

if is_kong then
assert.equal(true, string.find(header, "Via: kong") ~= nil, 1, true)
assert.equal(true, string.find(header, "Via: 1.1 kong") ~= nil, 1, true)
end
end

Expand Down
16 changes: 8 additions & 8 deletions spec/02-integration/05-proxy/14-server_tokens_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ local uuid = require("kong.tools.uuid").uuid


local default_server_header = meta._SERVER_TOKENS

local default_via_value = "1.1 " .. default_server_header

for _, strategy in helpers.each_strategy() do
describe("headers [#" .. strategy .. "]", function()
Expand Down Expand Up @@ -95,7 +95,7 @@ describe("headers [#" .. strategy .. "]", function()

assert.res_status(200, res)
assert.not_equal(default_server_header, res.headers["server"])
assert.equal(default_server_header, res.headers["via"])
assert.equal(default_via_value, res.headers["via"])
end)

it("should return Kong 'Server' header but not the Kong 'Via' header when no API matched (no proxy)", function()
Expand Down Expand Up @@ -146,8 +146,8 @@ describe("headers [#" .. strategy .. "]", function()
})

assert.res_status(200, res)
assert.equal(default_server_header, res.headers["via"])
assert.not_equal(default_server_header, res.headers["server"])
assert.equal(default_via_value, res.headers["via"])
assert.not_equal(default_via_value, res.headers["server"])
end)

it("should not return Kong 'Via' header or Kong 'Via' header when no API matched (no proxy)", function()
Expand Down Expand Up @@ -223,7 +223,7 @@ describe("headers [#" .. strategy .. "]", function()

assert.res_status(200, res)
assert.not_equal(default_server_header, res.headers["server"])
assert.equal(default_server_header, res.headers["via"])
assert.equal(default_via_value, res.headers["via"])
end)

it("should return Kong 'Server' header but not the Kong 'Via' header when no API matched (no proxy)", function()
Expand Down Expand Up @@ -746,7 +746,7 @@ describe("headers [#" .. strategy .. "]", function()

assert.res_status(200, res)
assert.not_equal(default_server_header, res.headers["server"])
assert.equal(default_server_header, res.headers["via"])
assert.equal(default_via_value, res.headers["via"])
assert.is_not_nil(res.headers[constants.HEADERS.PROXY_LATENCY])
assert.is_nil(res.headers[constants.HEADERS.RESPONSE_LATENCY])
end)
Expand Down Expand Up @@ -807,7 +807,7 @@ describe("headers [#" .. strategy .. "]", function()

assert.res_status(200, res)
assert.not_equal(default_server_header, res.headers["server"])
assert.equal(default_server_header, res.headers["via"])
assert.equal(default_via_value, res.headers["via"])
assert.is_not_nil(res.headers[constants.HEADERS.PROXY_LATENCY])
assert.is_nil(res.headers[constants.HEADERS.RESPONSE_LATENCY])
end)
Expand Down Expand Up @@ -885,7 +885,7 @@ describe("headers [#" .. strategy .. "]", function()

assert.res_status(200, res)
assert.not_equal(default_server_header, res.headers["server"])
assert.equal(default_server_header, res.headers["via"])
assert.equal(default_via_value, res.headers["via"])
assert.is_not_nil(res.headers[constants.HEADERS.PROXY_LATENCY])
assert.is_nil(res.headers[constants.HEADERS.RESPONSE_LATENCY])
end)
Expand Down
1 change: 1 addition & 0 deletions spec/02-integration/05-proxy/30-max-args_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ local function validate_proxy(params, body, truncated)
request_headers["x-forwarded-prefix"] = nil
request_headers["x-forwarded-proto"] = nil
request_headers["x-real-ip"] = nil
request_headers["via"] = nil

assert.same(params.headers, request_headers)
assert.same(params.query, body.uri_args)
Expand Down
Loading
Loading