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 e7ceda0 feat(ext-plugin): support to get request body (#5600) e7ceda0 is described below commit e7ceda0387909ba41c0eb90a897c7b70e1e96545 Author: tzssangglass <tzssanggl...@gmail.com> AuthorDate: Sun Nov 28 20:41:06 2021 -0600 feat(ext-plugin): support to get request body (#5600) --- apisix/plugins/ext-plugin/init.lua | 12 +++ t/lib/ext-plugin.lua | 31 +++++- t/plugin/ext-plugin/request-body.t | 201 +++++++++++++++++++++++++++++++++++++ 3 files changed, 243 insertions(+), 1 deletion(-) diff --git a/apisix/plugins/ext-plugin/init.lua b/apisix/plugins/ext-plugin/init.lua index 1a8fc9c..1e3ff0c 100644 --- a/apisix/plugins/ext-plugin/init.lua +++ b/apisix/plugins/ext-plugin/init.lua @@ -28,6 +28,7 @@ local extra_info = require("A6.ExtraInfo.Info") local extra_info_req = require("A6.ExtraInfo.Req") local extra_info_var = require("A6.ExtraInfo.Var") local extra_info_resp = require("A6.ExtraInfo.Resp") +local extra_info_reqbody = require("A6.ExtraInfo.ReqBody") local text_entry = require("A6.TextEntry") local err_resp = require("A6.Err.Resp") local err_code = require("A6.Err.Code") @@ -273,6 +274,17 @@ local function handle_extra_info(ctx, input) local var_name = var_req:Name() res = ctx.var[var_name] + elseif info_type == extra_info.ReqBody then + local info = req:Info() + local reqbody_req = extra_info_reqbody.New() + reqbody_req:Init(info.bytes, info.pos) + + local err + res, err = core.request.get_body() + if err then + core.log.error("failed to read request body: ", err) + end + else return nil, "unsupported info type: " .. info_type end diff --git a/t/lib/ext-plugin.lua b/t/lib/ext-plugin.lua index f38951a..33e87d5 100644 --- a/t/lib/ext-plugin.lua +++ b/t/lib/ext-plugin.lua @@ -33,7 +33,7 @@ local extra_info = require("A6.ExtraInfo.Info") local extra_info_req = require("A6.ExtraInfo.Req") local extra_info_var = require("A6.ExtraInfo.Var") local extra_info_resp = require("A6.ExtraInfo.Resp") - +local extra_info_reqbody = require("A6.ExtraInfo.ReqBody") local _M = {} local builder = flatbuffers.Builder(0) @@ -169,6 +169,8 @@ function _M.go(case) local entry = call_req:Args(1) assert(entry:Name() == "x") assert(entry:Value() == "z") + elseif case.get_request_body then + assert(call_req:Method() == a6_method.POST) else assert(call_req:Method() == a6_method.GET) end @@ -208,6 +210,33 @@ function _M.go(case) local res = resp:ResultAsString() assert(res == action.result, res) end + + if action.type == "reqbody" then + extra_info_reqbody.Start(builder) + local reqbody_req = extra_info_reqbody.End(builder) + build_extra_info(reqbody_req, extra_info.ReqBody) + local req = extra_info_req.End(builder) + builder:Finish(req) + data = builder:Output() + local ok, err = ext.send(sock, constants.RPC_EXTRA_INFO, data) + if not ok then + ngx.log(ngx.ERR, err) + return + end + ngx.log(ngx.WARN, "send extra info req successfully") + + local ty, data = ext.receive(sock) + if not ty then + ngx.log(ngx.ERR, data) + return + end + + assert(ty == constants.RPC_EXTRA_INFO, ty) + local buf = flatbuffers.binaryArray.New(data) + local resp = extra_info_resp.GetRootAsResp(buf, 0) + local res = resp:ResultAsString() + assert(res == action.result, res) + end end end diff --git a/t/plugin/ext-plugin/request-body.t b/t/plugin/ext-plugin/request-body.t new file mode 100644 index 0000000..fe01362 --- /dev/null +++ b/t/plugin/ext-plugin/request-body.t @@ -0,0 +1,201 @@ +# +# 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'; + +repeat_each(1); +no_long_string(); +no_root_location(); +no_shuffle(); + +add_block_preprocessor(sub { + my ($block) = @_; + + $block->set_value("stream_conf_enable", 1); + + if (!defined $block->extra_stream_config) { + my $stream_config = <<_EOC_; + server { + listen unix:\$TEST_NGINX_HTML_DIR/nginx.sock; + + content_by_lua_block { + local ext = require("lib.ext-plugin") + ext.go({}) + } + } + +_EOC_ + $block->set_value("extra_stream_config", $stream_config); + } + + my $unix_socket_path = $ENV{"TEST_NGINX_HTML_DIR"} . "/nginx.sock"; + my $cmd = $block->ext_plugin_cmd // "['sleep', '5s']"; + my $extra_yaml_config = <<_EOC_; +ext-plugin: + path_for_test: $unix_socket_path + cmd: $cmd +_EOC_ + + $block->set_value("extra_yaml_config", $extra_yaml_config); + + if (!$block->request) { + $block->set_value("request", "GET /t"); + } + + if (!$block->error_log) { + $block->set_value("no_error_log", "[error]\n[alert]"); + } +}); + +run_tests; + +__DATA__ + +=== TEST 1: add route +--- config + location /t { + content_by_lua_block { + local json = require("toolkit.json") + local t = require("lib.test_admin") + + local code, message, res = t.test('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/hello", + "plugins": { + "ext-plugin-pre-req": { + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + } + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say(message) + return + end + + ngx.say(message) + } + } +--- response_body +passed + + + +=== TEST 2: request body(text) +--- request +POST /hello +123 +--- extra_stream_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock; + + content_by_lua_block { + local ext = require("lib.ext-plugin") + local actions = { + {type = "reqbody", result = "123"}, + } + ext.go({extra_info = actions, stop = true, get_request_body = true}) + } + } +--- error_code: 405 +--- grep_error_log eval +qr/send extra info req successfully/ +--- grep_error_log_out +send extra info req successfully + + + +=== TEST 3: request body(x-www-form-urlencoded) +--- request +POST /hello +foo=bar +--- more_headers +Content-Type: application/x-www-form-urlencoded +--- extra_stream_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock; + + content_by_lua_block { + local ext = require("lib.ext-plugin") + local actions = { + {type = "reqbody", result = "foo=bar"}, + } + ext.go({extra_info = actions, stop = true, get_request_body = true}) + } + } +--- error_code: 405 +--- grep_error_log eval +qr/send extra info req successfully/ +--- grep_error_log_out +send extra info req successfully + + + +=== TEST 4: request body(json) +--- request +POST /hello +{"foo":"bar"} +--- more_headers +Content-Type: application/json +--- extra_stream_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock; + + content_by_lua_block { + local ext = require("lib.ext-plugin") + local actions = { + {type = "reqbody", result = "{\"foo\":\"bar\"}"}, + } + ext.go({extra_info = actions, stop = true, get_request_body = true}) + } + } +--- error_code: 405 +--- grep_error_log eval +qr/send extra info req successfully/ +--- grep_error_log_out +send extra info req successfully + + + +=== TEST 5: request body(nil) +--- request +POST /hello +--- extra_stream_config + server { + + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock; + + content_by_lua_block { + local ext = require("lib.ext-plugin") + local actions = { + {type = "reqbody", result = nil}, + } + ext.go({extra_info = actions, stop = true, get_request_body = true}) + } + } +--- error_code: 405 +--- grep_error_log eval +qr/send extra info req successfully/ +--- grep_error_log_out +send extra info req successfully