From 48aa25cbaffe5dae66f8ee683e9079e131bc9a0b Mon Sep 17 00:00:00 2001 From: Andreas Dewes Date: Wed, 15 Sep 2021 12:56:51 +0200 Subject: [PATCH] Ensure gRPC struct data is always a (nested) string map. --- grpc/server.go | 13 +++++++++++-- helpers/structs.go | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 helpers/structs.go diff --git a/grpc/server.go b/grpc/server.go index 2ab3f90..9e45b76 100644 --- a/grpc/server.go +++ b/grpc/server.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "github.com/iris-connect/eps" + "github.com/iris-connect/eps/helpers" epsNet "github.com/iris-connect/eps/net" "github.com/iris-connect/eps/protobuf" "github.com/iris-connect/eps/tls" @@ -227,7 +228,11 @@ func (s *Server) Call(context context.Context, pbRequest *protobuf.Request) (*pr } if response != nil { if response.Result != nil { - resultStruct, err := structpb.NewStruct(response.Result) + stringMap, err := helpers.ToStringMap(response.Result) + if err != nil { + return nil, fmt.Errorf("error converting result to string map: %w", err) + } + resultStruct, err := structpb.NewStruct(stringMap) if err != nil { return nil, fmt.Errorf("error serializing response for gRPC: %w", err) } @@ -240,7 +245,11 @@ func (s *Server) Call(context context.Context, pbRequest *protobuf.Request) (*pr } if response.Error.Data != nil { - errorStruct, err := structpb.NewStruct(response.Error.Data) + stringMap, err := helpers.ToStringMap(response.Error.Data) + if err != nil { + return nil, fmt.Errorf("error converting error data to string map: %w", err) + } + errorStruct, err := structpb.NewStruct(stringMap) if err != nil { return nil, fmt.Errorf("error serializing error data for gRPC: %w", err) } diff --git a/helpers/structs.go b/helpers/structs.go new file mode 100644 index 0000000..58a10b6 --- /dev/null +++ b/helpers/structs.go @@ -0,0 +1,17 @@ +package helpers + +import ( + "encoding/json" +) + +// convert an arbitrary structure to a string map via the JSON encoding +func ToStringMap(value interface{}) (map[string]interface{}, error) { + var out map[string]interface{} + if jsonData, err := json.Marshal(value); err != nil { + return nil, err + } else if err := json.Unmarshal(jsonData, &out); err != nil { + return nil, err + } else { + return out, nil + } +}