github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/server/grpc/codec.go (about) 1 // Copyright 2020 Asim Aslam 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // Original source: github.com/micro/go-micro/v3/server/grpc/codec.go 16 17 package grpc 18 19 import ( 20 "encoding/json" 21 "strings" 22 23 b "bytes" 24 25 "github.com/golang/protobuf/jsonpb" 26 "github.com/golang/protobuf/proto" 27 "github.com/tickoalcantara12/micro/v3/util/codec" 28 "github.com/tickoalcantara12/micro/v3/util/codec/bytes" 29 "google.golang.org/grpc" 30 "google.golang.org/grpc/encoding" 31 "google.golang.org/grpc/metadata" 32 ) 33 34 type jsonCodec struct{} 35 type bytesCodec struct{} 36 type protoCodec struct{} 37 type wrapCodec struct{ encoding.Codec } 38 39 var jsonpbMarshaler = &jsonpb.Marshaler{ 40 EnumsAsInts: false, 41 EmitDefaults: true, 42 OrigName: true, 43 } 44 45 var ( 46 defaultGRPCCodecs = map[string]encoding.Codec{ 47 "application/json": jsonCodec{}, 48 "application/proto": protoCodec{}, 49 "application/protobuf": protoCodec{}, 50 "application/octet-stream": protoCodec{}, 51 "application/grpc": protoCodec{}, 52 "application/grpc+json": jsonCodec{}, 53 "application/grpc+proto": protoCodec{}, 54 "application/grpc+bytes": bytesCodec{}, 55 "multipart/form-data": jsonCodec{}, 56 } 57 ) 58 59 func (w wrapCodec) String() string { 60 return w.Codec.Name() 61 } 62 63 func (w wrapCodec) Marshal(v interface{}) ([]byte, error) { 64 b, ok := v.(*bytes.Frame) 65 if ok { 66 return b.Data, nil 67 } 68 return w.Codec.Marshal(v) 69 } 70 71 func (w wrapCodec) Unmarshal(data []byte, v interface{}) error { 72 b, ok := v.(*bytes.Frame) 73 if ok { 74 b.Data = data 75 return nil 76 } 77 if v == nil { 78 return nil 79 } 80 return w.Codec.Unmarshal(data, v) 81 } 82 83 func (protoCodec) Marshal(v interface{}) ([]byte, error) { 84 m, ok := v.(proto.Message) 85 if !ok { 86 return nil, codec.ErrInvalidMessage 87 } 88 return proto.Marshal(m) 89 } 90 91 func (protoCodec) Unmarshal(data []byte, v interface{}) error { 92 m, ok := v.(proto.Message) 93 if !ok { 94 return codec.ErrInvalidMessage 95 } 96 return proto.Unmarshal(data, m) 97 } 98 99 func (protoCodec) Name() string { 100 return "proto" 101 } 102 103 func (jsonCodec) Marshal(v interface{}) ([]byte, error) { 104 if pb, ok := v.(proto.Message); ok { 105 s, err := jsonpbMarshaler.MarshalToString(pb) 106 return []byte(s), err 107 } 108 109 return json.Marshal(v) 110 } 111 112 func (jsonCodec) Unmarshal(data []byte, v interface{}) error { 113 if len(data) == 0 { 114 return nil 115 } 116 if pb, ok := v.(proto.Message); ok { 117 return jsonpb.Unmarshal(b.NewReader(data), pb) 118 } 119 return json.Unmarshal(data, v) 120 } 121 122 func (jsonCodec) Name() string { 123 return "json" 124 } 125 126 func (bytesCodec) Marshal(v interface{}) ([]byte, error) { 127 b, ok := v.(*[]byte) 128 if !ok { 129 return nil, codec.ErrInvalidMessage 130 } 131 return *b, nil 132 } 133 134 func (bytesCodec) Unmarshal(data []byte, v interface{}) error { 135 b, ok := v.(*[]byte) 136 if !ok { 137 return codec.ErrInvalidMessage 138 } 139 *b = data 140 return nil 141 } 142 143 func (bytesCodec) Name() string { 144 return "bytes" 145 } 146 147 type grpcCodec struct { 148 grpc.ServerStream 149 // headers 150 id string 151 target string 152 method string 153 endpoint string 154 155 c encoding.Codec 156 } 157 158 func (g *grpcCodec) ReadHeader(m *codec.Message, mt codec.MessageType) error { 159 md, _ := metadata.FromIncomingContext(g.ServerStream.Context()) 160 if m == nil { 161 m = new(codec.Message) 162 } 163 if m.Header == nil { 164 m.Header = make(map[string]string, len(md)) 165 } 166 for k, v := range md { 167 m.Header[k] = strings.Join(v, ",") 168 } 169 m.Id = g.id 170 m.Target = g.target 171 m.Method = g.method 172 m.Endpoint = g.endpoint 173 return nil 174 } 175 176 func (g *grpcCodec) ReadBody(v interface{}) error { 177 // caller has requested a frame 178 if f, ok := v.(*bytes.Frame); ok { 179 return g.ServerStream.RecvMsg(f) 180 } 181 return g.ServerStream.RecvMsg(v) 182 } 183 184 func (g *grpcCodec) Write(m *codec.Message, v interface{}) error { 185 // if we don't have a body 186 if v != nil { 187 b, err := g.c.Marshal(v) 188 if err != nil { 189 return err 190 } 191 m.Body = b 192 } 193 // write the body using the framing codec 194 return g.ServerStream.SendMsg(&bytes.Frame{Data: m.Body}) 195 } 196 197 func (g *grpcCodec) Close() error { 198 return nil 199 } 200 201 func (g *grpcCodec) String() string { 202 return "grpc" 203 }