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

membphis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 963e299  bugfix: passed the copied `api_ctx`, it may be freed if the 
`api_ctx` (#2002)
963e299 is described below

commit 963e29951d38d60659c98e2961400c6b6738c4bb
Author: YuanSheng Wang <[email protected]>
AuthorDate: Thu Aug 6 10:20:34 2020 +0800

    bugfix: passed the copied `api_ctx`, it may be freed if the `api_ctx` 
(#2002)
    
    * bugfix: passed the copied `api_ctx`, it may be freed if the `api_ctx`
      was called in back timer async.
    
    Fixed #1935.
---
 apisix/plugins/syslog.lua | 33 ++++++++++++-------
 t/plugin/syslog.t         | 81 +++++++++++++++++++++++------------------------
 2 files changed, 61 insertions(+), 53 deletions(-)

diff --git a/apisix/plugins/syslog.lua b/apisix/plugins/syslog.lua
index 7b96a2e..d2c46b9 100644
--- a/apisix/plugins/syslog.lua
+++ b/apisix/plugins/syslog.lua
@@ -14,6 +14,7 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 --
+
 local core = require("apisix.core")
 local log_util = require("apisix.utils.log-util")
 local batch_processor = require("apisix.utils.batch-processor")
@@ -26,6 +27,7 @@ local stale_timer_running = false;
 local timer_at = ngx.timer.at
 local tostring = tostring
 
+
 local schema = {
     type = "object",
     properties = {
@@ -47,10 +49,12 @@ local schema = {
     required = {"host", "port"}
 }
 
+
 local lrucache = core.lrucache.new({
     ttl = 300, count = 512
 })
 
+
 local _M = {
     version = 0.1,
     priority = 401,
@@ -58,30 +62,30 @@ local _M = {
     schema = schema,
 }
 
+
 function _M.check_schema(conf)
     return core.schema.check(schema, conf)
 end
 
+
 function _M.flush_syslog(logger)
     local ok, err = logger:flush(logger)
     if not ok then
         core.log.error("failed to flush message:", err)
     end
+
+    return ok
 end
 
-local function send_syslog_data(conf, log_message)
+
+local function send_syslog_data(conf, log_message, api_ctx)
     local err_msg
     local res = true
 
-    -- fetch api_ctx
-    local api_ctx = ngx.ctx.api_ctx
-    if not api_ctx then
-        core.log.error("invalid api_ctx cannot proceed with sys logger plugin")
-        return core.response.exit(500)
-    end
-
     -- fetch it from lrucache
-    local logger, err =  lrucache(api_ctx.conf_type .. "#" .. api_ctx.conf_id, 
api_ctx.conf_version,
+    local logger, err =  lrucache(
+        api_ctx.conf_type .. "#" .. api_ctx.conf_id,
+        api_ctx.conf_version,
         logger_socket.new, logger_socket, {
             host = conf.host,
             port = conf.port,
@@ -93,7 +97,8 @@ local function send_syslog_data(conf, log_message)
             retry_interval = conf.retry_interval,
             pool_size = conf.pool_size,
             tls = conf.tls,
-        })
+        }
+    )
 
     if not logger then
         res = false
@@ -110,6 +115,7 @@ local function send_syslog_data(conf, log_message)
     return res, err_msg
 end
 
+
 -- remove stale objects from the memory after timer expires
 local function remove_stale_objects(premature)
     if premature then
@@ -126,8 +132,9 @@ local function remove_stale_objects(premature)
     stale_timer_running = false
 end
 
+
 -- log phase in APISIX
-function _M.log(conf)
+function _M.log(conf, ctx)
     local entry = log_util.get_full_log(ngx, conf)
 
     if not entry.route_id then
@@ -149,6 +156,7 @@ function _M.log(conf)
     end
 
     -- Generate a function to be executed by the batch processor
+    local cp_ctx = core.table.clone(ctx)
     local func = function(entries, batch_max_size)
         local data, err
         if batch_max_size == 1 then
@@ -161,7 +169,7 @@ function _M.log(conf)
             return false, 'error occurred while encoding the data: ' .. err
         end
 
-        return send_syslog_data(conf, data)
+        return send_syslog_data(conf, data, cp_ctx)
     end
 
     local config = {
@@ -186,4 +194,5 @@ function _M.log(conf)
 
 end
 
+
 return _M
diff --git a/t/plugin/syslog.t b/t/plugin/syslog.t
index 05a5cd1..c82dcd2 100644
--- a/t/plugin/syslog.t
+++ b/t/plugin/syslog.t
@@ -19,6 +19,7 @@ use t::APISIX 'no_plan';
 repeat_each(1);
 no_long_string();
 no_root_location();
+
 run_tests;
 
 __DATA__
@@ -169,7 +170,7 @@ hello world
     location /t {
         content_by_lua_block {
             local plugin = require("apisix.plugins.syslog")
-            local logger_socket = require "resty.logger.socket"
+            local logger_socket = require("resty.logger.socket")
             local logger, err = logger_socket:new({
                     host = "127.0.0.1",
                     port = 5044,
@@ -188,13 +189,16 @@ hello world
 
             local ok, err = plugin.flush_syslog(logger)
             if not ok then
-                ngx.say(err)
+                ngx.say("failed to flush syslog: ", err)
+                return
             end
             ngx.say("done")
         }
     }
 --- request
 GET /t
+--- response_body
+done
 --- no_error_log
 [error]
 
@@ -206,62 +210,57 @@ GET /t
         content_by_lua_block {
             local t = require("lib.test_admin").test
             local code, body = t('/apisix/admin/routes/1',
-                 ngx.HTTP_PUT,
-                 [[{
-                        "plugins": {
-                            "syslog": {
-                                 "host" : "127.0.0.1",
-                                 "port" : 5044,
-                                 "flush_limit" : 1
-                              }
-                        },
-                        "upstream": {
-                            "nodes": {
-                                "127.0.0.1:1980": 1
-                            },
-                            "type": "roundrobin"
-                        },
-                        "uri": "/hello"
-                }]],
+                ngx.HTTP_PUT,
                 [[{
-                    "node": {
-                        "value": {
-                            "plugins": {
-                                "syslog": {
-                                 "host" : "127.0.0.1",
-                                 "port" : 5044,
-                                 "flush_limit" : 1
-                              }
-                            },
-                            "upstream": {
-                                "nodes": {
-                                    "127.0.0.1:1980": 1
-                                },
-                                "type": "roundrobin"
-                            },
-                            "uri": "/hello"
+                    "plugins": {
+                        "syslog": {
+                                "host" : "127.0.0.1",
+                                "port" : 5044,
+                                "flush_limit" : 1,
+                                "timeout": 1
+                            }
+                    },
+                    "upstream": {
+                        "nodes": {
+                            "127.0.0.1:1980": 1
                         },
-                        "key": "/apisix/routes/1"
+                        "type": "roundrobin"
                     },
-                    "action": "set"
+                    "uri": "/hello"
                 }]]
-                )
+            )
 
             if code >= 300 then
                 ngx.status = code
             end
-
             ngx.say(body)
 
+            -- wait etcd sync
+            ngx.sleep(0.5)
+
             local http = require "resty.http"
             local httpc = http.new()
             local uri = "http://127.0.0.1:"; .. ngx.var.server_port .. "/hello"
             local res, err = httpc:request_uri(uri, {method = "GET"})
+            if not res then
+                ngx.say("failed request: ", err)
+                return
+            end
+
+            if res.status >= 300 then
+                ngx.status = res.status
+            end
+            ngx.print(res.body)
+
+            -- wait flush log
+            ngx.sleep(2.5)
         }
     }
 --- request
-GET /hello
+GET /t
+--- response_body
+passed
 hello world
 --- no_error_log
 [error]
---- wait: 0.2
+--- timeout: 5

Reply via email to