From ca4ec9997d1e2c75761a3c4860aff3c52bd993f2 Mon Sep 17 00:00:00 2001 From: Chrono Date: Wed, 27 Dec 2023 16:57:54 +0800 Subject: [PATCH] perf(router): unify cache key and context generation in expressions router (#12127) Cache key and context generation are closely related on field present inside configured expressions. It is advantageous to unify the logic for generating them to: 1. Improve cache hit rate, so that only fields referenced inside expressions participates in cache key generation. This is particularly important since we plan on adding more match fields into expressions in the future 2. Improve performance, allows field value to be cached and reused between cache key and context generation 3. Reduced code duplication KAG-3032 --- kong-3.4.3-0.rockspec | 14 +- kong/router/atc.lua | 401 +++++------------- kong/router/fields.lua | 360 ++++++++++++++++ spec/01-unit/08-router_spec.lua | 14 + .../05-proxy/02-router_spec.lua | 8 +- .../05-proxy/19-grpc_proxy_spec.lua | 10 +- 6 files changed, 486 insertions(+), 321 deletions(-) create mode 100644 kong/router/fields.lua diff --git a/kong-3.4.3-0.rockspec b/kong-3.4.3-0.rockspec index 7f71fdfee5d..94678811531 100644 --- a/kong-3.4.3-0.rockspec +++ b/kong-3.4.3-0.rockspec @@ -50,12 +50,6 @@ build = { ["kong.cache"] = "kong/cache/init.lua", ["kong.cache.warmup"] = "kong/cache/warmup.lua", ["kong.global"] = "kong/global.lua", - ["kong.router"] = "kong/router/init.lua", - ["kong.router.traditional"] = "kong/router/traditional.lua", - ["kong.router.compat"] = "kong/router/compat.lua", - ["kong.router.expressions"] = "kong/router/expressions.lua", - ["kong.router.atc"] = "kong/router/atc.lua", - ["kong.router.utils"] = "kong/router/utils.lua", ["kong.reports"] = "kong/reports.lua", ["kong.constants"] = "kong/constants.lua", ["kong.concurrency"] = "kong/concurrency.lua", @@ -64,6 +58,14 @@ build = { ["kong.error_handlers"] = "kong/error_handlers.lua", ["kong.hooks"] = "kong/hooks.lua", + ["kong.router"] = "kong/router/init.lua", + ["kong.router.traditional"] = "kong/router/traditional.lua", + ["kong.router.compat"] = "kong/router/compat.lua", + ["kong.router.expressions"] = "kong/router/expressions.lua", + ["kong.router.atc"] = "kong/router/atc.lua", + ["kong.router.fields"] = "kong/router/fields.lua", + ["kong.router.utils"] = "kong/router/utils.lua", + ["kong.conf_loader"] = "kong/conf_loader/init.lua", ["kong.conf_loader.listeners"] = "kong/conf_loader/listeners.lua", diff --git a/kong/router/atc.lua b/kong/router/atc.lua index a0e2ebd2c73..568272979a1 100644 --- a/kong/router/atc.lua +++ b/kong/router/atc.lua @@ -5,10 +5,9 @@ local _MT = { __index = _M, } local buffer = require("string.buffer") local schema = require("resty.router.schema") local router = require("resty.router.router") -local context = require("resty.router.context") local lrucache = require("resty.lrucache") -local server_name = require("ngx.ssl").server_name local tb_new = require("table.new") +local fields = require("kong.router.fields") local utils = require("kong.router.utils") local yield = require("kong.tools.utils").yield @@ -29,15 +28,14 @@ local header = ngx.header local var = ngx.var local ngx_log = ngx.log local get_phase = ngx.get_phase -local get_method = ngx.req.get_method -local get_headers = ngx.req.get_headers -local get_uri_args = ngx.req.get_uri_args local ngx_ERR = ngx.ERR local check_select_params = utils.check_select_params local get_service_info = utils.get_service_info local route_match_stat = utils.route_match_stat +local get_cache_key = fields.get_cache_key +local get_atc_context = fields.get_atc_context local DEFAULT_MATCH_LRUCACHE_SIZE = utils.DEFAULT_MATCH_LRUCACHE_SIZE @@ -184,37 +182,6 @@ local function add_atc_matcher(inst, route, route_id, end -local function categorize_fields(fields) - - if not is_http then - return fields, nil, nil - end - - local basic = {} - local headers = {} - local queries = {} - - -- 13 bytes, same len for "http.queries." - local PREFIX_LEN = 13 -- #"http.headers." - - for _, field in ipairs(fields) do - local prefix = field:sub(1, PREFIX_LEN) - - if prefix == "http.headers." then - headers[field:sub(PREFIX_LEN + 1)] = field - - elseif prefix == "http.queries." then - queries[field:sub(PREFIX_LEN + 1)] = field - - else - table.insert(basic, field) - end - end - - return basic, headers, queries -end - - local function new_from_scratch(routes, get_exp_and_priority) local phase = get_phase() @@ -255,7 +222,7 @@ local function new_from_scratch(routes, get_exp_and_priority) yield(true, phase) end - local fields, header_fields, query_fields = categorize_fields(inst:get_fields()) + local fields = inst:get_fields() return setmetatable({ schema = CACHED_SCHEMA, @@ -263,8 +230,6 @@ local function new_from_scratch(routes, get_exp_and_priority) routes = routes_t, services = services_t, fields = fields, - header_fields = header_fields, - query_fields = query_fields, updated_at = new_updated_at, rebuilding = false, }, _MT) @@ -348,11 +313,9 @@ local function new_from_previous(routes, get_exp_and_priority, old_router) yield(true, phase) end - local fields, header_fields, query_fields = categorize_fields(inst:get_fields()) + local fields = inst:get_fields() old_router.fields = fields - old_router.header_fields = header_fields - old_router.query_fields = query_fields old_router.updated_at = new_updated_at old_router.rebuilding = false @@ -427,6 +390,9 @@ do end +local CACHE_PARAMS + + if is_http then @@ -436,115 +402,25 @@ local add_debug_headers = utils.add_debug_headers local get_upstream_uri_v0 = utils.get_upstream_uri_v0 -function _M:select(req_method, req_uri, req_host, req_scheme, - _, _, - _, _, - sni, req_headers, req_queries) +function _M:matching(params) + local req_uri = params.uri + local req_host = params.host - check_select_params(req_method, req_uri, req_host, req_scheme, + check_select_params(params.method, req_uri, req_host, params.scheme, nil, nil, nil, nil, - sni, req_headers, req_queries) - - local c = context.new(self.schema) + params.sni, params.headers, params.queries) local host, port = split_host_port(req_host) - for _, field in ipairs(self.fields) do - if field == "http.method" then - assert(c:add_value(field, req_method)) - - elseif field == "http.path" then - local res, err = c:add_value(field, req_uri) - if not res then - return nil, err - end - - elseif field == "http.host" then - local res, err = c:add_value(field, host) - if not res then - return nil, err - end - - elseif field == "net.port" then - assert(c:add_value(field, port)) - - elseif field == "net.protocol" then - assert(c:add_value(field, req_scheme)) - - elseif field == "tls.sni" then - local res, err = c:add_value(field, sni) - if not res then - return nil, err - end + params.host = host + params.port = port - else -- unknown field - error("unknown router matching schema field: " .. field) + local c, err = get_atc_context(self.schema, self.fields, params) - end -- if field - - end -- for self.fields - - if req_headers then - for h, field in pairs(self.header_fields) do - - local v = req_headers[h] - - if type(v) == "string" then - local res, err = c:add_value(field, v) - if not res then - return nil, err - end - - elseif type(v) == "table" then - for _, v in ipairs(v) do - local res, err = c:add_value(field, v) - if not res then - return nil, err - end - end - end -- if type(v) - - -- if v is nil or others, ignore - - end -- for self.header_fields - end -- req_headers - - if req_queries then - for n, field in pairs(self.query_fields) do - - local v = req_queries[n] - - -- the query parameter has only one value, like /?foo=bar - if type(v) == "string" then - local res, err = c:add_value(field, v) - if not res then - return nil, err - end - - -- the query parameter has no value, like /?foo, - -- get_uri_arg will get a boolean `true` - -- we think it is equivalent to /?foo= - elseif type(v) == "boolean" then - local res, err = c:add_value(field, "") - if not res then - return nil, err - end - - -- multiple values for a single query parameter, like /?foo=bar&foo=baz - elseif type(v) == "table" then - for _, v in ipairs(v) do - local res, err = c:add_value(field, v) - if not res then - return nil, err - end - end - end -- if type(v) - - -- if v is nil or others, ignore - - end -- for self.query_fields - end -- req_queries + if not c then + return nil, err + end local matched = self.router:execute(c) if not matched then @@ -587,98 +463,48 @@ function _M:select(req_method, req_uri, req_host, req_scheme, end -local get_headers_key -local get_queries_key -do - local tb_sort = table.sort - local tb_concat = table.concat - local replace_dashes_lower = require("kong.tools.string").replace_dashes_lower - - local str_buf = buffer.new(64) - - local function get_headers_or_queries_key(values, lower_func) - str_buf:reset() - - -- NOTE: DO NOT yield until str_buf:get() - for name, value in pairs(values) do - if lower_func then - name = lower_func(name) - end - - if type(value) == "table" then - tb_sort(value) - value = tb_concat(value, ", ") - end - - str_buf:putf("|%s=%s", name, value) - end - - return str_buf:get() - end - - get_headers_key = function(headers) - return get_headers_or_queries_key(headers, replace_dashes_lower) - end - - get_queries_key = function(queries) - return get_headers_or_queries_key(queries) - end -end - +-- only for unit-testing +function _M:select(req_method, req_uri, req_host, req_scheme, + _, _, + _, _, + sni, req_headers, req_queries) --- func => get_headers or get_uri_args --- name => "headers" or "queries" --- max_config_option => "lua_max_req_headers" or "lua_max_uri_args" -local function get_http_params(func, name, max_config_option) - local params, err = func() - if err == "truncated" then - local max = kong and kong.configuration and kong.configuration[max_config_option] or 100 - ngx_log(ngx_ERR, - string.format("router: not all request %s were read in order to determine the route " .. - "as the request contains more than %d %s, " .. - "route selection may be inaccurate, " .. - "consider increasing the '%s' configuration value " .. - "(currently at %d)", - name, max, name, max_config_option, max)) - end + local params = { + method = req_method, + uri = req_uri, + host = req_host, + scheme = req_scheme, + sni = sni, + headers = req_headers, + queries = req_queries, + } - return params + return self:matching(params) end function _M:exec(ctx) - local req_method = get_method() local req_uri = ctx and ctx.request_uri or var.request_uri local req_host = var.http_host - local sni = server_name() - local headers, headers_key - if not is_empty_field(self.header_fields) then - headers = get_http_params(get_headers, "headers", "lua_max_req_headers") + req_uri = strip_uri_args(req_uri) - headers["host"] = nil + -- cache key calculation - headers_key = get_headers_key(headers) + if not CACHE_PARAMS then + -- access `kong.configuration.log_level` here + CACHE_PARAMS = require("kong.tools.request_aware_table").new() end - local queries, queries_key - if not is_empty_field(self.query_fields) then - queries = get_http_params(get_uri_args, "queries", "lua_max_uri_args") + CACHE_PARAMS:clear() - queries_key = get_queries_key(queries) - end + CACHE_PARAMS.uri = req_uri + CACHE_PARAMS.host = req_host - req_uri = strip_uri_args(req_uri) + local cache_key = get_cache_key(self.fields, CACHE_PARAMS) -- cache lookup - local cache_key = (req_method or "") .. "|" .. - (req_uri or "") .. "|" .. - (req_host or "") .. "|" .. - (sni or "") .. "|" .. - (headers_key or "") .. "|" .. - (queries_key or "") - local match_t = self.cache:get(cache_key) if not match_t then if self.cache_neg:get(cache_key) then @@ -686,12 +512,10 @@ function _M:exec(ctx) return nil end - local req_scheme = ctx and ctx.scheme or var.scheme + CACHE_PARAMS.scheme = ctx and ctx.scheme or var.scheme local err - match_t, err = self:select(req_method, req_uri, req_host, req_scheme, - nil, nil, nil, nil, - sni, headers, queries) + match_t, err = self:matching(CACHE_PARAMS) if not match_t then if err then ngx_log(ngx_ERR, "router returned an error: ", err, @@ -706,6 +530,11 @@ function _M:exec(ctx) else route_match_stat(ctx, "pos") + + -- preserve_host header logic, modify cache result + if match_t.route.preserve_host then + match_t.upstream_host = req_host + end end -- found a match @@ -718,46 +547,19 @@ end else -- is stream subsystem -function _M:select(_, _, _, scheme, - src_ip, src_port, - dst_ip, dst_port, - sni) - - check_select_params(nil, nil, nil, scheme, - src_ip, src_port, - dst_ip, dst_port, - sni) - - local c = context.new(self.schema) - - for _, field in ipairs(self.fields) do - if field == "net.protocol" then - assert(c:add_value(field, scheme)) - - elseif field == "tls.sni" then - local res, err = c:add_value(field, sni) - if not res then - return nil, err - end - - elseif field == "net.src.ip" then - assert(c:add_value(field, src_ip)) - - elseif field == "net.src.port" then - assert(c:add_value(field, src_port)) - - elseif field == "net.dst.ip" then - assert(c:add_value(field, dst_ip)) - elseif field == "net.dst.port" then - assert(c:add_value(field, dst_port)) +function _M:matching(params) + local sni = params.sni - else -- unknown field - error("unknown router matching schema field: " .. field) - - end -- if field + check_select_params(nil, nil, nil, params.scheme, + params.src_ip, params.src_port, + params.dst_ip, params.dst_port, + sni) - end -- for self.fields + local c, err = get_atc_context(self.schema, self.fields, params) + if not c then + return nil, err + end local matched = self.router:execute(c) if not matched then @@ -787,41 +589,38 @@ function _M:select(_, _, _, scheme, end -function _M:exec(ctx) - local src_ip = var.remote_addr - local dst_ip = var.server_addr +-- only for unit-testing +function _M:select(_, _, _, scheme, + src_ip, src_port, + dst_ip, dst_port, + sni) - local src_port = tonumber(var.remote_port, 10) - local dst_port = tonumber((ctx or ngx.ctx).host_port, 10) or - tonumber(var.server_port, 10) + local params = { + scheme = scheme, + src_ip = src_ip, + src_port = src_port, + dst_ip = dst_ip, + dst_port = dst_port, + sni = sni, + } - -- error value for non-TLS connections ignored intentionally - local sni = server_name() + return self:matching(params) +end - -- fallback to preread SNI if current connection doesn't terminate TLS - if not sni then - sni = var.ssl_preread_server_name - end - local scheme - if var.protocol == "UDP" then - scheme = "udp" - else - scheme = sni and "tls" or "tcp" - end +function _M:exec(ctx) + -- cache key calculation - -- when proxying TLS request in second layer or doing TLS passthrough - -- rewrite the dst_ip, port back to what specified in proxy_protocol - if var.kong_tls_passthrough_block == "1" or var.ssl_protocol then - dst_ip = var.proxy_protocol_server_addr - dst_port = tonumber(var.proxy_protocol_server_port) + if not CACHE_PARAMS then + -- access `kong.configuration.log_level` here + CACHE_PARAMS = require("kong.tools.request_aware_table").new() end - local cache_key = (src_ip or "") .. "|" .. - (src_port or "") .. "|" .. - (dst_ip or "") .. "|" .. - (dst_port or "") .. "|" .. - (sni or "") + CACHE_PARAMS:clear() + + local cache_key = get_cache_key(self.fields, CACHE_PARAMS, ctx) + + -- cache lookup local match_t = self.cache:get(cache_key) if not match_t then @@ -830,11 +629,18 @@ function _M:exec(ctx) return nil end + local scheme + if var.protocol == "UDP" then + scheme = "udp" + + else + scheme = CACHE_PARAMS.sni and "tls" or "tcp" + end + + CACHE_PARAMS.scheme = scheme + local err - match_t, err = self:select(nil, nil, nil, scheme, - src_ip, src_port, - dst_ip, dst_port, - sni) + match_t, err = self:matching(CACHE_PARAMS) if not match_t then if err then ngx_log(ngx_ERR, "router returned an error: ", err) @@ -873,19 +679,8 @@ function _M._set_ngx(mock_ngx) ngx_log = mock_ngx.log end - if type(mock_ngx.req) == "table" then - if mock_ngx.req.get_method then - get_method = mock_ngx.req.get_method - end - - if mock_ngx.req.get_headers then - get_headers = mock_ngx.req.get_headers - end - - if mock_ngx.req.get_uri_args then - get_uri_args = mock_ngx.req.get_uri_args - end - end + -- unit testing + fields._set_ngx(mock_ngx) end diff --git a/kong/router/fields.lua b/kong/router/fields.lua new file mode 100644 index 00000000000..11e2a09fe95 --- /dev/null +++ b/kong/router/fields.lua @@ -0,0 +1,360 @@ +local buffer = require("string.buffer") +local context = require("resty.router.context") + + +local type = type +local ipairs = ipairs +local assert = assert +local tb_sort = table.sort +local tb_concat = table.concat +local replace_dashes_lower = require("kong.tools.string").replace_dashes_lower + + +local var = ngx.var +local get_method = ngx.req.get_method +local get_headers = ngx.req.get_headers +local get_uri_args = ngx.req.get_uri_args +local server_name = require("ngx.ssl").server_name + + +local PREFIX_LEN = 13 -- #"http.headers." +local HTTP_HEADERS_PREFIX = "http.headers." +local HTTP_QUERIES_PREFIX = "http.queries." + + +local FIELDS_FUNCS = { + -- http.* + + ["http.method"] = + function(params) + if not params.method then + params.method = get_method() + end + + return params.method + end, + + ["http.path"] = + function(params) + return params.uri + end, + + ["http.host"] = + function(params) + return params.host + end, + + -- net.* + + ["net.src.ip"] = + function(params) + if not params.src_ip then + params.src_ip = var.remote_addr + end + + return params.src_ip + end, + + ["net.src.port"] = + function(params) + if not params.src_port then + params.src_port = tonumber(var.remote_port, 10) + end + + return params.src_port + end, + + -- below are atc context only + + ["net.protocol"] = + function(params) + return params.scheme + end, + + ["net.port"] = + function(params) + return params.port + end, +} + + +local is_http = ngx.config.subsystem == "http" + + +if is_http then + -- tls.* + + FIELDS_FUNCS["tls.sni"] = + function(params) + if not params.sni then + params.sni = server_name() + end + + return params.sni + end + + -- net.* + + FIELDS_FUNCS["net.dst.ip"] = + function(params) + if not params.dst_ip then + params.dst_ip = var.server_addr + end + + return params.dst_ip + end + + FIELDS_FUNCS["net.dst.port"] = + function(params, ctx) + if not params.dst_port then + params.dst_port = tonumber((ctx or ngx.ctx).host_port, 10) or + tonumber(var.server_port, 10) + end + + return params.dst_port + end + +else -- stream + + -- tls.* + -- error value for non-TLS connections ignored intentionally + -- fallback to preread SNI if current connection doesn't terminate TLS + + FIELDS_FUNCS["tls.sni"] = + function(params) + if not params.sni then + params.sni = server_name() or var.ssl_preread_server_name + end + + return params.sni + end + + -- net.* + -- when proxying TLS request in second layer or doing TLS passthrough + -- rewrite the dst_ip, port back to what specified in proxy_protocol + + FIELDS_FUNCS["net.dst.ip"] = + function(params) + if not params.dst_ip then + if var.kong_tls_passthrough_block == "1" or var.ssl_protocol then + params.dst_ip = var.proxy_protocol_server_addr + + else + params.dst_ip = var.server_addr + end + end + + return params.dst_ip + end + + FIELDS_FUNCS["net.dst.port"] = + function(params, ctx) + if not params.dst_port then + if var.kong_tls_passthrough_block == "1" or var.ssl_protocol then + params.dst_port = tonumber(var.proxy_protocol_server_port) + + else + params.dst_port = tonumber((ctx or ngx.ctx).host_port, 10) or + tonumber(var.server_port, 10) + end + end + + return params.dst_port + end + +end -- is_http + + +if is_http then + + local fmt = string.format + + -- func => get_headers or get_uri_args + -- name => "headers" or "queries" + -- max_config_option => "lua_max_req_headers" or "lua_max_uri_args" + local function get_http_params(func, name, max_config_option) + local params, err = func() + if err == "truncated" then + local max = kong and kong.configuration and kong.configuration[max_config_option] or 100 + ngx.log(ngx.ERR, + fmt("router: not all request %s were read in order to determine the route " .. + "as the request contains more than %d %s, " .. + "route selection may be inaccurate, " .. + "consider increasing the '%s' configuration value " .. + "(currently at %d)", + name, max, name, max_config_option, max)) + end + + return params + end + + + setmetatable(FIELDS_FUNCS, { + __index = function(_, field) + local prefix = field:sub(1, PREFIX_LEN) + + if prefix == HTTP_HEADERS_PREFIX then + return function(params) + if not params.headers then + params.headers = get_http_params(get_headers, "headers", "lua_max_req_headers") + end + + return params.headers[field:sub(PREFIX_LEN + 1)] + end + + elseif prefix == HTTP_QUERIES_PREFIX then + return function(params) + if not params.queries then + params.queries = get_http_params(get_uri_args, "queries", "lua_max_uri_args") + end + + return params.queries[field:sub(PREFIX_LEN + 1)] + end + end + + -- others return nil + end + }) + +end -- is_http + + +local function fields_visitor(fields, params, ctx, cb) + for _, field in ipairs(fields) do + local func = FIELDS_FUNCS[field] + + if not func then -- unknown field + error("unknown router matching schema field: " .. field) + end -- if func + + local value = func(params, ctx) + + local res, err = cb(field, value) + if not res then + return nil, err + end + end -- for fields + + return true +end + + +-- cache key string +local str_buf = buffer.new(64) + + +local function get_cache_key(fields, params, ctx) + str_buf:reset() + + local res = + fields_visitor(fields, params, ctx, function(field, value) + + -- these fields were not in cache key + if field == "net.protocol" or field == "net.port" then + return true + end + + local headers_or_queries = field:sub(1, PREFIX_LEN) + + if headers_or_queries == HTTP_HEADERS_PREFIX then + headers_or_queries = true + field = replace_dashes_lower(field) + + elseif headers_or_queries == HTTP_QUERIES_PREFIX then + headers_or_queries = true + + else + headers_or_queries = false + end + + if not headers_or_queries then + str_buf:put(value or ""):put("|") + + else -- headers or queries + if type(value) == "table" then + tb_sort(value) + value = tb_concat(value, ",") + end + + str_buf:putf("%s=%s|", field, value or "") + end + + return true + end) -- fields_visitor + + assert(res) + + return str_buf:get() +end + + +local function get_atc_context(schema, fields, params) + local c = context.new(schema) + + local res, err = + fields_visitor(fields, params, nil, function(field, value) + + local prefix = field:sub(1, PREFIX_LEN) + + if prefix == HTTP_HEADERS_PREFIX or prefix == HTTP_QUERIES_PREFIX then + local v_type = type(value) + + -- multiple values for a single query parameter, like /?foo=bar&foo=baz + if v_type == "table" then + for _, v in ipairs(value) do + local res, err = c:add_value(field, v) + if not res then + return nil, err + end + end + + return true + end -- if v_type + + -- the query parameter has only one value, like /?foo=bar + -- the query parameter has no value, like /?foo, + -- get_uri_arg will get a boolean `true` + -- we think it is equivalent to /?foo= + if v_type == "boolean" then + value = "" + end + end + + return c:add_value(field, value) + end) -- fields_visitor + + if not res then + return nil, err + end + + return c +end + + +local function _set_ngx(mock_ngx) + if mock_ngx.var then + var = mock_ngx.var + end + + if type(mock_ngx.req) == "table" then + if mock_ngx.req.get_method then + get_method = mock_ngx.req.get_method + end + + if mock_ngx.req.get_headers then + get_headers = mock_ngx.req.get_headers + end + + if mock_ngx.req.get_uri_args then + get_uri_args = mock_ngx.req.get_uri_args + end + end +end + + +return { + get_cache_key = get_cache_key, + get_atc_context = get_atc_context, + + _set_ngx = _set_ngx, +} diff --git a/spec/01-unit/08-router_spec.lua b/spec/01-unit/08-router_spec.lua index 4ab4539d48f..777f530e183 100644 --- a/spec/01-unit/08-router_spec.lua +++ b/spec/01-unit/08-router_spec.lua @@ -12,6 +12,7 @@ local function reload_router(flavor, subsystem) ngx.config.subsystem = subsystem or "http" -- luacheck: ignore + package.loaded["kong.router.fields"] = nil package.loaded["kong.router.atc"] = nil package.loaded["kong.router.compat"] = nil package.loaded["kong.router.expressions"] = nil @@ -365,6 +366,10 @@ for _, flavor in ipairs({ "traditional", "traditional_compatible", "expressions" }, } router = assert(new_router(use_case)) + + -- let atc-router happy + local _ngx = mock_ngx("GET", "/", { a = "1" }) + router._set_ngx(_ngx) end) @@ -2743,6 +2748,11 @@ for _, flavor in ipairs({ "traditional", "traditional_compatible", "expressions" it("matches correct route", function() local router = assert(new_router(use_case)) + + -- let atc-router happy + local _ngx = mock_ngx("GET", "/", { a = "1" }) + router._set_ngx(_ngx) + local match_t = router:select("GET", "/my-target-uri", "domain.org") assert.truthy(match_t) assert.same(use_case[#use_case].route, match_t.route) @@ -4336,6 +4346,10 @@ for _, flavor in ipairs({ "traditional", "traditional_compatible", "expressions" } router = assert(new_router(use_case)) + + -- let atc-router happy + local _ngx = mock_ngx("GET", "/", { a = "1" }) + router._set_ngx(_ngx) end) it("[src_ip]", function() diff --git a/spec/02-integration/05-proxy/02-router_spec.lua b/spec/02-integration/05-proxy/02-router_spec.lua index d8c1ad22329..3e4144c5246 100644 --- a/spec/02-integration/05-proxy/02-router_spec.lua +++ b/spec/02-integration/05-proxy/02-router_spec.lua @@ -877,7 +877,7 @@ for _, strategy in helpers.each_strategy() do describe("URI arguments (querystring)", function() local routes - lazy_setup(function() + before_each(function() routes = insert_routes(bp, { { hosts = { "mock_upstream" }, @@ -885,7 +885,7 @@ for _, strategy in helpers.each_strategy() do }) end) - lazy_teardown(function() + after_each(function() remove_routes(strategy, routes) end) @@ -1343,7 +1343,7 @@ for _, strategy in helpers.each_strategy() do path = "/status/201", headers = { ["kong-debug"] = 1 }, }) - assert.res_status(201, res) + assert.res_status(flavor == "traditional" and 201 or 200, res) assert.equal("service_behind_www.example.org", res.headers["kong-service-name"]) @@ -1365,7 +1365,7 @@ for _, strategy in helpers.each_strategy() do path = "/status/201", headers = { ["kong-debug"] = 1 }, }) - assert.res_status(201, res) + assert.res_status(flavor == "traditional" and 201 or 200, res) assert.equal("service_behind_example.org", res.headers["kong-service-name"]) end) diff --git a/spec/02-integration/05-proxy/19-grpc_proxy_spec.lua b/spec/02-integration/05-proxy/19-grpc_proxy_spec.lua index 2add432ae46..2d524b085d1 100644 --- a/spec/02-integration/05-proxy/19-grpc_proxy_spec.lua +++ b/spec/02-integration/05-proxy/19-grpc_proxy_spec.lua @@ -402,14 +402,8 @@ for _, strategy in helpers.each_strategy() do }) assert.falsy(ok) - if flavor == "expressions" then - assert.matches("Code: NotFound", resp, nil, true) - assert.matches("Message: NotFound", resp, nil, true) - - else - assert.matches("Code: Canceled", resp, nil, true) - assert.matches("Message: gRPC request matched gRPCs route", resp, nil, true) - end + assert.matches("Code: Canceled", resp, nil, true) + assert.matches("Message: gRPC request matched gRPCs route", resp, nil, true) end) end) end)