Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: hold_body_chunk should use seperate buffer for each plugin in case of pollution #9266

Merged
merged 3 commits into from
Apr 13, 2023
Merged

Conversation

Sn0rt
Copy link
Contributor

@Sn0rt Sn0rt commented Apr 7, 2023

Description

Fixes #9228

and fix:

Fixed a problem with a unit test left before.
This unit test proves that there is a collaboration problem between http-logger and some plugins, which will cause http-logger to repeatedly print the content of the body.

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (If not, please discuss on the APISIX mailing list first)

Signed-off-by: sn0rt <wangguohao.2009@gmail.com>
@Sn0rt Sn0rt changed the title fix: 9228 fix: hold_body_chunk can not be used in more than one plugin Apr 7, 2023
@Sn0rt
Copy link
Contributor Author

Sn0rt commented Apr 12, 2023

how to reprorude the duplicate log

to create a new test file.

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use t::APISIX 'no_plan';

no_long_string();
no_shuffle();
no_root_location();

add_block_preprocessor(sub {
    my ($block) = @_;

    if (!$block->request) {
        $block->set_value("request", "GET /t");
    }
});

run_tests;

__DATA__

=== TEST 1: simulate simple SOAP proxy
--- config
location /demo {
    content_by_lua_block {
        local core = require("apisix.core")
        local body = core.request.get_body()
        local xml2lua = require("xml2lua")
        local xmlhandler = require("xmlhandler.tree")
        local handler = xmlhandler:new()
        local parser = xml2lua.parser(handler)
        parser:parse(body)

        ngx.print(string.format([[
<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <ns2:getCountryResponse
            xmlns:ns2="http://spring.io/guides/gs-producing-web-service">
            <ns2:country>
                <ns2:name>%s</ns2:name>
                <ns2:population>46704314</ns2:population>
                <ns2:capital>Madrid</ns2:capital>
                <ns2:currency>EUR</ns2:currency>
            </ns2:country>
        </ns2:getCountryResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
        ]], handler.root["soap-env:Envelope"]["soap-env:Body"]["ns0:getCountryRequest"]["ns0:name"]))
    }
}
    location /t {
        content_by_lua_block {
            local t = require("lib.test_admin")

            local req_template = ngx.encode_base64[[
<?xml version="1.0"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
 <soap-env:Body>
  <ns0:getCountryRequest xmlns:ns0="http://spring.io/guides/gs-producing-web-service">
   <ns0:name>{{_escape_xml(name)}}</ns0:name>
  </ns0:getCountryRequest>
 </soap-env:Body>
</soap-env:Envelope>
            ]]

            local rsp_template = ngx.encode_base64[[
{% if Envelope.Body.Fault == nil then %}
{
   "status":"{{_ctx.var.status}}",
   "currency":"{{Envelope.Body.getCountryResponse.country.currency}}",
   "population":{{Envelope.Body.getCountryResponse.country.population}},
   "capital":"{{Envelope.Body.getCountryResponse.country.capital}}",
   "name":"{{Envelope.Body.getCountryResponse.country.name}}"
}
{% else %}
{
   "message":{*_escape_json(Envelope.Body.Fault.faultstring[1])*},
   "code":"{{Envelope.Body.Fault.faultcode}}"
   {% if Envelope.Body.Fault.faultactor ~= nil then %}
   , "actor":"{{Envelope.Body.Fault.faultactor}}"
   {% end %}
}
{% end %}
            ]]

            local code, body = t.test('/apisix/admin/routes/1',
                ngx.HTTP_PUT,
                string.format([[{
                    "uri": "/ws",
                    "plugins": {
                        "proxy-rewrite": {
                            "uri": "/demo"
                        },
                        "body-transformer": {
                            "request": {
                                "template": "%s"
                            },
                            "response": {
                                "input_format": "xml",
                                "template": "%s"
                            }
                        }
                    },
                    "upstream": {
                        "type": "roundrobin",
                        "nodes": {
                            "127.0.0.1:%d": 1
                        }
                    }
                }]], req_template, rsp_template, ngx.var.server_port)
            )

            if code >= 300 then
                ngx.status = code
                return
            end

            local code, body = t.test('/apisix/admin/global_rules/1',
                ngx.HTTP_PUT,
                [[{
                    "plugins": {
                        "http-logger": {
                            "uri": "http://127.0.0.1:1980/log",
                            "batch_max_size": 1,
                            "include_resp_body": true
                        }
                    }
                }]]
                )

            if code >= 300 then
                ngx.status = code
                return
            end

            ngx.sleep(0.5)

            local core = require("apisix.core")
            local http = require("resty.http")
            local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/ws"
            local body = [[{"name": "Spain"}]]
            local opt = {method = "POST", body = body, headers = {["Content-Type"] = "application/json"}}
            local httpc = http.new()
            local res = httpc:request_uri(uri, opt)
            assert(res.status == 200)
            local data1 = core.json.decode(res.body)
            local data2 = core.json.decode[[{"status":"200","currency":"EUR","population":46704314,"capital":"Madrid","name":"Spain"}]]
            assert(core.json.stably_encode(data1), core.json.stably_encode(data2))
        }
    }

try to run test file and ignore the output of test.

$ prove -I. -I../test-nginx/inc -I../test-nginx/lib -r t/plugin/body-transformer.t

to check the log of apisix.
and you will find the log of response body has been duplicated

23/04/12 06:09:41 [info] 52938#52938: *158 [lua] balancer.lua:384: run(): proxy request to 127.0.0.1:1984 while connecting to upstream, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:180: hold_body_chunk(): nil while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:181: hold_body_chunk(): Stack trace
stack traceback:
	/home/ubuntu/apisix/apisix/core/response.lua:181: in function 'hold_body_chunk'
	/home/ubuntu/apisix/apisix/utils/log-util.lua:298: in function 'collect_body'
	/home/ubuntu/apisix/apisix/plugins/http-logger.lua:153: in function 'phase_func'
	/home/ubuntu/apisix/apisix/plugin.lua:1131: in function 'run_plugin'
	/home/ubuntu/apisix/apisix/plugin.lua:1164: in function 'run_global_rules'
	/home/ubuntu/apisix/apisix/init.lua:402: in function 'common_phase'
	/home/ubuntu/apisix/apisix/init.lua:746: in function 'http_body_filter_phase'
	body_filter_by_lua:2: in main chunk while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:182: hold_body_chunk(): null while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [info] 52938#52938: *158 [lua] response.lua:183: hold_body_chunk():  chunk <SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <ns2:getCountryResponse
            xmlns:ns2="http://spring.io/guides/gs-producing-web-service">
            <ns2:country>
                <ns2:name>Spain</ns2:name>
                <ns2:population>46704314</ns2:population>
                <ns2:capital>Madrid</ns2:capital>
                <ns2:currency>EUR</ns2:currency>
            </ns2:country>
        </ns2:getCountryResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
         oef false while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:180: hold_body_chunk(): table: 0x7f8bb45e7d38 while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:181: hold_body_chunk(): Stack trace
stack traceback:
	/home/ubuntu/apisix/apisix/core/response.lua:181: in function 'hold_body_chunk'
	/home/ubuntu/apisix/apisix/plugins/body-transformer.lua:195: in function 'phase_func'
	/home/ubuntu/apisix/apisix/plugin.lua:1131: in function 'common_phase'
	/home/ubuntu/apisix/apisix/init.lua:746: in function 'http_body_filter_phase'
	body_filter_by_lua:2: in main chunk while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:182: hold_body_chunk(): {"1":"<SOAP-ENV:Envelope\n    xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n    <SOAP-ENV:Header/>\n    <SOAP-ENV:Body>\n        <ns2:getCountryResponse\n            xmlns:ns2=\"http://spring.io/guides/gs-producing-web-service\">\n            <ns2:country>\n                <ns2:name>Spain</ns2:name>\n                <ns2:population>46704314</ns2:population>\n                <ns2:capital>Madrid</ns2:capital>\n                <ns2:currency>EUR</ns2:currency>\n            </ns2:country>\n        </ns2:getCountryResponse>\n    </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n        ","n":1} while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [info] 52938#52938: *158 [lua] response.lua:183: hold_body_chunk():  chunk <SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <ns2:getCountryResponse
            xmlns:ns2="http://spring.io/guides/gs-producing-web-service">
            <ns2:country>
                <ns2:name>Spain</ns2:name>
                <ns2:population>46704314</ns2:population>
                <ns2:capital>Madrid</ns2:capital>
                <ns2:currency>EUR</ns2:currency>
            </ns2:country>
        </ns2:getCountryResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
         oef false while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:180: hold_body_chunk(): table: 0x7f8bb45e7d38 while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:181: hold_body_chunk(): Stack trace
stack traceback:
	/home/ubuntu/apisix/apisix/core/response.lua:181: in function 'hold_body_chunk'
	/home/ubuntu/apisix/apisix/utils/log-util.lua:298: in function 'collect_body'
	/home/ubuntu/apisix/apisix/plugins/http-logger.lua:153: in function 'phase_func'
	/home/ubuntu/apisix/apisix/plugin.lua:1131: in function 'run_plugin'
	/home/ubuntu/apisix/apisix/plugin.lua:1164: in function 'run_global_rules'
	/home/ubuntu/apisix/apisix/init.lua:402: in function 'common_phase'
	/home/ubuntu/apisix/apisix/init.lua:746: in function 'http_body_filter_phase'
	body_filter_by_lua:2: in main chunk while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:182: hold_body_chunk(): {"1":"<SOAP-ENV:Envelope\n    xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n    <SOAP-ENV:Header/>\n    <SOAP-ENV:Body>\n        <ns2:getCountryResponse\n            xmlns:ns2=\"http://spring.io/guides/gs-producing-web-service\">\n            <ns2:country>\n                <ns2:name>Spain</ns2:name>\n                <ns2:population>46704314</ns2:population>\n                <ns2:capital>Madrid</ns2:capital>\n                <ns2:currency>EUR</ns2:currency>\n            </ns2:country>\n        </ns2:getCountryResponse>\n    </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n        ","2":"<SOAP-ENV:Envelope\n    xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n    <SOAP-ENV:Header/>\n    <SOAP-ENV:Body>\n        <ns2:getCountryResponse\n            xmlns:ns2=\"http://spring.io/guides/gs-producing-web-service\">\n            <ns2:country>\n                <ns2:name>Spain</ns2:name>\n                <ns2:population>46704314</ns2:population>\n                <ns2:capital>Madrid</ns2:capital>\n                <ns2:currency>EUR</ns2:currency>\n            </ns2:country>\n        </ns2:getCountryResponse>\n    </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n        ","n":2} while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [info] 52938#52938: *158 [lua] response.lua:183: hold_body_chunk():  chunk  oef true while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:180: hold_body_chunk(): nil while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:181: hold_body_chunk(): Stack trace
stack traceback:
	/home/ubuntu/apisix/apisix/core/response.lua:181: in function 'hold_body_chunk'
	/home/ubuntu/apisix/apisix/plugins/body-transformer.lua:195: in function 'phase_func'
	/home/ubuntu/apisix/apisix/plugin.lua:1131: in function 'common_phase'
	/home/ubuntu/apisix/apisix/init.lua:746: in function 'http_body_filter_phase'
	body_filter_by_lua:2: in main chunk while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [notice] 52938#52938: *158 [lua] response.lua:182: hold_body_chunk(): null while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [info] 52938#52938: *158 [lua] response.lua:183: hold_body_chunk():  chunk  oef true while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [error] 52938#52938: *158 [lua] body-transformer.lua:145: transform(): response template rendering: [string "context=... or {}..."]:5: attempt to index global 'Envelope' (a nil value) while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [error] 52938#52938: *158 [lua] body-transformer.lua:202: phase_func(): failed to transform response body:  while sending to client, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [info] 52938#52938: *158 [lua] log-util.lua:215: get_log_entry(): metadata: null while logging request, client: 127.0.0.1, server: localhost, request: "POST /ws HTTP/1.1", upstream: "http://127.0.0.1:1984/demo", host: "127.0.0.1:1984"
2023/04/12 06:09:41 [info] 52938#52938: *163 [lua] http-logger.lua:91: func(): sending a batch logs to http://127.0.0.1:1980/log, context: ngx.timer, client: 127.0.0.1, server: 0.0.0.0:1984
2023/04/12 06:09:41 [warn] 52938#52938: *165 [lua] server.lua:444: go(): request log: {"apisix_latency":99.999998092651,"client_ip":"127.0.0.1","latency":101.99999809265,"request":{"headers":{"content-length":"313","content-type":"application/json","host":"127.0.0.1:1984","user-agent":"lua-resty-http/0.16.1 (Lua) ngx_lua/10021"},"method":"POST","querystring":{},"size":167,"uri":"/ws","url":"http://127.0.0.1:1984/ws"},"response":{"body":"<SOAP-ENV:Envelope\n    xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n    <SOAP-ENV:Header/>\n    <SOAP-ENV:Body>\n        <ns2:getCountryResponse\n            xmlns:ns2=\"http://spring.io/guides/gs-producing-web-service\">\n            <ns2:country>\n                <ns2:name>Spain</ns2:name>\n                <ns2:population>46704314</ns2:population>\n                <ns2:capital>Madrid</ns2:capital>\n                <ns2:currency>EUR</ns2:currency>\n            </ns2:country>\n        </ns2:getCountryResponse>\n    </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n        <SOAP-ENV:Envelope\n    xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n    <SOAP-ENV:Header/>\n    <SOAP-ENV:Body>\n        <ns2:getCountryResponse\n            xmlns:ns2=\"http://spring.io/guides/gs-producing-web-service\">\n            <ns2:country>\n                <ns2:name>Spain</ns2:name>\n                <ns2:population>46704314</ns2:population>\n                <ns2:capital>Madrid</ns2:capital>\n                <ns2:currency>EUR</ns2:currency>\n            </ns2:country>\n        </ns2:getCountryResponse>\n    </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n        ","headers":{"connection":"close","content-type":"text/plain","date":"Wed, 12 Apr 2023 06:09:41 GMT","server":"APISIX/3.2.0","transfer-encoding":"chunked"},"size":161,"status":200},"route_id":"1","server":{"hostname":"ip-172-31-36-124","version":"3.2.0"},"service_id":"","start_time":1681279781019,"upstream":"127.0.0.1:1984","upstream_latency":2}, client: 127.0.0.1, server: , request: "POST /log? HTTP/1.1", host: "127.0.0.1"
2023/04/12 06:09:41 [info] 52938#52938: *165 client 127.0.0.1 closed keepalive connection
2023/04/12 06:09:41 [notice] 52937#52937: signal 15 (SIGTERM)

@@ -486,7 +486,7 @@ GET /grpc_plus?a=1&b=2
--- response_body eval
qr/\{"result":3\}/
--- error_log eval
qr/request log: \{.*body":\"\\u0000\\u0000\\u0000\\u0000\\u0002\\b\\u0003\\u0000\\u0000\\u0000\\u0000\\u0002\\b\\u0003"/
qr/request log: \{.*body":\"\\u0000\\u0000\\u0000\\u0000\\u0002\\b\\u0003"/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR fixes another bug: insert the same chunk twice (by different plugins) into the body_buffer.

Bug reproduce:

diff --git a/apisix/core/response.lua b/apisix/core/response.lua
index b934d94b..971961b3 100644
--- a/apisix/core/response.lua
+++ b/apisix/core/response.lua
@@ -178,6 +178,8 @@ function _M.hold_body_chunk(ctx, hold_the_copy)
     local body_buffer
     local chunk, eof = arg[1], arg[2]
     if type(chunk) == "string" and chunk ~= "" then
+        ngx.log(ngx.WARN, "#chunk: ", #chunk)
+        ngx.log(ngx.WARN, debug.traceback("hold_body_chunk", 3))
         body_buffer = ctx._body_buffer
         if not body_buffer then
             body_buffer = {
@@ -185,10 +187,13 @@ function _M.hold_body_chunk(ctx, hold_the_copy)
                 n = 1
             }
             ctx._body_buffer = body_buffer
+            ngx.log(ngx.WARN, "create body_buffer: ", tostring(body_buffer))
+            ngx.log(ngx.WARN, "init #chunk: ", #chunk)
         else
             local n = body_buffer.n + 1
             body_buffer.n = n
             body_buffer[n] = chunk
+            ngx.log(ngx.WARN, "add #chunk: ", #chunk)
         end
     end

error.log from this test case:

2023/04/12 18:08:06 [warn] 2785045#2785045: *3 [lua] response.lua:181: hold_body_chunk(): #chunk: 7 while sending to client, client: 127.0.0.1, server: localhost, request: "GET /grpc_plus?a=1&b=2 HTTP/1.1", upstream: "grpc://127.0.0.1:50051", host: "localhost"
2023/04/12 18:08:06 [warn] 2785045#2785045: *3 [lua] response.lua:182: hold_body_chunk(): hold_body_chunk
stack traceback:
        /opt/apisix/apisix/plugins/http-logger.lua:153: in function 'phase_func'
        /opt/apisix/apisix/plugin.lua:1131: in function 'run_plugin'
        /opt/apisix/apisix/plugin.lua:1164: in function 'run_global_rules'
        /opt/apisix/apisix/init.lua:403: in function 'common_phase'
        /opt/apisix/apisix/init.lua:747: in function 'http_body_filter_phase'
        body_filter_by_lua:2: in main chunk while sending to client, client: 127.0.0.1, server: localhost, request: "GET /grpc_plus?a=1&b=2 HTTP/1.1", upstream: "grpc://127.0.0.1:50051", host: "localhost"
2023/04/12 18:08:06 [warn] 2785045#2785045: *3 [lua] response.lua:190: hold_body_chunk(): create body_buffer: table: 0x7f4aede1e4c8 while sending to client, client: 127.0.0.1, server: localhost, request: "GET /grpc_plus?a=1&b=2 HTTP/1.1", upstream: "grpc://127.0.0.1:50051", host: "localhost"
2023/04/12 18:08:06 [warn] 2785045#2785045: *3 [lua] response.lua:191: hold_body_chunk(): init #chunk: 7 while sending to client, client: 127.0.0.1, server: localhost,request: "GET /grpc_plus?a=1&b=2 HTTP/1.1", upstream: "grpc://127.0.0.1:50051", host: "localhost"
2023/04/12 18:08:06 [warn] 2785045#2785045: *3 [lua] response.lua:181: hold_body_chunk(): #chunk: 7 while sending to client, client: 127.0.0.1, server: localhost, request: "GET /grpc_plus?a=1&b=2 HTTP/1.1", upstream: "grpc://127.0.0.1:50051", host: "localhost"
2023/04/12 18:08:06 [warn] 2785045#2785045: *3 [lua] response.lua:182: hold_body_chunk(): hold_body_chunk
stack traceback:
        /opt/apisix/apisix/plugins/grpc-transcode.lua:202: in function 'phase_func'
        /opt/apisix/apisix/plugin.lua:1131: in function 'common_phase'
        /opt/apisix/apisix/init.lua:747: in function 'http_body_filter_phase'
        body_filter_by_lua:2: in main chunk while sending to client, client: 127.0.0.1, server: localhost, request: "GET /grpc_plus?a=1&b=2 HTTP/1.1", upstream: "grpc://127.0.0.1:50051", host: "localhost"
2023/04/12 18:08:06 [warn] 2785045#2785045: *3 [lua] response.lua:196: hold_body_chunk(): add #chunk: 7 while sending to client, client: 127.0.0.1, server: localhost, request: "GET /grpc_plus?a=1&b=2 HTTP/1.1", upstream: "grpc://127.0.0.1:50051", host: "localhost"
2023/04/12 18:08:06 [warn] 2785045#2785045: *3 [lua] response.lua:110: response(): #buffer: 14 while sending to client, client: 127.0.0.1, server: localhost, request: "GET /grpc_plus?a=1&b=2 HTTP/1.1", upstream: "grpc://127.0.0.1:50051", host: "localhost"

@monkeyDluffy6017
Copy link
Contributor

monkeyDluffy6017 commented Apr 13, 2023

Hi @Sn0rt, this pr seems have a long description, and it fix several problems, right?
But it's very hard to understand.
For the pr title hold_body_chunk can not be used in more than one plugin, i don't see any test cases about this?

@kingluo kingluo changed the title fix: hold_body_chunk can not be used in more than one plugin fix: hold_body_chunk should use seperate buffer for each plugin in case of pollution Apr 13, 2023
@kingluo
Copy link
Contributor

kingluo commented Apr 13, 2023

Hi @Sn0rt, this pr seems have a long description, and it fix several problems, right? But it's very hard to understand. For the pr title hold_body_chunk can not be used in more than one plugin, i don't see any test cases about this?

I change the title. It's for use by body filter plugins to work together.

@monkeyDluffy6017
Copy link
Contributor

I change the title. It's for use by body filter plugins to work together.

Could you add test cases to prove that the current body filter plugins can't work together?

@kingluo
Copy link
Contributor

kingluo commented Apr 13, 2023

I change the title. It's for use by body filter plugins to work together.

Could you add test cases to prove that the current body filter plugins can't work together?

It is used by #9267.
That is, this is a side issue, The test case you need is right here: #9267, where body-transformer and proxy-mirror both use hold_body_chunk. Moreover, the bugfix of this old test case is also another example: #9266 (comment)

@Sn0rt
Copy link
Contributor Author

Sn0rt commented Apr 13, 2023

I change the title. It's for use by body filter plugins to work together.

Could you add test cases to prove that the current body filter plugins can't work together?

I think it's unnecessary. the reasons is you can found the second commit of this PR.
I remove the dulicated log from test case. and to construct a new test for prove.

@monkeyDluffy6017 monkeyDluffy6017 merged commit f39cadd into apache:master Apr 13, 2023
AlinsRan pushed a commit to AlinsRan/apisix that referenced this pull request Jun 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug: hold_body_chunk can not be used in more than one plugin
6 participants