-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
What happened:
使用下列的pb生成 http代码, 使用 json payload正常, 但使用pb序列化后, 解析 request panic
// 客户端
message Client {
option (google.api.resource) = {
type: "v1.greeter.test.example.com/Client"
pattern: "clients/{client_int32}"
};
// 资源名称
string name = 1;
// id
int32 id = 2;
// 状态
ClientStatus status = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
string display_name = 4 ;
}
service ExampleService {
// 创建Client
// (-- api-linter: core::0133::method-signature=disabled
// aip.dev/not-precedent: 顶层资源无需parent --)
rpc CreateClient(CreateClientRequest) returns (CreateClientResponse) {
option (google.api.method_signature) = "client";
option (google.api.http) = {
post: "/api/v1/clients"
body: "client"
};
}
}
// 创建Client请求
message CreateClientRequest {
// 创建Client
Client client = 1 [(google.api.field_behavior) = REQUIRED];
}
// 创建Client响应
message CreateClientResponse {
// 创建Client响应
Client client = 1 [(google.api.field_behavior) = REQUIRED];
}
从json转成pb,后端无需修改代码, 前端修改 Content-Type : application/proto
. 具体的代码实现在 github.com/go-kratos/kratos/v2/transport/http/codec.go
// CodecForRequest get encoding.Codec via http.Request
func CodecForRequest(r *http.Request, name string) (encoding.Codec, bool) {
for _, accept := range r.Header[name] {
codec := encoding.GetCodec(httputil.ContentSubtype(accept))
if codec != nil {
return codec, true
}
}
return encoding.GetCodec("json"), false
}
原因
panic 日志
2023/04/12 14:16:11 http: panic serving 192.168.105.20:49928: interface conversion: **v1.Client is not protoreflect.ProtoMessage: missing method ProtoReflect
goroutine 107 [running]:
net/http.(*conn).serve.func1()
/data/go1.19/src/net/http/server.go:1850 +0x148
panic({0x13f86a0, 0xc0004aa480})
/data/go1.19/src/runtime/panic.go:890 +0x267
github.com/go-kratos/kratos/v2/encoding/proto.codec.Unmarshal({}, {0xc000570400, 0x13, 0x200}, {0x134db20, 0xc0004aa478})
/data/common/kratos-layout/vendor/github.com/go-kratos/kratos/v2/encoding/proto/proto.go:26 +0x67
github.com/go-kratos/kratos/v2/transport/http.DefaultRequestDecoder(0xc00050cc00, {0x134db20, 0xc0004aa478})
/data/common/kratos-layout/vendor/github.com/go-kratos/kratos/v2/transport/http/codec.go:72 +0x286
github.com/go-kratos/kratos/v2/transport/http.(*wrapper).Bind(0xc000518980, {0x134db20, 0xc0004aa478})
/data/common/kratos-layout/vendor/github.com/go-kratos/kratos/v2/transport/http/context.go:99 +0x62
go.example.com/apis/lixin/test/kratos-layout/v1._KratoLayoutService_CreateClient0_HTTP_Handler.func1({0x7f03b05effc8, 0xc000518980})
github.com/go-kratos/kratos/v2/encoding/proto/proto.go
func (codec) Unmarshal(data []byte, v interface{}) error {
// v 是一个二级指针 (**Client)
// v 是一个二级指针 (**Client)
// v 是一个二级指针 (**Client)
return proto.Unmarshal(data, v.(proto.Message))
}
生成的Go代码如下
// 创建Client请求
type CreateClientRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// 注意这里是指针
// 注意这里是指针
// 注意这里是指针
Client *Client `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"`
}
func _KratoLayoutService_CreateClient0_HTTP_Handler(srv KratoLayoutServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in CreateClientRequest
// 这里进一步取指针的地址
// 这里进一步取指针的地址
// 这里进一步取指针的地址
if err := ctx.Bind(&in.Client); err != nil {
return err
}
// 。。。。。。。
return ctx.Result(200, reply)
}
}
What you expected to happen:
How to reproduce it (as minimally and precisely as possible):
Anything else we need to know?:
Environment:
- Kratos version (use
kratos -v
): github.com/go-kratos/kratos/v2 v2.5.3 - Go version (use
go version
): 1.19 - OS (e.g:
cat /etc/os-release
):
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
- Others:
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working