This is an automated email from the ASF dual-hosted git repository. shuyangw 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 9db2dd2 fix(grpc-transcode): handle enum type (#4706) 9db2dd2 is described below commit 9db2dd2399c3970df1e1b7fa0f8b7dcd92d26b1c Author: 罗泽轩 <spacewander...@gmail.com> AuthorDate: Sun Aug 1 04:27:11 2021 +0800 fix(grpc-transcode): handle enum type (#4706) Signed-off-by: spacewander <spacewander...@gmail.com> --- apisix/plugins/grpc-transcode.lua | 6 +- apisix/plugins/grpc-transcode/request.lua | 9 +- apisix/plugins/grpc-transcode/util.lua | 3 +- ci/common.sh | 2 +- t/plugin/grpc-transcode.t | 154 ++++++++++++++++++++++++++++++ 5 files changed, 165 insertions(+), 9 deletions(-) diff --git a/apisix/plugins/grpc-transcode.lua b/apisix/plugins/grpc-transcode.lua index 98dd3f9..b9ed7ab 100644 --- a/apisix/plugins/grpc-transcode.lua +++ b/apisix/plugins/grpc-transcode.lua @@ -120,11 +120,11 @@ function _M.access(conf, ctx) return end - local ok, err = request(proto_obj, conf.service, - conf.method, conf.pb_option, conf.deadline) + local ok, err, err_code = request(proto_obj, conf.service, + conf.method, conf.pb_option, conf.deadline) if not ok then core.log.error("transform request error: ", err) - return + return err_code end ctx.proto_obj = proto_obj diff --git a/apisix/plugins/grpc-transcode/request.lua b/apisix/plugins/grpc-transcode/request.lua index 0775321..3af710e 100644 --- a/apisix/plugins/grpc-transcode/request.lua +++ b/apisix/plugins/grpc-transcode/request.lua @@ -23,6 +23,7 @@ local ngx = ngx local string = string local table = table local ipairs = ipairs +local pcall = pcall local tonumber = tonumber local req_read_body = ngx.req.read_body @@ -31,7 +32,7 @@ return function (proto, service, method, pb_option, deadline, default_values) local m = util.find_method(proto, service, method) if not m then return false, "Undefined service method: " .. service .. "/" .. method - .. " end" + .. " end", 503 end req_read_body() @@ -43,10 +44,10 @@ return function (proto, service, method, pb_option, deadline, default_values) end local map_message = util.map_message(m.input_type, default_values or {}) - local encoded = pb.encode(m.input_type, map_message) + local ok, encoded = pcall(pb.encode, m.input_type, map_message) - if not encoded then - return false, "failed to encode request data to protobuf" + if not ok or not encoded then + return false, "failed to encode request data to protobuf", 400 end local size = #encoded diff --git a/apisix/plugins/grpc-transcode/util.lua b/apisix/plugins/grpc-transcode/util.lua index da76426..faffecc 100644 --- a/apisix/plugins/grpc-transcode/util.lua +++ b/apisix/plugins/grpc-transcode/util.lua @@ -100,7 +100,8 @@ function _M.map_message(field, default_values) 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 + local _, _, ty = pb.type(field_type) + if ty ~= "enum" and field_type:sub(1, 1) == "." then sub, err = _M.map_message(field_type, default_values) if err then return nil, err diff --git a/ci/common.sh b/ci/common.sh index a6b7814..56f2d33 100644 --- a/ci/common.sh +++ b/ci/common.sh @@ -31,4 +31,4 @@ create_lua_deps() { # luarocks install luacov-coveralls --tree=deps --local > build.log 2>&1 || (cat build.log && exit 1) } -GRPC_SERVER_EXAMPLE_VER=20210417 +GRPC_SERVER_EXAMPLE_VER=20210730 diff --git a/t/plugin/grpc-transcode.t b/t/plugin/grpc-transcode.t index c87ba56..78baac0 100644 --- a/t/plugin/grpc-transcode.t +++ b/t/plugin/grpc-transcode.t @@ -661,3 +661,157 @@ passed GET /t --- no_error_log [error] + + + +=== TEST 23: set proto with enum +--- 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) {} + } + enum Gender { + GENDER_UNKNOWN = 0; + GENDER_MALE = 1; + GENDER_FEMALE = 2; + } + message HelloRequest { + string name = 1; + repeated string items = 2; + Gender gender = 3; + } + message HelloReply { + string message = 1; + repeated string items = 2; + Gender gender = 3; + }" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 24: hit route, no gender +--- request +POST /grpctest +{"name":"world"} +--- more_headers +Content-Type: application/json +--- response_body eval +qr/"gender":"GENDER_UNKNOWN"/ +--- no_error_log +[error] + + + +=== TEST 25: hit route, gender is a value +--- request +POST /grpctest +{"name":"world","gender":2} +--- more_headers +Content-Type: application/json +--- response_body eval +qr/"gender":"GENDER_FEMALE"/ +--- no_error_log +[error] + + + +=== TEST 26: hit route, gender is a name +--- request +POST /grpctest +{"name":"world","gender":"GENDER_MALE"} +--- more_headers +Content-Type: application/json +--- response_body eval +qr/"gender":"GENDER_MALE"/ +--- no_error_log +[error] + + + +=== TEST 27: hit route, bad gender +--- request +POST /grpctest +{"name":"world","gender":"GENDER_MA"} +--- more_headers +Content-Type: application/json +--- error_code: 400 +--- error_log +failed to encode request data to protobuf + + + +=== TEST 28: set routes(decode enum as value) +--- 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", + "pb_option":["enum_as_value"] + } + }, + "upstream": { + "scheme": "grpc", + "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 29: hit route +--- request +POST /grpctest +{"name":"world","gender":2} +--- more_headers +Content-Type: application/json +--- response_body eval +qr/"gender":2/ +--- no_error_log +[error]