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]

Reply via email to