nic-6443 opened a new pull request, #14156: URL: https://github.com/apache/apisix/pull/14156
This adds an optional `_meta.filter_phase` so a plugin can say when its `_meta.filter` gets decided, and stops `status`, `bytes_sent`, `body_bytes_sent` and `request_time` from sticking in the `ctx.var` cache. Together they fix the logger filters from #13724: a filter like `["OR", ["status","~=",404], ["upstream_status","==",404]]` with `filter_phase: body_filter` or `log` now logs the backend 404 with its real status and body and drops the gateway-generated one. The semantics are small. A function in a phase earlier than the named one always runs, so `meta_filter` returns true without evaluating. At the named phase or later, the existing cached path runs: one decision per request, no phase in the key. A named phase the request skips decides at the next one that runs, so HEAD with `body_filter` decides at `log`. With `filter_phase` unset nothing changes in `meta_filter`. The config is rejected on a bad value, without `filter`, or when the plugin has no function at or after the phase, since that filter would never run. It's generic with no plugin allowlist, and it's the same on stream routes, where `preread` takes the rank of `access`. I didn't go with a per-phase cache key (#13727, #13790) because re-evaluating in each phase is what #8162 removed, and it breaks plugins that need one decision across phases. I prototyped the #13727 shape and ran it: `response-rewrite` with a `status==200` filter and a new `status_code` re-evaluates in `body_filter` and returns the new status with the old body, and `limit-conn` with a `status~=500` filter skips its release on a 500, so later requests get 503. So this needs explicit config, by design: the user picks the phase, and existing configs keep their behaviour. The docs now spell out that consequence too. Functions before the named phase always run, so a plugin's earlier action can't depend on something only known later, and the plugin docs list concrete configs that are unsupported by design, such as `limit-conn` with `filter_phase: log` and `csrf` exemptions with `filter_phase: header_filter`, along with the rule for judging other plugins. The same docs change covers the default decision point and a table of common variables and when they become meaningful. Two things worth a look. `lua_body_filter` is called from `before_proxy` and interleaves with `header_filter`/`body_filter` once streaming starts, so `meta_filter` reads a stored decision before it compares phases, otherwise a later chunk would ignore a decision already made. And since `status` no longer caches, `ctx.var.status` now always reads through to nginx. Tests are in `t/plugin/meta-filter-phase.t`, all integration through real requests except one table-driven check of the phase ordering. The `status` poisoning cases fail on master, and the `response-rewrite` and `limit-conn` regressions with `filter_phase` unset pass on both. Fixes #13724 -- 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]
