bugfix: grpc-transcode plugin converts http/json parameters abnormally (#2139)

* fix bug

* optimiz

* update grpc_server_example

* add test cases

* fix: test case

* fix: test case

* return val directly

* fix: test case respond body compare text

* fix test case error

Co-authored-by: Wen Ming <moonbingbing@gmail.com>
This commit is contained in:
nic-chen 2020-09-10 18:02:16 +08:00 committed by GitHub
parent 37817e4198
commit 087f87a7e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 127 additions and 20 deletions

View File

@ -99,7 +99,7 @@ do_install() {
ls -l ./
if [ ! -f "build-cache/grpc_server_example" ]; then
wget https://github.com/iresty/grpc_server_example/releases/download/20200314/grpc_server_example-amd64.tar.gz
wget https://github.com/iresty/grpc_server_example/releases/download/20200901/grpc_server_example-amd64.tar.gz
tar -xvf grpc_server_example-amd64.tar.gz
mv grpc_server_example build-cache/
fi

View File

@ -268,7 +268,7 @@ do_install() {
ls -l ./
if [ ! -f "build-cache/grpc_server_example" ]; then
wget https://github.com/iresty/grpc_server_example/releases/download/20200314/grpc_server_example-amd64.tar.gz
wget https://github.com/iresty/grpc_server_example/releases/download/20200901/grpc_server_example-amd64.tar.gz
tar -xvf grpc_server_example-amd64.tar.gz
mv grpc_server_example build-cache/
fi

View File

@ -51,7 +51,7 @@ do_install() {
wget -P utils https://raw.githubusercontent.com/openresty/openresty-devel-utils/master/lj-releng
chmod a+x utils/lj-releng
wget https://github.com/iresty/grpc_server_example/releases/download/20200314/grpc_server_example-darwin-amd64.tar.gz
wget https://github.com/iresty/grpc_server_example/releases/download/20200901/grpc_server_example-darwin-amd64.tar.gz
tar -xvf grpc_server_example-darwin-amd64.tar.gz
brew install grpcurl

View File

@ -14,7 +14,8 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local json = require("apisix.core.json")
local core = require("apisix.core")
local json = core.json
local pb = require("pb")
local ngx = ngx
local pairs = pairs
@ -47,24 +48,35 @@ function _M.find_method(protos, service, method)
end
local function get_from_request(name, kind)
local request_table
if ngx.req.get_method() == "POST" then
if string.find(ngx.req.get_headers()["Content-Type"] or "",
"application/json", 1, true) then
request_table = json.decode(ngx.req.get_body_data())
else
request_table = ngx.req.get_post_args()
local function get_request_table()
local method = ngx.req.get_method()
local content_type = ngx.req.get_headers()["Content-Type"] or ""
if string.find(content_type, "application/json", 1, true) and
(method == "POST" or method == "PUT" or method == "PATCH")
then
local req_body, _ = core.request.get_body()
if req_body then
local data, _ = json.decode(req_body)
if data then
return data
end
else
request_table = ngx.req.get_uri_args()
end
end
if method == "POST" then
return ngx.req.get_post_args()
end
return ngx.req.get_uri_args()
end
local function get_from_request(request_table, name, kind)
if not request_table then
return nil
end
local prefix = kind:sub(1, 3)
if prefix == "str" then
return request_table[name] or nil
end
if prefix == "int" then
if request_table[name] then
if kind == "int64" then
@ -75,7 +87,7 @@ local function get_from_request(name, kind)
end
end
return nil
return request_table[name]
end
@ -86,6 +98,7 @@ function _M.map_message(field, default_values)
local request = {}
local sub, err
local request_table = get_request_table()
for name, _, field_type in pb.fields(field) do
if field_type:sub(1, 1) == "." then
sub, err = _M.map_message(field_type, default_values)
@ -94,7 +107,7 @@ function _M.map_message(field, default_values)
end
request[name] = sub
else
request[name] = get_from_request(name, field_type)
request[name] = get_from_request(request_table, name, field_type)
or default_values[name] or nil
end
end

View File

@ -485,3 +485,97 @@ GET /t
{"error_msg":"failed to check the configuration of plugin grpc-transcode err: property \"method\" is required"}
--- no_error_log
[error]
=== TEST 18: set proto(id: 1, with array parameter)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/proto/1',
ngx.HTTP_PUT,
[[{
"content" : "syntax = \"proto3\";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
repeated string items = 2;
}
message HelloReply {
string message = 1;
repeated string items = 2;
}"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]
=== TEST 19: set routes(id: 1, with array parameter)
--- 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,
[[{
"methods": ["GET", "POST"],
"uri": "/grpctest",
"service_protocol": "grpc",
"plugins": {
"grpc-transcode": {
"proto_id": "1",
"service": "helloworld.Greeter",
"method": "SayHello"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:50051": 1
}
}
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]
=== TEST 20: hit route
--- request
POST /grpctest
{"name":"apisix", "items": ["a","b","c"]}
--- more_headers
Content-Type: application/json
--- response_body eval
qr/\{"items":\["a","b","c"\],"message":"Hello apisix"\}/
--- no_error_log
[error]