You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2022/10/10 06:00:29 UTC

[apisix] branch master updated: chore: update hold_body_chunk to avoid unexpected behavior (#8045)

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

spacewander 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 c25e1123d chore: update hold_body_chunk to avoid unexpected behavior (#8045)
c25e1123d is described below

commit c25e1123d90b9b9926de002b9a472740f1bbbbb0
Author: 罗泽轩 <sp...@gmail.com>
AuthorDate: Mon Oct 10 14:00:21 2022 +0800

    chore: update hold_body_chunk to avoid unexpected behavior (#8045)
---
 apisix/core/response.lua | 22 ++++++++++----------
 t/core/response.t        | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/apisix/core/response.lua b/apisix/core/response.lua
index 29442dfb6..b934d94b9 100644
--- a/apisix/core/response.lua
+++ b/apisix/core/response.lua
@@ -177,17 +177,6 @@ end
 function _M.hold_body_chunk(ctx, hold_the_copy)
     local body_buffer
     local chunk, eof = arg[1], arg[2]
-    if eof then
-        body_buffer = ctx._body_buffer
-        if not body_buffer then
-            return chunk
-        end
-
-        body_buffer = concat_tab(body_buffer, "", 1, body_buffer.n)
-        ctx._body_buffer = nil
-        return body_buffer
-    end
-
     if type(chunk) == "string" and chunk ~= "" then
         body_buffer = ctx._body_buffer
         if not body_buffer then
@@ -203,6 +192,17 @@ function _M.hold_body_chunk(ctx, hold_the_copy)
         end
     end
 
+    if eof then
+        body_buffer = ctx._body_buffer
+        if not body_buffer then
+            return chunk
+        end
+
+        body_buffer = concat_tab(body_buffer, "", 1, body_buffer.n)
+        ctx._body_buffer = nil
+        return body_buffer
+    end
+
     if not hold_the_copy then
         -- flush the origin body chunk
         arg[1] = nil
diff --git a/t/core/response.t b/t/core/response.t
index ed7856be2..eda1ec252 100644
--- a/t/core/response.t
+++ b/t/core/response.t
@@ -163,3 +163,55 @@ done
 aaa:
 --- no_error_log
 [error]
+
+
+
+=== TEST 8: hold_body_chunk (ngx.arg[2] == true and ngx.arg[1] ~= "")
+--- config
+    location = /t {
+        content_by_lua_block {
+            -- Nginx uses a separate buf to mark the end of the stream,
+            -- hence when ngx.arg[2] == true, ngx.arg[1] will be equal to "".
+            -- To avoid something unexpected, here we add a test to verify
+            -- this situation via mock.
+            local t = ngx.arg
+            local metatable = getmetatable(t)
+            local count = 0
+            setmetatable(t, {__index = function(t, idx)
+                if count == 0 then
+                    if idx == 1 then
+                        return "hello "
+                    end
+                    count = count + 1
+                    return false
+                end
+                if count == 1 then
+                    if idx == 1 then
+                        return "world\n"
+                    end
+                    count = count + 1
+                    return true
+                end
+
+                return metatable.__index(t, idx)
+            end,
+            __newindex = metatable.__newindex})
+
+            -- trigger body_filter_by_lua_block
+            ngx.print("A")
+        }
+        body_filter_by_lua_block {
+            local core = require("apisix.core")
+            local final_body = core.response.hold_body_chunk(ngx.ctx)
+            if not final_body then
+                return
+            end
+            ngx.arg[1] = final_body
+        }
+    }
+--- request
+GET /t
+--- response_body
+hello world
+--- no_error_log
+[error]