github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/common/msgparser/jsonrpc2_handler.go (about) 1 package msgparser 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "errors" 7 "github.com/nyan233/littlerpc/core/common/jsonrpc2" 8 "github.com/nyan233/littlerpc/core/middle/codec" 9 "github.com/nyan233/littlerpc/core/protocol/message" 10 "github.com/nyan233/littlerpc/core/utils/convert" 11 "math" 12 "strconv" 13 ) 14 15 type jsonRpc2Handler struct { 16 Codec codec.Codec 17 } 18 19 func (j *jsonRpc2Handler) Header() []byte { 20 return []byte{jsonrpc2.Header} 21 } 22 23 func (j *jsonRpc2Handler) BaseLen() (BaseLenType, int) { 24 return SingleRequest, -1 25 } 26 27 func (j *jsonRpc2Handler) MessageLength(base []byte) int { 28 panic("implement me") 29 } 30 31 func (j *jsonRpc2Handler) Unmarshal(data []byte, msg *message.Message) (Action, error) { 32 var base jsonrpc2.BaseMessage 33 err := j.Codec.Unmarshal(data, &base) 34 if err != nil { 35 return -1, err 36 } 37 if base.Version != jsonrpc2.Version { 38 return -1, errors.New("unknown message version") 39 } 40 if base.MessageType > math.MaxUint8 { 41 return -1, errors.New("message type overflow") 42 } 43 msg.SetMsgId(base.Id) 44 msg.SetMsgType(uint8(base.MessageType)) 45 if base.MetaData != nil { 46 for k, v := range base.MetaData { 47 msg.MetaData.Store(k, v) 48 } 49 } 50 isJsonParams := true 51 var packerScheme string 52 if base.MetaData != nil { 53 packerScheme = base.MetaData[message.PackerScheme] 54 codecScheme := base.MetaData[message.CodecScheme] 55 isJsonParams = codecScheme == "" || codecScheme == message.DefaultCodec 56 } 57 if !(packerScheme == "" || packerScheme == message.DefaultPacker) { 58 return -1, errors.New("jsonrpc2 not supported only text packer") 59 } 60 switch uint8(base.MessageType) { 61 case message.ContextCancel, message.Call: 62 var trait jsonrpc2.RequestTrait 63 err = j.Codec.Unmarshal(data, &trait) 64 if err != nil { 65 return -1, err 66 } 67 msg.SetServiceName(trait.Method) 68 if trait.Params == nil || len(trait.Params) == 0 { 69 return UnmarshalComplete, nil 70 } 71 switch trait.Params[0] { 72 case '[': 73 var msgs []json.RawMessage 74 err = j.Codec.Unmarshal(trait.Params, &msgs) 75 if err != nil { 76 return -1, err 77 } 78 for _, v := range msgs { 79 var bytes []byte 80 var err error 81 if !isJsonParams { 82 bytes, err = base64.StdEncoding.DecodeString(convert.BytesToString(v)) 83 if err != nil { 84 return 0, err 85 } 86 } else { 87 bytes = v 88 } 89 msg.AppendPayloads(bytes) 90 } 91 default: 92 msg.AppendPayloads(trait.Params) 93 } 94 msg.GetAndSetLength() 95 case message.Return: 96 var trait jsonrpc2.ResponseTrait 97 err = j.Codec.Unmarshal(data, &trait) 98 if err != nil { 99 return -1, err 100 } 101 if trait.Error != nil { 102 msg.MetaData.Store(message.ErrorCode, strconv.Itoa(trait.Error.Code)) 103 msg.MetaData.Store(message.ErrorMessage, trait.Error.Message) 104 if trait.Error.Data != nil || len(trait.Error.Data) != 0 { 105 msg.MetaData.Store(message.ErrorMore, convert.BytesToString(trait.Error.Data)) 106 } 107 } 108 for _, result := range trait.Result { 109 msg.AppendPayloads(result) 110 } 111 default: 112 return -1, errors.New("unknown message type") 113 } 114 return UnmarshalComplete, nil 115 }