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  }