Ethan-Zhang-ZH opened a new issue, #13479:
URL: https://github.com/apache/apisix/issues/13479
### Current Behavior
After upgrading Apache APISIX from 3.10 to 3.15, we started seeing errors
from the `workflow` plugin during the log phase:
```text
failed to run log_by_lua*:
/usr/local/apisix/apisix/plugins/workflow.lua:182: attempt to index field
'_workflow_cache' (a nil value)
stack traceback:
/usr/local/apisix/apisix/plugins/workflow.lua:182: in function
'phase_func'
/usr/local/apisix/apisix/plugin.lua:1231: in function 'run_plugin'
/usr/local/apisix/apisix/plugin.lua:1331: in function
'run_global_rules'
/usr/local/apisix/apisix/init.lua:472: in function 'common_phase'
/usr/local/apisix/apisix/init.lua:1064: in function 'http_log_phase'
The affected requests are mainly OPTIONS preflight requests.
Expected Behavior
The workflow plugin should not throw an error in the log phase when
ctx._workflow_cache is not initialized.
Error Analysis
In APISIX 3.15, workflow.lua added a log phase handler introduced by:
- PR: https://github.com/apache/apisix/pull/12465
- Commit:
https://github.com/apache/apisix/commit/ee108c588ac5f7eb0ea794b2d1ec3e7c9729fd45
The current logic initializes ctx._workflow_cache only in the access phase:
function _M.access(conf, ctx)
ctx._workflow_cache = ctx._workflow_cache or {}
...
ctx._workflow_cache[idx] = match_result
end
However, the log phase assumes the field always exists:
function _M.log(conf, ctx)
for idx, rule in ipairs(conf.rules) do
local match_result = ctx._workflow_cache[idx]
...
end
end
If a request is finalized before workflow.access() runs, for example an
OPTIONS request handled earlier by CORS or another plugin, the log phase can
still execute while ctx._workflow_cache is nil.
Possible Fix
Add a nil guard at the beginning of workflow.log():
function _M.log(conf, ctx)
if not ctx._workflow_cache then
return
end
for idx, rule in ipairs(conf.rules) do
local match_result = ctx._workflow_cache[idx]
...
end
end
Environment
- APISIX version: 3.15
- Previous version without this issue: 3.10
- Plugin involved: workflow
- Request type: mainly OPTIONS preflight requests
### Expected Behavior
_No response_
### Error Logs
_No response_
### Steps to Reproduce
1. Start APISIX 3.15 with the `workflow`, `cors`, and `limit-conn` plugins
enabled.
2. Configure a global rule that uses the `workflow` plugin with a
`limit-conn` action.
Example:
```json
{
"plugins": {
"workflow": {
"rules": [
{
"case": [
["http_method", "==", "GET"]
],
"actions": [
[
"limit-conn",
{
"conn": 1,
"burst": 0,
"default_conn_delay": 0,
"key": "remote_addr",
"rejected_code": 503
}
]
]
}
]
}
}
}
3. Configure a route with the cors plugin enabled so that OPTIONS preflight
requests are handled before the access phase.
Example:
{
"uri": "/test",
"plugins": {
"cors": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}
4. Send an OPTIONS preflight request:
curl -i -X OPTIONS "http://127.0.0.1:9080/test" \
-H "Origin: https://example.com" \
-H "Access-Control-Request-Method: GET"
5. Check the APISIX error log.
Actual result:
failed to run log_by_lua*:
/usr/local/apisix/apisix/plugins/workflow.lua:182: attempt to index field
'_workflow_cache' (a nil value)
Expected result:
APISIX should handle the request without logging an error. The workflow
plugin should skip the log phase safely when ctx._workflow_cache was not
initialized in the access phase.
The core trigger is: `workflow.log()` runs, but `workflow.access()` did not
run for that request.
### Environment
- APISIX version (run `apisix version`):
- Operating system (run `uname -a`):
- OpenResty / Nginx version (run `openresty -V` or `nginx -V`):
- etcd version, if relevant (run `curl
http://127.0.0.1:9090/v1/server_info`):
- APISIX Dashboard version, if relevant:
- Plugin runner version, for issues related to plugin runners:
- LuaRocks version, for installation issues (run `luarocks --version`):
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]