This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch release/2.15
in repository https://gitbox.apache.org/repos/asf/apisix.git

commit e262a90004aa238c9dd8710469dedd377037e540
Author: soulbird <[email protected]>
AuthorDate: Fri Oct 28 14:24:18 2022 +0800

    fix: meta.filter in plugin doesn't work in response-rewrite plugin (#8162)
    
    Co-authored-by: soulbird <[email protected]>
    Signed-off-by: spacewander <[email protected]>
---
 apisix/plugin.lua |  38 ++++++++--
 t/plugin/plugin.t | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 244 insertions(+), 6 deletions(-)

diff --git a/apisix/plugin.lua b/apisix/plugin.lua
index 2e6758efb..511fbc605 100644
--- a/apisix/plugin.lua
+++ b/apisix/plugin.lua
@@ -76,6 +76,21 @@ local function custom_sort_plugin(l, r)
     return l._meta.priority > r._meta.priority
 end
 
+local function check_disable(plugin_conf)
+    if not plugin_conf then
+        return nil
+    end
+
+    if not plugin_conf._meta then
+       return nil
+    end
+
+    if type(plugin_conf._meta) ~= "table" then
+        return nil
+    end
+
+    return plugin_conf._meta.disable
+end
 
 local PLUGIN_TYPE_HTTP = 1
 local PLUGIN_TYPE_STREAM = 2
@@ -391,6 +406,13 @@ local function meta_filter(ctx, plugin_name, plugin_conf)
         return true
     end
 
+    local match_cache_key =
+        ctx.conf_type .. "#" .. ctx.conf_id .. "#"
+            .. ctx.conf_version .. "#" .. plugin_name .. "#meta_filter_matched"
+    if ctx[match_cache_key] ~= nil then
+        return ctx[match_cache_key]
+    end
+
     local ex, ok, err
     if ctx then
         ex, err = expr_lrucache(plugin_name .. ctx.conf_type .. ctx.conf_id,
@@ -409,6 +431,8 @@ local function meta_filter(ctx, plugin_name, plugin_conf)
                          " plugin_name: ", plugin_name)
         return true
     end
+
+    ctx[match_cache_key] = ok
     return ok
 end
 
@@ -433,8 +457,7 @@ function _M.filter(ctx, conf, plugins, route_conf, phase)
             goto continue
         end
 
-        local matched = meta_filter(ctx, name, plugin_conf)
-        if not plugin_conf.disable and matched then
+        if not check_disable(plugin_conf) then
             if plugin_obj.run_policy == "prefer_route" and route_plugin_conf 
~= nil then
                 local plugin_conf_in_route = route_plugin_conf[name]
                 if plugin_conf_in_route and not plugin_conf_in_route.disable 
then
@@ -897,8 +920,12 @@ function _M.run_plugin(phase, plugins, api_ctx)
             end
 
             if phase_func then
-                plugin_run = true
                 local conf = plugins[i + 1]
+                if not meta_filter(api_ctx, plugins[i]["name"], conf)then
+                    goto CONTINUE
+                end
+
+                plugin_run = true
                 local code, body = phase_func(conf, api_ctx)
                 if code or body then
                     if is_http then
@@ -931,9 +958,10 @@ function _M.run_plugin(phase, plugins, api_ctx)
 
     for i = 1, #plugins, 2 do
         local phase_func = plugins[i][phase]
-        if phase_func then
+        local conf = plugins[i + 1]
+        if phase_func and meta_filter(api_ctx, plugins[i]["name"], conf) then
             plugin_run = true
-            phase_func(plugins[i + 1], api_ctx)
+            phase_func(conf, api_ctx)
         end
     end
 
diff --git a/t/plugin/plugin.t b/t/plugin/plugin.t
index 755294868..248688050 100644
--- a/t/plugin/plugin.t
+++ b/t/plugin/plugin.t
@@ -520,8 +520,218 @@ passed
 
 
 
-=== TEST 18: hit route: run proxy-rewrite plugin
+=== TEST 18: hit route: run global proxy-rewrite plugin
 --- request
 GET /hello1?version=v4
 --- response_headers
 x-api-version: v4
+
+
+
+=== TEST 19: different global_rules with the same plugin will not use the same 
meta.filter cache
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/global_rules/3',
+                ngx.HTTP_PUT,
+                {
+                    plugins = {
+                        ["proxy-rewrite"] = {
+                            _meta = {
+                                filter = {
+                                    {"arg_version", "==", "v5"}
+                                }
+                            },
+                            uri = "/echo",
+                            headers = {
+                                ["X-Api-Version"] = "v5"
+                            }
+                        }
+                    }
+                }
+            )
+            if code >= 300 then
+                ngx.print(body)
+            else
+                ngx.say(body)
+            end
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 20: hit global_rules which has the same plugin with different 
meta.filter
+--- pipelined_requests eval
+["GET /hello1?version=v4", "GET /hello1?version=v5"]
+--- response_headers eval
+["x-api-version: v4", "x-api-version: v5"]
+
+
+
+=== TEST 21: use _meta.filter in response-rewrite plugin
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "plugins": {
+                            "response-rewrite": {
+                                "_meta": {
+                                    "filter": [
+                                        ["upstream_status", "~=", 200]
+                                    ]
+                                },
+                                "headers": {
+                                    "test-header": "error"
+                                }
+                            }
+                        },
+                        "upstream": {
+                            "nodes": {
+                                "127.0.0.1:1980": 1
+                            },
+                            "type": "roundrobin"
+                        },
+                        "uri": "/*"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 22: upstream_status = 502, enable response-rewrite plugin
+--- request
+GET /specific_status
+--- more_headers
+x-test-upstream-status: 502
+--- response_headers
+test-header: error
+--- error_code: 502
+
+
+
+=== TEST 23: upstream_status = 200, disable response-rewrite plugin
+--- request
+GET /hello
+--- response_headers
+!test-header
+
+
+
+=== TEST 24: use _meta.filter in response-rewrite plugin
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "plugins": {
+                            "proxy-rewrite": {
+                                "headers": {
+                                    "foo-age": "$arg_age"
+                                }
+                            },
+                            "response-rewrite": {
+                                "_meta": {
+                                    "filter": [
+                                        ["http_foo_age", "==", "18"]
+                                    ]
+                                },
+                               "status_code": 403
+                            }
+                        },
+                        "upstream": {
+                            "nodes": {
+                                "127.0.0.1:1980": 1
+                            },
+                            "type": "roundrobin"
+                        },
+                        "uri": "/*"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 25: proxy-rewrite plugin will set $http_foo_age, response-rewrite 
plugin return 403
+--- request
+GET /hello?age=18
+--- error_code: 403
+
+
+
+=== TEST 26: response-rewrite plugin disable, return 200
+--- request
+GET /hello
+
+
+
+=== TEST 27: use response var in meta.filter
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "plugins": {
+                            "proxy-rewrite": {
+                                "_meta": {
+                                    "filter": [
+                                        ["upstream_status", "==", "200"]
+                                    ]
+                                },
+                                "uri": "/echo",
+                                "headers": {
+                                    "x-version": "v1"
+                                }
+                            }
+                        },
+                        "upstream": {
+                            "nodes": {
+                                "127.0.0.1:1980": 1
+                            },
+                            "type": "roundrobin"
+                        },
+                        "uri": "/*"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 28: hit route: disable proxy-rewrite plugin
+--- request
+GET /hello
+--- response_headers
+!x-version

Reply via email to