in protocol/dubbo/hessian2/hessian_request.go [86:180]
func packRequest(service Service, header DubboHeader, req any) ([]byte, error) {
var (
err error
types string
byteArray []byte
pkgLen int
)
request := EnsureRequest(req)
args, ok := request.Params.([]any)
if !ok {
return nil, perrors.Errorf("@params is not of type: []any")
}
hb := header.Type == PackageHeartbeat
//////////////////////////////////////////
// byteArray
//////////////////////////////////////////
// magic
switch header.Type {
case PackageHeartbeat:
byteArray = append(byteArray, DubboRequestHeartbeatHeader[:]...)
case PackageRequest_TwoWay:
byteArray = append(byteArray, DubboRequestHeaderBytesTwoWay[:]...)
default:
byteArray = append(byteArray, DubboRequestHeaderBytes[:]...)
}
// serialization id, two way flag, event, request/response flag
// SerialID is id of serialization approach in java dubbo
byteArray[2] |= header.SerialID & SERIAL_MASK
// request id
binary.BigEndian.PutUint64(byteArray[4:], uint64(header.ID))
encoder := hessian.NewEncoder()
encoder.Append(byteArray[:HEADER_LENGTH])
//////////////////////////////////////////
// body
//////////////////////////////////////////
if hb {
_ = encoder.Encode(nil)
goto END
}
// dubbo version + path + version + method
if err = encoder.Encode(DEFAULT_DUBBO_PROTOCOL_VERSION); err != nil {
logger.Warnf("Encode(DEFAULT_DUBBO_PROTOCOL_VERSION) = error: %v", err)
}
if err = encoder.Encode(service.Path); err != nil {
logger.Warnf("Encode(service.Path) = error: %v", err)
}
if err = encoder.Encode(service.Version); err != nil {
logger.Warnf("Encode(service.Version) = error: %v", err)
}
if err = encoder.Encode(service.Method); err != nil {
logger.Warnf("Encode(service.Method) = error: %v", err)
}
// args = args type list + args value list
if types, err = getArgsTypeList(args); err != nil {
return nil, perrors.Wrapf(err, " PackRequest(args:%+v)", args)
}
_ = encoder.Encode(types)
for _, v := range args {
_ = encoder.Encode(v)
}
request.Attachments[PATH_KEY] = service.Path
request.Attachments[VERSION_KEY] = service.Version
if len(service.Group) > 0 {
request.Attachments[GROUP_KEY] = service.Group
}
if len(service.Interface) > 0 {
request.Attachments[INTERFACE_KEY] = service.Interface
}
if service.Timeout != 0 {
request.Attachments[TIMEOUT_KEY] = strconv.Itoa(int(service.Timeout / time.Millisecond))
}
_ = encoder.Encode(request.Attachments)
END:
byteArray = encoder.Buffer()
pkgLen = len(byteArray)
if pkgLen > int(DEFAULT_LEN) { // recommand 8M
logger.Warnf("Data length %d too large, recommand max payload %d. "+
"Dubbo java can't handle the package whose size is greater than %d!!!", pkgLen, DEFAULT_LEN, DEFAULT_LEN)
}
// byteArray{body length}
binary.BigEndian.PutUint32(byteArray[12:], uint32(pkgLen-HEADER_LENGTH))
return byteArray, nil
}