github.com/micro/go-micro/v2@v2.9.1/client/grpc/codec.go (about) 1 package grpc 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 8 b "bytes" 9 10 "github.com/golang/protobuf/jsonpb" 11 "github.com/golang/protobuf/proto" 12 "github.com/micro/go-micro/v2/codec" 13 "github.com/micro/go-micro/v2/codec/bytes" 14 "github.com/oxtoacart/bpool" 15 "google.golang.org/grpc" 16 "google.golang.org/grpc/encoding" 17 ) 18 19 type jsonCodec struct{} 20 type protoCodec struct{} 21 type bytesCodec struct{} 22 type wrapCodec struct{ encoding.Codec } 23 24 var jsonpbMarshaler = &jsonpb.Marshaler{} 25 var useNumber bool 26 27 // create buffer pool with 16 instances each preallocated with 256 bytes 28 var bufferPool = bpool.NewSizedBufferPool(16, 256) 29 30 var ( 31 defaultGRPCCodecs = map[string]encoding.Codec{ 32 "application/json": jsonCodec{}, 33 "application/proto": protoCodec{}, 34 "application/protobuf": protoCodec{}, 35 "application/octet-stream": protoCodec{}, 36 "application/grpc": protoCodec{}, 37 "application/grpc+json": jsonCodec{}, 38 "application/grpc+proto": protoCodec{}, 39 "application/grpc+bytes": bytesCodec{}, 40 } 41 ) 42 43 // UseNumber fix unmarshal Number(8234567890123456789) to interface(8.234567890123457e+18) 44 func UseNumber() { 45 useNumber = true 46 } 47 48 func (w wrapCodec) String() string { 49 return w.Codec.Name() 50 } 51 52 func (w wrapCodec) Marshal(v interface{}) ([]byte, error) { 53 b, ok := v.(*bytes.Frame) 54 if ok { 55 return b.Data, nil 56 } 57 return w.Codec.Marshal(v) 58 } 59 60 func (w wrapCodec) Unmarshal(data []byte, v interface{}) error { 61 b, ok := v.(*bytes.Frame) 62 if ok { 63 b.Data = data 64 return nil 65 } 66 return w.Codec.Unmarshal(data, v) 67 } 68 69 func (protoCodec) Marshal(v interface{}) ([]byte, error) { 70 switch m := v.(type) { 71 case *bytes.Frame: 72 return m.Data, nil 73 case proto.Message: 74 return proto.Marshal(m) 75 } 76 return nil, fmt.Errorf("failed to marshal: %v is not type of *bytes.Frame or proto.Message", v) 77 } 78 79 func (protoCodec) Unmarshal(data []byte, v interface{}) error { 80 m, ok := v.(proto.Message) 81 if !ok { 82 return fmt.Errorf("failed to unmarshal: %v is not type of proto.Message", v) 83 } 84 return proto.Unmarshal(data, m) 85 } 86 87 func (protoCodec) Name() string { 88 return "proto" 89 } 90 91 func (bytesCodec) Marshal(v interface{}) ([]byte, error) { 92 b, ok := v.(*[]byte) 93 if !ok { 94 return nil, fmt.Errorf("failed to marshal: %v is not type of *[]byte", v) 95 } 96 return *b, nil 97 } 98 99 func (bytesCodec) Unmarshal(data []byte, v interface{}) error { 100 b, ok := v.(*[]byte) 101 if !ok { 102 return fmt.Errorf("failed to unmarshal: %v is not type of *[]byte", v) 103 } 104 *b = data 105 return nil 106 } 107 108 func (bytesCodec) Name() string { 109 return "bytes" 110 } 111 112 func (jsonCodec) Marshal(v interface{}) ([]byte, error) { 113 if b, ok := v.(*bytes.Frame); ok { 114 return b.Data, nil 115 } 116 117 if pb, ok := v.(proto.Message); ok { 118 buf := bufferPool.Get() 119 defer bufferPool.Put(buf) 120 if err := jsonpbMarshaler.Marshal(buf, pb); err != nil { 121 return nil, err 122 } 123 return buf.Bytes(), nil 124 } 125 126 return json.Marshal(v) 127 } 128 129 func (jsonCodec) Unmarshal(data []byte, v interface{}) error { 130 if len(data) == 0 { 131 return nil 132 } 133 if b, ok := v.(*bytes.Frame); ok { 134 b.Data = data 135 return nil 136 } 137 if pb, ok := v.(proto.Message); ok { 138 return jsonpb.Unmarshal(b.NewReader(data), pb) 139 } 140 141 dec := json.NewDecoder(b.NewReader(data)) 142 if useNumber { 143 dec.UseNumber() 144 } 145 return dec.Decode(v) 146 } 147 148 func (jsonCodec) Name() string { 149 return "json" 150 } 151 152 type grpcCodec struct { 153 // headers 154 id string 155 target string 156 method string 157 endpoint string 158 159 s grpc.ClientStream 160 c encoding.Codec 161 } 162 163 func (g *grpcCodec) ReadHeader(m *codec.Message, mt codec.MessageType) error { 164 md, err := g.s.Header() 165 if err != nil { 166 return err 167 } 168 if m == nil { 169 m = new(codec.Message) 170 } 171 if m.Header == nil { 172 m.Header = make(map[string]string, len(md)) 173 } 174 for k, v := range md { 175 m.Header[k] = strings.Join(v, ",") 176 } 177 m.Id = g.id 178 m.Target = g.target 179 m.Method = g.method 180 m.Endpoint = g.endpoint 181 return nil 182 } 183 184 func (g *grpcCodec) ReadBody(v interface{}) error { 185 if f, ok := v.(*bytes.Frame); ok { 186 return g.s.RecvMsg(f) 187 } 188 return g.s.RecvMsg(v) 189 } 190 191 func (g *grpcCodec) Write(m *codec.Message, v interface{}) error { 192 // if we don't have a body 193 if v != nil { 194 return g.s.SendMsg(v) 195 } 196 // write the body using the framing codec 197 return g.s.SendMsg(&bytes.Frame{Data: m.Body}) 198 } 199 200 func (g *grpcCodec) Close() error { 201 return g.s.CloseSend() 202 } 203 204 func (g *grpcCodec) String() string { 205 return g.c.Name() 206 }