Skip to content

Commit 21d7673

Browse files
bzp2010kaihaojiangspacewanderjack.fusunaowei
authored
feat: release 2.10.3 (#5958)
Co-authored-by: kaihaojiang <kaihaojiang@tencent.com> Co-authored-by: 罗泽轩 <spacewanderlzx@gmail.com> Co-authored-by: jack.fu <jack.fu@yijinin.com> Co-authored-by: sunaowei <sunaowei@neild> Co-authored-by: cache-missing <90820067+cache-missing@users.noreply.github.com> Co-authored-by: tzssangglass <tzssangglass@gmail.com> Co-authored-by: 帅进超 <shuaijinchao@gmail.com> Co-authored-by: leslie <59061168+leslie-tsang@users.noreply.github.com> Co-authored-by: jackfu <jackfu1008@gmail.com> Co-authored-by: S96EA <neild47@163.com>
1 parent ffc6cd6 commit 21d7673

39 files changed

+1017
-187
lines changed

.github/workflows/build.yml

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ jobs:
2525
- linux_openresty
2626
- linux_openresty_1_17
2727
- linux_tengine
28-
- linux_apisix_master_luarocks
2928
- linux_apisix_current_luarocks
3029
- linux_openresty_mtls
3130

CHANGELOG.md

+21
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ title: Changelog
2323

2424
## Table of Contents
2525

26+
- [2.10.3](#2103)
2627
- [2.10.2](#2102)
2728
- [2.10.1](#2101)
2829
- [2.10.0](#2100)
@@ -48,6 +49,26 @@ title: Changelog
4849
- [0.7.0](#070)
4950
- [0.6.0](#060)
5051

52+
## 2.10.3
53+
54+
### Bugfix
55+
56+
- fix: str concat in error call [#5540](https://github.com/apache/apisix/pull/5540)
57+
- fix: ignore changes of /apisix/plugins/ [#5558](https://github.com/apache/apisix/pull/5558)
58+
- fix: invalid error after passive health check is changed [#5589](https://github.com/apache/apisix/pull/5589)
59+
- fix(batch-processor): we didn't free stale object actually [#5700](https://github.com/apache/apisix/pull/5700)
60+
- fix(patch): add global `math.randomseed` patch support [#5682](https://github.com/apache/apisix/pull/5682)
61+
- fix(log-rotate): after enabling compression collect log exceptions [#5715](https://github.com/apache/apisix/pull/5715)
62+
- feat(ext-plugin): avoid sending conf request more times [#5183](https://github.com/apache/apisix/pull/5183)
63+
- feat: use lock to ensure fetching token from shdict always [#5263](https://github.com/apache/apisix/pull/5263)
64+
- fix(ext-plugin): don't use stale key [#5782](https://github.com/apache/apisix/pull/5782)
65+
- fix(mqtt-proxy): client id can be empty [#5816](https://github.com/apache/apisix/pull/5816)
66+
- fix(sls-logger): log entry unable get millisecond timestamp [#5820](https://github.com/apache/apisix/pull/5820)
67+
- fix(ua-restriction): refine plugin configuration check logic [#5728](https://github.com/apache/apisix/pull/5728)
68+
- fix(cors): compatible with scenarios where origin is modified [#5890](https://github.com/apache/apisix/pull/5890)
69+
- fix(proxy-rewrite): make sure proxy-rewrite update the core.request.header cache [#5914](https://github.com/apache/apisix/pull/5914)
70+
- fix(mqtt): handle properties for MQTT 5 [#5916](https://github.com/apache/apisix/pull/5916)
71+
5172
## 2.10.2
5273

5374
### Bugfix

apisix/cli/ngx_tpl.lua

+3
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ http {
191191
# for authz-keycloak
192192
lua_shared_dict access-tokens {* http.lua_shared_dict["access-tokens"] *}; # cache for service account access tokens
193193
194+
# for ext-plugin
195+
lua_shared_dict ext-plugin {* http.lua_shared_dict["ext-plugin"] *}; # cache for ext-plugin
196+
194197
# for custom shared dict
195198
{% if http.custom_lua_shared_dict then %}
196199
{% for cache_key, cache_size in pairs(http.custom_lua_shared_dict) do %}

apisix/core/version.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
-- limitations under the License.
1616
--
1717
return {
18-
VERSION = "2.10.2"
18+
VERSION = "2.10.3"
1919
}

apisix/patch.lua

+47
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,23 @@ local ipmatcher = require("resty.ipmatcher")
2020
local socket = require("socket")
2121
local unix_socket = require("socket.unix")
2222
local ssl = require("ssl")
23+
local ngx = ngx
2324
local get_phase = ngx.get_phase
2425
local ngx_socket = ngx.socket
2526
local original_tcp = ngx.socket.tcp
2627
local original_udp = ngx.socket.udp
2728
local concat_tab = table.concat
29+
local debug = debug
2830
local new_tab = require("table.new")
2931
local log = ngx.log
3032
local WARN = ngx.WARN
3133
local ipairs = ipairs
3234
local select = select
3335
local setmetatable = setmetatable
36+
local string = string
37+
local table = table
3438
local type = type
39+
local tonumber = tonumber
3540

3641

3742
local config_local
@@ -86,6 +91,48 @@ do
8691
end
8792

8893

94+
do -- `math.randomseed` patch
95+
-- `math.random` generates PRND(pseudo-random numbers) from the seed set by `math.randomseed`
96+
-- Many module libraries use `ngx.time` and `ngx.worker.pid` to generate seeds which may
97+
-- loss randomness in container env (where pids are identical, e.g. root pid is 1)
98+
-- Kubernetes may launch multi instance with deployment RS at the same time, `ngx.time` may
99+
-- get same return in the pods.
100+
-- Therefore, this global patch enforce entire framework to use
101+
-- the best-practice PRND generates.
102+
103+
local resty_random = require("resty.random")
104+
local math_randomseed = math.randomseed
105+
local seeded = {}
106+
107+
-- make linter happy
108+
-- luacheck: ignore
109+
math.randomseed = function()
110+
local worker_pid = ngx.worker.pid()
111+
112+
-- check seed mark
113+
if seeded[worker_pid] then
114+
log(ngx.DEBUG, debug.traceback("Random seed has been inited", 2))
115+
return
116+
end
117+
118+
-- generate randomseed
119+
-- chose 6 from APISIX's SIX, 256 ^ 6 should do the trick
120+
-- it shouldn't be large than 16 to prevent overflow.
121+
local random_bytes = resty_random.bytes(6)
122+
local t = {}
123+
124+
for i = 1, #random_bytes do
125+
t[i] = string.byte(random_bytes, i)
126+
end
127+
128+
local s = table.concat(t)
129+
130+
math_randomseed(tonumber(s))
131+
seeded[worker_pid] = true
132+
end
133+
end -- do
134+
135+
89136
local patch_udp_socket
90137
do
91138
local old_udp_sock_setpeername

apisix/plugin.lua

+10-8
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ function _M.load(config)
234234
local_conf, err = core.config.local_conf(true)
235235
if not local_conf then
236236
-- the error is unrecoverable, so we need to raise it
237-
error("failed to load the configuration file: ", err)
237+
error("failed to load the configuration file: " .. err)
238238
end
239239

240240
http_plugin_names = local_conf.plugins
@@ -245,13 +245,15 @@ function _M.load(config)
245245
stream_plugin_names = {}
246246
local plugins_conf = config.value
247247
-- plugins_conf can be nil when another instance writes into etcd key "/apisix/plugins/"
248-
if plugins_conf then
249-
for _, conf in ipairs(plugins_conf) do
250-
if conf.stream then
251-
core.table.insert(stream_plugin_names, conf.name)
252-
else
253-
core.table.insert(http_plugin_names, conf.name)
254-
end
248+
if not plugins_conf then
249+
return local_plugins
250+
end
251+
252+
for _, conf in ipairs(plugins_conf) do
253+
if conf.stream then
254+
core.table.insert(stream_plugin_names, conf.name)
255+
else
256+
core.table.insert(http_plugin_names, conf.name)
255257
end
256258
end
257259
end

apisix/plugins/cors.lua

+3-1
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,16 @@ end
227227

228228

229229
function _M.rewrite(conf, ctx)
230+
-- save the original request origin as it may be changed at other phase
231+
ctx.original_request_origin = core.request.header(ctx, "Origin")
230232
if ctx.var.request_method == "OPTIONS" then
231233
return 200
232234
end
233235
end
234236

235237

236238
function _M.header_filter(conf, ctx)
237-
local req_origin = core.request.header(ctx, "Origin")
239+
local req_origin = ctx.original_request_origin
238240
-- Try allow_origins first, if mismatched, try allow_origins_by_regex.
239241
local allow_origins
240242
allow_origins = process_with_allow_origins(conf, ctx, req_origin)

apisix/plugins/ext-plugin/init.lua

+88-15
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ if is_http then
4040
ngx_pipe = require("ngx.pipe")
4141
events = require("resty.worker.events")
4242
end
43+
local resty_lock = require("resty.lock")
4344
local resty_signal = require "resty.signal"
4445
local bit = require("bit")
4546
local band = bit.band
@@ -63,11 +64,18 @@ local type = type
6364

6465

6566
local events_list
66-
local lrucache = core.lrucache.new({
67-
type = "plugin",
68-
invalid_stale = true,
69-
ttl = helper.get_conf_token_cache_time(),
70-
})
67+
68+
local function new_lrucache()
69+
return core.lrucache.new({
70+
type = "plugin",
71+
invalid_stale = true,
72+
ttl = helper.get_conf_token_cache_time(),
73+
})
74+
end
75+
local lrucache = new_lrucache()
76+
77+
local shdict_name = "ext-plugin"
78+
local shdict = ngx.shared[shdict_name]
7179

7280
local schema = {
7381
type = "object",
@@ -293,14 +301,74 @@ local function handle_extra_info(ctx, input)
293301
end
294302

295303

304+
local function fetch_token(key)
305+
if shdict then
306+
return shdict:get(key)
307+
else
308+
core.log.error('shm "ext-plugin" not found')
309+
return nil
310+
end
311+
end
312+
313+
314+
local function store_token(key, token)
315+
if shdict then
316+
local exp = helper.get_conf_token_cache_time()
317+
-- early expiry, lrucache in critical state sends prepare_conf_req as original behaviour
318+
exp = exp * 0.9
319+
local success, err, forcible = shdict:set(key, token, exp)
320+
if not success then
321+
core.log.error("ext-plugin:failed to set conf token, err: ", err)
322+
end
323+
if forcible then
324+
core.log.warn("ext-plugin:set valid items forcibly overwritten")
325+
end
326+
else
327+
core.log.error('shm "ext-plugin" not found')
328+
end
329+
end
330+
331+
332+
local function flush_token()
333+
if shdict then
334+
core.log.warn("flush conf token in shared dict")
335+
shdict:flush_all()
336+
else
337+
core.log.error('shm "ext-plugin" not found')
338+
end
339+
end
340+
341+
296342
local rpc_call
297343
local rpc_handlers = {
298344
nil,
299345
function (conf, ctx, sock, unique_key)
346+
local token = fetch_token(unique_key)
347+
if token then
348+
core.log.info("fetch token from shared dict, token: ", token)
349+
return token
350+
end
351+
352+
local lock, err = resty_lock:new(shdict_name)
353+
if not lock then
354+
return nil, "failed to create lock: " .. err
355+
end
356+
357+
local elapsed, err = lock:lock("prepare_conf")
358+
if not elapsed then
359+
return nil, "failed to acquire the lock: " .. err
360+
end
361+
362+
local token = fetch_token(unique_key)
363+
if token then
364+
lock:unlock()
365+
core.log.info("fetch token from shared dict, token: ", token)
366+
return token
367+
end
368+
300369
builder:Clear()
301370

302371
local key = builder:CreateString(unique_key)
303-
304372
local conf_vec
305373
if conf.conf then
306374
local len = #conf.conf
@@ -331,23 +399,30 @@ local rpc_handlers = {
331399

332400
local ok, err = send(sock, constants.RPC_PREPARE_CONF, builder:Output())
333401
if not ok then
402+
lock:unlock()
334403
return nil, "failed to send RPC_PREPARE_CONF: " .. err
335404
end
336405

337406
local ty, resp = receive(sock)
338407
if ty == nil then
408+
lock:unlock()
339409
return nil, "failed to receive RPC_PREPARE_CONF: " .. resp
340410
end
341411

342412
if ty ~= constants.RPC_PREPARE_CONF then
413+
lock:unlock()
343414
return nil, "failed to receive RPC_PREPARE_CONF: unexpected type " .. ty
344415
end
345416

346417
local buf = flatbuffers.binaryArray.New(resp)
347418
local pcr = prepare_conf_resp.GetRootAsResp(buf, 0)
348-
local token = pcr:ConfToken()
419+
token = pcr:ConfToken()
349420

350421
core.log.notice("get conf token: ", token, " conf: ", core.json.delay_encode(conf.conf))
422+
store_token(unique_key, token)
423+
424+
lock:unlock()
425+
351426
return token
352427
end,
353428
function (conf, ctx, sock, entry)
@@ -471,7 +546,6 @@ local rpc_handlers = {
471546
local buf = flatbuffers.binaryArray.New(resp)
472547
local call_resp = http_req_call_resp.GetRootAsResp(buf, 0)
473548
local action_type = call_resp:ActionType()
474-
475549
if action_type == http_req_call_action.Stop then
476550
local action = call_resp:Action()
477551
local stop = http_req_call_stop.New()
@@ -588,15 +662,14 @@ rpc_call = function (ty, conf, ctx, ...)
588662
end
589663

590664

591-
local function create_lrucache()
665+
local function recreate_lrucache()
666+
flush_token()
667+
592668
if lrucache then
593669
core.log.warn("flush conf token lrucache")
594670
end
595671

596-
lrucache = core.lrucache.new({
597-
type = "plugin",
598-
ttl = helper.get_conf_token_cache_time(),
599-
})
672+
lrucache = new_lrucache()
600673
end
601674

602675

@@ -620,7 +693,7 @@ function _M.communicate(conf, ctx, plugin_name)
620693
end
621694

622695
core.log.warn("refresh cache and try again")
623-
create_lrucache()
696+
recreate_lrucache()
624697
end
625698

626699
core.log.error(err)
@@ -717,7 +790,7 @@ function _M.init_worker()
717790
)
718791

719792
-- flush cache when runner exited
720-
events.register(create_lrucache, events_list._source, events_list.runner_exit)
793+
events.register(recreate_lrucache, events_list._source, events_list.runner_exit)
721794

722795
-- note that the runner is run under the same user as the Nginx master
723796
if process.type() == "privileged agent" then

apisix/plugins/http-logger.lua

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ local plugin = require("apisix.plugin")
2525
local ngx = ngx
2626
local tostring = tostring
2727
local ipairs = ipairs
28+
local pairs = pairs
2829
local timer_at = ngx.timer.at
2930

3031
local plugin_name = "http-logger"
@@ -150,7 +151,7 @@ local function remove_stale_objects(premature)
150151
return
151152
end
152153

153-
for key, batch in ipairs(buffers) do
154+
for key, batch in pairs(buffers) do
154155
if #batch.entry_buffer.entries == 0 and #batch.batch_to_process == 0 then
155156
core.log.warn("removing batch processor stale object, conf: ",
156157
core.json.delay_encode(key))

0 commit comments

Comments
 (0)