trpc.group/trpc-go/trpc-go@v1.0.3/codec/message_impl.go (about) 1 // 2 // 3 // Tencent is pleased to support the open source community by making tRPC available. 4 // 5 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 // All rights reserved. 7 // 8 // If you have downloaded a copy of the tRPC source code from Tencent, 9 // please note that tRPC source code is licensed under the Apache 2.0 License, 10 // A copy of the Apache 2.0 License is included in this file. 11 // 12 // 13 14 package codec 15 16 import ( 17 "context" 18 "net" 19 "strings" 20 "time" 21 22 "trpc.group/trpc-go/trpc-go/errs" 23 ) 24 25 // msg is the context of rpc. 26 type msg struct { 27 context context.Context 28 frameHead interface{} 29 requestTimeout time.Duration 30 serializationType int 31 compressType int 32 streamID uint32 33 dyeing bool 34 dyeingKey string 35 serverRPCName string 36 clientRPCName string 37 serverMetaData MetaData 38 clientMetaData MetaData 39 callerServiceName string 40 calleeServiceName string 41 calleeContainerName string 42 serverRspErr error 43 clientRspErr error 44 serverReqHead interface{} 45 serverRspHead interface{} 46 clientReqHead interface{} 47 clientRspHead interface{} 48 localAddr net.Addr 49 remoteAddr net.Addr 50 logger interface{} 51 callerApp string 52 callerServer string 53 callerService string 54 callerMethod string 55 calleeApp string 56 calleeServer string 57 calleeService string 58 calleeMethod string 59 namespace string 60 setName string 61 envName string 62 envTransfer string 63 requestID uint32 64 calleeSetName string 65 streamFrame interface{} 66 commonMeta CommonMeta 67 callType RequestType 68 } 69 70 // resetDefault reset all fields of msg to default value. 71 func (m *msg) resetDefault() { 72 m.context = nil 73 m.frameHead = nil 74 m.requestTimeout = 0 75 m.serializationType = 0 76 m.compressType = 0 77 m.dyeing = false 78 m.dyeingKey = "" 79 m.serverRPCName = "" 80 m.clientRPCName = "" 81 m.serverMetaData = nil 82 m.clientMetaData = nil 83 m.callerServiceName = "" 84 m.calleeServiceName = "" 85 m.calleeContainerName = "" 86 m.serverRspErr = nil 87 m.clientRspErr = nil 88 m.serverReqHead = nil 89 m.serverRspHead = nil 90 m.clientReqHead = nil 91 m.clientRspHead = nil 92 m.localAddr = nil 93 m.remoteAddr = nil 94 m.logger = nil 95 m.callerApp = "" 96 m.callerServer = "" 97 m.callerService = "" 98 m.callerMethod = "" 99 m.calleeApp = "" 100 m.calleeServer = "" 101 m.calleeService = "" 102 m.calleeMethod = "" 103 m.namespace = "" 104 m.setName = "" 105 m.envName = "" 106 m.envTransfer = "" 107 m.requestID = 0 108 m.streamFrame = nil 109 m.streamID = 0 110 m.calleeSetName = "" 111 m.commonMeta = nil 112 m.callType = 0 113 } 114 115 // Context restores old context when create new msg. 116 func (m *msg) Context() context.Context { 117 return m.context 118 } 119 120 // WithNamespace set server's namespace. 121 func (m *msg) WithNamespace(namespace string) { 122 m.namespace = namespace 123 } 124 125 // Namespace returns namespace. 126 func (m *msg) Namespace() string { 127 return m.namespace 128 } 129 130 // WithEnvName sets environment. 131 func (m *msg) WithEnvName(envName string) { 132 m.envName = envName 133 } 134 135 // WithSetName sets set name. 136 func (m *msg) WithSetName(setName string) { 137 m.setName = setName 138 } 139 140 // SetName returns set name. 141 func (m *msg) SetName() string { 142 return m.setName 143 } 144 145 // WithCalleeSetName sets the callee set name. 146 func (m *msg) WithCalleeSetName(s string) { 147 m.calleeSetName = s 148 } 149 150 // CalleeSetName returns the callee set name. 151 func (m *msg) CalleeSetName() string { 152 return m.calleeSetName 153 } 154 155 // EnvName returns environment. 156 func (m *msg) EnvName() string { 157 return m.envName 158 } 159 160 // WithEnvTransfer sets environment transfer value. 161 func (m *msg) WithEnvTransfer(envTransfer string) { 162 m.envTransfer = envTransfer 163 } 164 165 // EnvTransfer returns environment transfer value. 166 func (m *msg) EnvTransfer() string { 167 return m.envTransfer 168 } 169 170 // WithRemoteAddr sets remote address. 171 func (m *msg) WithRemoteAddr(addr net.Addr) { 172 m.remoteAddr = addr 173 } 174 175 // WithLocalAddr set local address. 176 func (m *msg) WithLocalAddr(addr net.Addr) { 177 m.localAddr = addr 178 } 179 180 // RemoteAddr returns remote address. 181 func (m *msg) RemoteAddr() net.Addr { 182 return m.remoteAddr 183 } 184 185 // LocalAddr returns local address. 186 func (m *msg) LocalAddr() net.Addr { 187 return m.localAddr 188 } 189 190 // RequestTimeout returns request timeout set by 191 // upstream business protocol. 192 func (m *msg) RequestTimeout() time.Duration { 193 return m.requestTimeout 194 } 195 196 // WithRequestTimeout sets request timeout. 197 func (m *msg) WithRequestTimeout(t time.Duration) { 198 m.requestTimeout = t 199 } 200 201 // FrameHead returns frame head. 202 func (m *msg) FrameHead() interface{} { 203 return m.frameHead 204 } 205 206 // WithFrameHead sets frame head. 207 func (m *msg) WithFrameHead(f interface{}) { 208 m.frameHead = f 209 } 210 211 // SerializationType returns the value of body serialization, which is 212 // defined in serialization.go. 213 func (m *msg) SerializationType() int { 214 return m.serializationType 215 } 216 217 // WithSerializationType sets body serialization type of body. 218 func (m *msg) WithSerializationType(t int) { 219 m.serializationType = t 220 } 221 222 // CompressType returns compress type value, which is defined in compress.go. 223 func (m *msg) CompressType() int { 224 return m.compressType 225 } 226 227 // WithCompressType sets compress type. 228 func (m *msg) WithCompressType(t int) { 229 m.compressType = t 230 } 231 232 // ServerRPCName returns server rpc name. 233 func (m *msg) ServerRPCName() string { 234 return m.serverRPCName 235 } 236 237 // WithServerRPCName sets server rpc name. 238 func (m *msg) WithServerRPCName(s string) { 239 if m.serverRPCName == s { 240 return 241 } 242 m.serverRPCName = s 243 m.updateMethodNameUsingRPCName(s) 244 } 245 246 // ClientRPCName returns client rpc name. 247 func (m *msg) ClientRPCName() string { 248 return m.clientRPCName 249 } 250 251 // WithClientRPCName sets client rpc name, which will be called 252 // by client stub. 253 func (m *msg) WithClientRPCName(s string) { 254 if m.clientRPCName == s { 255 return 256 } 257 m.clientRPCName = s 258 m.updateMethodNameUsingRPCName(s) 259 } 260 261 func (m *msg) updateMethodNameUsingRPCName(s string) { 262 if rpcNameIsTRPCForm(s) { 263 m.WithCalleeMethod(methodFromRPCName(s)) 264 return 265 } 266 if m.CalleeMethod() == "" { 267 m.WithCalleeMethod(s) 268 } 269 } 270 271 // ServerMetaData returns server meta data, which is passed to server. 272 func (m *msg) ServerMetaData() MetaData { 273 return m.serverMetaData 274 } 275 276 // WithServerMetaData sets server meta data. 277 func (m *msg) WithServerMetaData(d MetaData) { 278 if d == nil { 279 d = MetaData{} 280 } 281 m.serverMetaData = d 282 } 283 284 // ClientMetaData returns client meta data, which will pass to downstream. 285 func (m *msg) ClientMetaData() MetaData { 286 return m.clientMetaData 287 } 288 289 // WithClientMetaData set client meta data. 290 func (m *msg) WithClientMetaData(d MetaData) { 291 if d == nil { 292 d = MetaData{} 293 } 294 m.clientMetaData = d 295 } 296 297 // CalleeServiceName returns callee service name. 298 func (m *msg) CalleeServiceName() string { 299 return m.calleeServiceName 300 } 301 302 // WithCalleeServiceName sets callee service name. 303 func (m *msg) WithCalleeServiceName(s string) { 304 if m.calleeServiceName == s { 305 return 306 } 307 m.calleeServiceName = s 308 if s == "*" { 309 return 310 } 311 app, server, service := getAppServerService(s) 312 m.WithCalleeApp(app) 313 m.WithCalleeServer(server) 314 m.WithCalleeService(service) 315 } 316 317 // CalleeContainerName returns callee container name. 318 func (m *msg) CalleeContainerName() string { 319 return m.calleeContainerName 320 } 321 322 // WithCalleeContainerName sets callee container name. 323 func (m *msg) WithCalleeContainerName(s string) { 324 m.calleeContainerName = s 325 } 326 327 // WithStreamFrame sets stream frame. 328 func (m *msg) WithStreamFrame(i interface{}) { 329 m.streamFrame = i 330 } 331 332 // StreamFrame returns stream frame. 333 func (m *msg) StreamFrame() interface{} { 334 return m.streamFrame 335 } 336 337 // CallerServiceName returns caller service name. 338 func (m *msg) CallerServiceName() string { 339 return m.callerServiceName 340 } 341 342 // WithCallerServiceName sets caller service name. 343 func (m *msg) WithCallerServiceName(s string) { 344 if m.callerServiceName == s { 345 return 346 } 347 m.callerServiceName = s 348 if s == "*" { 349 return 350 } 351 app, server, service := getAppServerService(s) 352 m.WithCallerApp(app) 353 m.WithCallerServer(server) 354 m.WithCallerService(service) 355 } 356 357 // ServerRspErr returns server response error, which is created 358 // by handler. 359 func (m *msg) ServerRspErr() *errs.Error { 360 if m.serverRspErr == nil { 361 return nil 362 } 363 e, ok := m.serverRspErr.(*errs.Error) 364 if !ok { 365 return &errs.Error{ 366 Type: errs.ErrorTypeBusiness, 367 Code: errs.RetUnknown, 368 Msg: m.serverRspErr.Error(), 369 } 370 } 371 return e 372 } 373 374 // WithServerRspErr sets server response error. 375 func (m *msg) WithServerRspErr(e error) { 376 m.serverRspErr = e 377 } 378 379 // WithStreamID sets stream id. 380 func (m *msg) WithStreamID(streamID uint32) { 381 m.streamID = streamID 382 } 383 384 // StreamID returns stream id. 385 func (m *msg) StreamID() uint32 { 386 return m.streamID 387 } 388 389 // ClientRspErr returns client response error, which created when client call downstream. 390 func (m *msg) ClientRspErr() error { 391 return m.clientRspErr 392 } 393 394 // WithClientRspErr sets client response err, this method will called 395 // when client parse response package. 396 func (m *msg) WithClientRspErr(e error) { 397 m.clientRspErr = e 398 } 399 400 // ServerReqHead returns the package head of request 401 func (m *msg) ServerReqHead() interface{} { 402 return m.serverReqHead 403 } 404 405 // WithServerReqHead sets the package head of request 406 func (m *msg) WithServerReqHead(h interface{}) { 407 m.serverReqHead = h 408 } 409 410 // ServerRspHead returns the package head of response 411 func (m *msg) ServerRspHead() interface{} { 412 return m.serverRspHead 413 } 414 415 // WithServerRspHead sets the package head returns to upstream 416 func (m *msg) WithServerRspHead(h interface{}) { 417 m.serverRspHead = h 418 } 419 420 // ClientReqHead returns the request package head of client, 421 // this is set only when cross protocol call. 422 func (m *msg) ClientReqHead() interface{} { 423 return m.clientReqHead 424 } 425 426 // WithClientReqHead sets the request package head of client. 427 func (m *msg) WithClientReqHead(h interface{}) { 428 m.clientReqHead = h 429 } 430 431 // ClientRspHead returns the request package head of client. 432 func (m *msg) ClientRspHead() interface{} { 433 return m.clientRspHead 434 } 435 436 // WithClientRspHead sets the response package head of client. 437 func (m *msg) WithClientRspHead(h interface{}) { 438 m.clientRspHead = h 439 } 440 441 // Dyeing return the dyeing mark. 442 func (m *msg) Dyeing() bool { 443 return m.dyeing 444 } 445 446 // WithDyeing sets the dyeing mark. 447 func (m *msg) WithDyeing(dyeing bool) { 448 m.dyeing = dyeing 449 } 450 451 // DyeingKey returns the dyeing key. 452 func (m *msg) DyeingKey() string { 453 return m.dyeingKey 454 } 455 456 // WithDyeingKey sets the dyeing key. 457 func (m *msg) WithDyeingKey(key string) { 458 m.dyeingKey = key 459 } 460 461 // CallerApp returns caller app. 462 func (m *msg) CallerApp() string { 463 return m.callerApp 464 } 465 466 // WithCallerApp sets caller app. 467 func (m *msg) WithCallerApp(app string) { 468 m.callerApp = app 469 } 470 471 // CallerServer returns caller server. 472 func (m *msg) CallerServer() string { 473 return m.callerServer 474 } 475 476 // WithCallerServer sets caller server. 477 func (m *msg) WithCallerServer(s string) { 478 m.callerServer = s 479 } 480 481 // CallerService returns caller service. 482 func (m *msg) CallerService() string { 483 return m.callerService 484 } 485 486 // WithCallerService sets caller service. 487 func (m *msg) WithCallerService(s string) { 488 m.callerService = s 489 } 490 491 // WithCallerMethod sets caller method. 492 func (m *msg) WithCallerMethod(s string) { 493 m.callerMethod = s 494 } 495 496 // CallerMethod returns caller method. 497 func (m *msg) CallerMethod() string { 498 return m.callerMethod 499 } 500 501 // CalleeApp returns caller app. 502 func (m *msg) CalleeApp() string { 503 return m.calleeApp 504 } 505 506 // WithCalleeApp sets callee app. 507 func (m *msg) WithCalleeApp(app string) { 508 m.calleeApp = app 509 } 510 511 // CalleeServer returns callee server. 512 func (m *msg) CalleeServer() string { 513 return m.calleeServer 514 } 515 516 // WithCalleeServer sets callee server. 517 func (m *msg) WithCalleeServer(s string) { 518 m.calleeServer = s 519 } 520 521 // CalleeService returns callee service. 522 func (m *msg) CalleeService() string { 523 return m.calleeService 524 } 525 526 // WithCalleeService sets callee service. 527 func (m *msg) WithCalleeService(s string) { 528 m.calleeService = s 529 } 530 531 // WithCalleeMethod sets callee method. 532 func (m *msg) WithCalleeMethod(s string) { 533 m.calleeMethod = s 534 } 535 536 // CalleeMethod returns callee method. 537 func (m *msg) CalleeMethod() string { 538 return m.calleeMethod 539 } 540 541 // WithLogger sets logger into context message. Generally, the logger is 542 // created from WithFields() method. 543 func (m *msg) WithLogger(l interface{}) { 544 m.logger = l 545 } 546 547 // Logger returns logger from context message. 548 func (m *msg) Logger() interface{} { 549 return m.logger 550 } 551 552 // WithRequestID sets request id. 553 func (m *msg) WithRequestID(id uint32) { 554 m.requestID = id 555 } 556 557 // RequestID returns request id. 558 func (m *msg) RequestID() uint32 { 559 return m.requestID 560 } 561 562 // WithCommonMeta sets common meta data. 563 func (m *msg) WithCommonMeta(c CommonMeta) { 564 m.commonMeta = c 565 } 566 567 // CommonMeta returns common meta data. 568 func (m *msg) CommonMeta() CommonMeta { 569 return m.commonMeta 570 } 571 572 // WithCallType sets type of call. 573 func (m *msg) WithCallType(t RequestType) { 574 m.callType = t 575 } 576 577 // CallType returns type of call. 578 func (m *msg) CallType() RequestType { 579 return m.callType 580 } 581 582 // WithNewMessage create a new empty message, and put it into ctx, 583 func WithNewMessage(ctx context.Context) (context.Context, Msg) { 584 585 m := msgPool.Get().(*msg) 586 ctx = context.WithValue(ctx, ContextKeyMessage, m) 587 m.context = ctx 588 return ctx, m 589 } 590 591 // PutBackMessage return struct Message to sync pool, 592 // and reset all the members of Message to default 593 func PutBackMessage(sourceMsg Msg) { 594 m, ok := sourceMsg.(*msg) 595 if !ok { 596 return 597 } 598 m.resetDefault() 599 msgPool.Put(m) 600 } 601 602 // WithCloneContextAndMessage creates a new context, then copy the message of current context 603 // into new context, this method will return the new context and message for stream mod. 604 func WithCloneContextAndMessage(ctx context.Context) (context.Context, Msg) { 605 newMsg := msgPool.Get().(*msg) 606 newCtx := context.Background() 607 val := ctx.Value(ContextKeyMessage) 608 m, ok := val.(*msg) 609 if !ok { 610 newCtx = context.WithValue(newCtx, ContextKeyMessage, newMsg) 611 newMsg.context = newCtx 612 return newCtx, newMsg 613 } 614 newCtx = context.WithValue(newCtx, ContextKeyMessage, newMsg) 615 newMsg.context = newCtx 616 copyCommonMessage(m, newMsg) 617 copyServerToServerMessage(m, newMsg) 618 return newCtx, newMsg 619 } 620 621 // copyCommonMessage copy common data of message. 622 func copyCommonMessage(m *msg, newMsg *msg) { 623 // Do not copy compress type here, as it will cause subsequence RPC calls to inherit the upstream 624 // compress type which is not the expected behavior. Compress type should not be propagated along 625 // the entire RPC invocation chain. 626 newMsg.frameHead = m.frameHead 627 newMsg.requestTimeout = m.requestTimeout 628 newMsg.serializationType = m.serializationType 629 newMsg.serverRPCName = m.serverRPCName 630 newMsg.clientRPCName = m.clientRPCName 631 newMsg.serverReqHead = m.serverReqHead 632 newMsg.serverRspHead = m.serverRspHead 633 newMsg.dyeing = m.dyeing 634 newMsg.dyeingKey = m.dyeingKey 635 newMsg.serverMetaData = m.serverMetaData.Clone() 636 newMsg.logger = m.logger 637 newMsg.namespace = m.namespace 638 newMsg.envName = m.envName 639 newMsg.setName = m.setName 640 newMsg.envTransfer = m.envTransfer 641 newMsg.commonMeta = m.commonMeta.Clone() 642 } 643 644 // copyClientMessage copy the message transferred from server to client. 645 func copyServerToClientMessage(m *msg, newMsg *msg) { 646 newMsg.clientMetaData = m.serverMetaData.Clone() 647 // clone this message for downstream client, so caller is equal to callee. 648 newMsg.callerServiceName = m.calleeServiceName 649 newMsg.callerApp = m.calleeApp 650 newMsg.callerServer = m.calleeServer 651 newMsg.callerService = m.calleeService 652 newMsg.callerMethod = m.calleeMethod 653 } 654 655 func copyServerToServerMessage(m *msg, newMsg *msg) { 656 newMsg.callerServiceName = m.callerServiceName 657 newMsg.callerApp = m.callerApp 658 newMsg.callerServer = m.callerServer 659 newMsg.callerService = m.callerService 660 newMsg.callerMethod = m.callerMethod 661 662 newMsg.calleeServiceName = m.calleeServiceName 663 newMsg.calleeService = m.calleeService 664 newMsg.calleeApp = m.calleeApp 665 newMsg.calleeServer = m.calleeServer 666 newMsg.calleeMethod = m.calleeMethod 667 } 668 669 // WithCloneMessage copy a new message and put into context, each rpc call should 670 // create a new message, this method will be called by client stub. 671 func WithCloneMessage(ctx context.Context) (context.Context, Msg) { 672 newMsg := msgPool.Get().(*msg) 673 val := ctx.Value(ContextKeyMessage) 674 m, ok := val.(*msg) 675 if !ok { 676 ctx = context.WithValue(ctx, ContextKeyMessage, newMsg) 677 newMsg.context = ctx 678 return ctx, newMsg 679 } 680 ctx = context.WithValue(ctx, ContextKeyMessage, newMsg) 681 newMsg.context = ctx 682 copyCommonMessage(m, newMsg) 683 copyServerToClientMessage(m, newMsg) 684 return ctx, newMsg 685 } 686 687 // Message returns the message of context. 688 func Message(ctx context.Context) Msg { 689 val := ctx.Value(ContextKeyMessage) 690 m, ok := val.(*msg) 691 if !ok { 692 return &msg{context: ctx} 693 } 694 return m 695 } 696 697 // EnsureMessage returns context and message, if there is a message in context, 698 // returns the original one, if not, returns a new one. 699 func EnsureMessage(ctx context.Context) (context.Context, Msg) { 700 val := ctx.Value(ContextKeyMessage) 701 if m, ok := val.(*msg); ok { 702 return ctx, m 703 } 704 return WithNewMessage(ctx) 705 } 706 707 // getAppServerService returns app, server and service parsed from service name. 708 // service name example: trpc.app.server.service 709 func getAppServerService(s string) (app, server, service string) { 710 if strings.Count(s, ".") >= ServiceSectionLength-1 { 711 i := strings.Index(s, ".") + 1 712 j := strings.Index(s[i:], ".") + i + 1 713 k := strings.Index(s[j:], ".") + j + 1 714 app = s[i : j-1] 715 server = s[j : k-1] 716 service = s[k:] 717 return 718 } 719 // app 720 i := strings.Index(s, ".") 721 if i == -1 { 722 app = s 723 return 724 } 725 app = s[:i] 726 // server 727 i++ 728 j := strings.Index(s[i:], ".") 729 if j == -1 { 730 server = s[i:] 731 return 732 } 733 j += i + 1 734 server = s[i : j-1] 735 // service 736 service = s[j:] 737 return 738 } 739 740 // methodFromRPCName returns the method parsed from rpc string. 741 func methodFromRPCName(s string) string { 742 return s[strings.LastIndex(s, "/")+1:] 743 } 744 745 // rpcNameIsTRPCForm checks whether the given string is of trpc form. 746 // It is equivalent to: 747 // 748 // var r = regexp.MustCompile(`^/[^/.]+\.[^/]+/[^/.]+$`) 749 // 750 // func rpcNameIsTRPCForm(s string) bool { 751 // return r.MatchString(s) 752 // } 753 // 754 // But regexp is much slower than the current version. 755 // Refer to BenchmarkRPCNameIsTRPCForm in message_bench_test.go. 756 func rpcNameIsTRPCForm(s string) bool { 757 if len(s) == 0 { 758 return false 759 } 760 if s[0] != '/' { // ^/ 761 return false 762 } 763 const start = 1 764 firstDot := strings.Index(s[start:], ".") 765 if firstDot == -1 || firstDot == 0 { // [^.]+\. 766 return false 767 } 768 if strings.Contains(s[start:start+firstDot], "/") { // [^/]+\. 769 return false 770 } 771 secondSlash := strings.Index(s[start+firstDot:], "/") 772 if secondSlash == -1 || secondSlash == 1 { // [^/]+/ 773 return false 774 } 775 if start+firstDot+secondSlash == len(s)-1 { // The second slash should not be the last character. 776 return false 777 } 778 const offset = 1 779 if strings.ContainsAny(s[start+firstDot+secondSlash+offset:], "/.") { // [^/.]+$ 780 return false 781 } 782 return true 783 }