AlinsRan opened a new pull request, #13595:
URL: https://github.com/apache/apisix/pull/13595
Fixes #13055
## Problem
When two `env NAME=VALUE;` directives share a common prefix (e.g.
`KUBERNETES_CLIENT_TOKEN` and `KUBERNETES_CLIENT_TOKEN_FILE`), resolving the
longer-named variable during the init / init_worker phase returns the
**shorter** variable's value, depending on declaration order.
## Root cause (in OpenResty, but worked around here without patching it)
Before any request is served, `lua-resty-core` replaces `os.getenv` with a
shim that delegates to the C function `ngx_http_lua_ffi_get_conf_env`. That
function matches the queried name against each configured `env` entry with:
```c
if (var[i].data[var[i].len] == '='
&& ngx_strncmp(name, var[i].data, var[i].len) == 0)
```
It checks that the configured entry ends at `var[i].len`, but it does
**not** require the queried `name` to end there too. So
`os.getenv("KUBERNETES_CLIENT_TOKEN_FILE")` matches the
`KUBERNETES_CLIENT_TOKEN` entry on its first 23 bytes and returns the wrong
value. This is an upstream `lua-nginx-module` bug, but it can be fully
sidestepped on the APISIX side.
PR #13147 cannot fix it, because during `init_by_lua` the `environ` snapshot
does not yet contain `env NAME=VALUE;` directive vars (nginx applies them only
in `ngx_set_environment` at worker start), so its lookup misses and falls back
to the same shim.
## Fix (self-contained, no OpenResty change)
- Resolve env variables from `environ` directly with exact keys
(`core.env.init()` already builds such a table) instead of going through the
buggy shim.
- nginx assigns the directive vars to the global `environ` in
`ngx_set_environment` at worker start (before `init_worker_by_lua`), so
`core.env.init()` is also invoked in the worker init phase to capture
directive-assigned values.
- Add `core.env.get(name)` for exact-match lookups; route `$ENV://`
resolution and the kubernetes discovery `read_env` through it.
## Tests
`t/core/env.t`:
- TEST 10/11: prefix-colliding directives resolve correctly via `$ENV://`,
regardless of declaration order.
- TEST 12: `core.env.get` returns exact values for prefix-colliding
directives.
- TEST 13: values captured in the `init_worker` phase for prefix-colliding
directives are correct.
## Compatibility
`core.env.get` falls back to `os.getenv` for variables set dynamically after
startup (e.g. via `core.os.setenv`), so existing behavior is preserved. The new
worker-phase `core.env.init()` is idempotent.
--
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]