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]

Reply via email to