diff --git a/kong/tools/request_aware_table.lua b/kong/tools/request_aware_table.lua index bb13f17d2359..104723010ad5 100644 --- a/kong/tools/request_aware_table.lua +++ b/kong/tools/request_aware_table.lua @@ -22,24 +22,26 @@ local NGX_VAR_PHASES = { log = true, balancer = true, } +local ALLOWED_REQUEST_ID_K = "__allowed_request_id" + -- Check if access is allowed for table, based on the request ID local function enforce_sequential_access(table) if not NGX_VAR_PHASES[get_phase()] then - -- not in a request context: allow access and reset allowed request ID - rawset(table, "__allowed_request_id", nil) + -- allow access and reset allowed request ID + rawset(table, ALLOWED_REQUEST_ID_K, nil) return end local curr_request_id = var.request_id - local allowed_request_id = rawget(table, "__allowed_request_id") + local allowed_request_id = rawget(table, ALLOWED_REQUEST_ID_K) if not allowed_request_id then -- first access. Set allowed request ID and allow access - rawset(table, "__allowed_request_id", curr_request_id) + rawset(table, ALLOWED_REQUEST_ID_K, curr_request_id) return end - if curr_request_id ~= table.__allowed_request_id then + if curr_request_id ~= table[ALLOWED_REQUEST_ID_K] then error("race condition detected; access to table forbidden", 2) end end @@ -52,7 +54,7 @@ local function clear_table(self) end table_clear(self.__data) - rawset(self, "__allowed_request_id", nil) + rawset(self, ALLOWED_REQUEST_ID_K, nil) end diff --git a/spec/02-integration/05-proxy/33-request-aware-table_spec.lua b/spec/02-integration/05-proxy/33-request-aware-table_spec.lua index fbe25539355c..604fae57fb65 100644 --- a/spec/02-integration/05-proxy/33-request-aware-table_spec.lua +++ b/spec/02-integration/05-proxy/33-request-aware-table_spec.lua @@ -7,11 +7,22 @@ local LOG_LEVELS = { } -local function new_table() +local function trigger_plugin_new_table() local client = helpers.proxy_client() local res = client:get("/", { query = { new_tab = true, + } + }) + assert.response(res).has.status(200) + assert.logfile().has.no.line("[error]", true) + client:close() +end + +local function trigger_plugin_clear_table() + local client = helpers.proxy_client() + local res = client:get("/", { + query = { clear = true, } }) @@ -63,7 +74,7 @@ for _, log_level in ipairs(LOG_LEVELS) do before_each(function() helpers.clean_logfile() - new_table() + trigger_plugin_new_table() client = helpers.proxy_client() end) @@ -95,21 +106,14 @@ for _, log_level in ipairs(LOG_LEVELS) do it("allows access when table is cleared between requests", function() -- access from request 1 (clear) - local r = client:get("/", { - query = { - clear = true, - } - }) + local r = client:get("/") assert.response(r).has.status(200) + trigger_plugin_clear_table() -- access from request 2 (clear) - r = client:get("/", { - query = { - clear = true, - } - }) + r = client:get("/") assert.response(r).has.status(200) - assert.logfile().has.no.line("[error]", true) + trigger_plugin_clear_table() -- access from request 3 r = client:get("/") @@ -118,4 +122,4 @@ for _, log_level in ipairs(LOG_LEVELS) do end) end) end -end \ No newline at end of file +end diff --git a/spec/fixtures/custom_plugins/kong/plugins/request-aware-table/handler.lua b/spec/fixtures/custom_plugins/kong/plugins/request-aware-table/handler.lua index 25966373fc70..a3c640cfeca8 100644 --- a/spec/fixtures/custom_plugins/kong/plugins/request-aware-table/handler.lua +++ b/spec/fixtures/custom_plugins/kong/plugins/request-aware-table/handler.lua @@ -22,16 +22,18 @@ function _M:access(conf) if query.new_tab == "true" then -- new table tab = RAT.new() + ngx.exit(200) end - -- access multiple times during same request - access_table() - access_table() - access_table() - if query.clear == "true" then -- clear table tab:clear() + ngx.exit(200) + end + + -- access multiple times during same request + for _ = 1, 3 do + access_table() end end