google.golang.org/grpc@v1.74.2/rpc_util.go (about)

     1  /*
     2   *
     3   * Copyright 2014 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package grpc
    20  
    21  import (
    22  	"compress/gzip"
    23  	"context"
    24  	"encoding/binary"
    25  	"fmt"
    26  	"io"
    27  	"math"
    28  	"strings"
    29  	"sync"
    30  	"time"
    31  
    32  	"google.golang.org/grpc/codes"
    33  	"google.golang.org/grpc/credentials"
    34  	"google.golang.org/grpc/encoding"
    35  	"google.golang.org/grpc/encoding/proto"
    36  	"google.golang.org/grpc/internal/transport"
    37  	"google.golang.org/grpc/mem"
    38  	"google.golang.org/grpc/metadata"
    39  	"google.golang.org/grpc/peer"
    40  	"google.golang.org/grpc/stats"
    41  	"google.golang.org/grpc/status"
    42  )
    43  
    44  // Compressor defines the interface gRPC uses to compress a message.
    45  //
    46  // Deprecated: use package encoding.
    47  type Compressor interface {
    48  	// Do compresses p into w.
    49  	Do(w io.Writer, p []byte) error
    50  	// Type returns the compression algorithm the Compressor uses.
    51  	Type() string
    52  }
    53  
    54  type gzipCompressor struct {
    55  	pool sync.Pool
    56  }
    57  
    58  // NewGZIPCompressor creates a Compressor based on GZIP.
    59  //
    60  // Deprecated: use package encoding/gzip.
    61  func NewGZIPCompressor() Compressor {
    62  	c, _ := NewGZIPCompressorWithLevel(gzip.DefaultCompression)
    63  	return c
    64  }
    65  
    66  // NewGZIPCompressorWithLevel is like NewGZIPCompressor but specifies the gzip compression level instead
    67  // of assuming DefaultCompression.
    68  //
    69  // The error returned will be nil if the level is valid.
    70  //
    71  // Deprecated: use package encoding/gzip.
    72  func NewGZIPCompressorWithLevel(level int) (Compressor, error) {
    73  	if level < gzip.DefaultCompression || level > gzip.BestCompression {
    74  		return nil, fmt.Errorf("grpc: invalid compression level: %d", level)
    75  	}
    76  	return &gzipCompressor{
    77  		pool: sync.Pool{
    78  			New: func() any {
    79  				w, err := gzip.NewWriterLevel(io.Discard, level)
    80  				if err != nil {
    81  					panic(err)
    82  				}
    83  				return w
    84  			},
    85  		},
    86  	}, nil
    87  }
    88  
    89  func (c *gzipCompressor) Do(w io.Writer, p []byte) error {
    90  	z := c.pool.Get().(*gzip.Writer)
    91  	defer c.pool.Put(z)
    92  	z.Reset(w)
    93  	if _, err := z.Write(p); err != nil {
    94  		return err
    95  	}
    96  	return z.Close()
    97  }
    98  
    99  func (c *gzipCompressor) Type() string {
   100  	return "gzip"
   101  }
   102  
   103  // Decompressor defines the interface gRPC uses to decompress a message.
   104  //
   105  // Deprecated: use package encoding.
   106  type Decompressor interface {
   107  	// Do reads the data from r and uncompress them.
   108  	Do(r io.Reader) ([]byte, error)
   109  	// Type returns the compression algorithm the Decompressor uses.
   110  	Type() string
   111  }
   112  
   113  type gzipDecompressor struct {
   114  	pool sync.Pool
   115  }
   116  
   117  // NewGZIPDecompressor creates a Decompressor based on GZIP.
   118  //
   119  // Deprecated: use package encoding/gzip.
   120  func NewGZIPDecompressor() Decompressor {
   121  	return &gzipDecompressor{}
   122  }
   123  
   124  func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) {
   125  	var z *gzip.Reader
   126  	switch maybeZ := d.pool.Get().(type) {
   127  	case nil:
   128  		newZ, err := gzip.NewReader(r)
   129  		if err != nil {
   130  			return nil, err
   131  		}
   132  		z = newZ
   133  	case *gzip.Reader:
   134  		z = maybeZ
   135  		if err := z.Reset(r); err != nil {
   136  			d.pool.Put(z)
   137  			return nil, err
   138  		}
   139  	}
   140  
   141  	defer func() {
   142  		z.Close()
   143  		d.pool.Put(z)
   144  	}()
   145  	return io.ReadAll(z)
   146  }
   147  
   148  func (d *gzipDecompressor) Type() string {
   149  	return "gzip"
   150  }
   151  
   152  // callInfo contains all related configuration and information about an RPC.
   153  type callInfo struct {
   154  	compressorName        string
   155  	failFast              bool
   156  	maxReceiveMessageSize *int
   157  	maxSendMessageSize    *int
   158  	creds                 credentials.PerRPCCredentials
   159  	contentSubtype        string
   160  	codec                 baseCodec
   161  	maxRetryRPCBufferSize int
   162  	onFinish              []func(err error)
   163  	authority             string
   164  }
   165  
   166  func defaultCallInfo() *callInfo {
   167  	return &callInfo{
   168  		failFast:              true,
   169  		maxRetryRPCBufferSize: 256 * 1024, // 256KB
   170  	}
   171  }
   172  
   173  // CallOption configures a Call before it starts or extracts information from
   174  // a Call after it completes.
   175  type CallOption interface {
   176  	// before is called before the call is sent to any server.  If before
   177  	// returns a non-nil error, the RPC fails with that error.
   178  	before(*callInfo) error
   179  
   180  	// after is called after the call has completed.  after cannot return an
   181  	// error, so any failures should be reported via output parameters.
   182  	after(*callInfo, *csAttempt)
   183  }
   184  
   185  // EmptyCallOption does not alter the Call configuration.
   186  // It can be embedded in another structure to carry satellite data for use
   187  // by interceptors.
   188  type EmptyCallOption struct{}
   189  
   190  func (EmptyCallOption) before(*callInfo) error      { return nil }
   191  func (EmptyCallOption) after(*callInfo, *csAttempt) {}
   192  
   193  // StaticMethod returns a CallOption which specifies that a call is being made
   194  // to a method that is static, which means the method is known at compile time
   195  // and doesn't change at runtime. This can be used as a signal to stats plugins
   196  // that this method is safe to include as a key to a measurement.
   197  func StaticMethod() CallOption {
   198  	return StaticMethodCallOption{}
   199  }
   200  
   201  // StaticMethodCallOption is a CallOption that specifies that a call comes
   202  // from a static method.
   203  type StaticMethodCallOption struct {
   204  	EmptyCallOption
   205  }
   206  
   207  // Header returns a CallOptions that retrieves the header metadata
   208  // for a unary RPC.
   209  func Header(md *metadata.MD) CallOption {
   210  	return HeaderCallOption{HeaderAddr: md}
   211  }
   212  
   213  // HeaderCallOption is a CallOption for collecting response header metadata.
   214  // The metadata field will be populated *after* the RPC completes.
   215  //
   216  // # Experimental
   217  //
   218  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   219  // later release.
   220  type HeaderCallOption struct {
   221  	HeaderAddr *metadata.MD
   222  }
   223  
   224  func (o HeaderCallOption) before(*callInfo) error { return nil }
   225  func (o HeaderCallOption) after(_ *callInfo, attempt *csAttempt) {
   226  	*o.HeaderAddr, _ = attempt.transportStream.Header()
   227  }
   228  
   229  // Trailer returns a CallOptions that retrieves the trailer metadata
   230  // for a unary RPC.
   231  func Trailer(md *metadata.MD) CallOption {
   232  	return TrailerCallOption{TrailerAddr: md}
   233  }
   234  
   235  // TrailerCallOption is a CallOption for collecting response trailer metadata.
   236  // The metadata field will be populated *after* the RPC completes.
   237  //
   238  // # Experimental
   239  //
   240  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   241  // later release.
   242  type TrailerCallOption struct {
   243  	TrailerAddr *metadata.MD
   244  }
   245  
   246  func (o TrailerCallOption) before(*callInfo) error { return nil }
   247  func (o TrailerCallOption) after(_ *callInfo, attempt *csAttempt) {
   248  	*o.TrailerAddr = attempt.transportStream.Trailer()
   249  }
   250  
   251  // Peer returns a CallOption that retrieves peer information for a unary RPC.
   252  // The peer field will be populated *after* the RPC completes.
   253  func Peer(p *peer.Peer) CallOption {
   254  	return PeerCallOption{PeerAddr: p}
   255  }
   256  
   257  // PeerCallOption is a CallOption for collecting the identity of the remote
   258  // peer. The peer field will be populated *after* the RPC completes.
   259  //
   260  // # Experimental
   261  //
   262  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   263  // later release.
   264  type PeerCallOption struct {
   265  	PeerAddr *peer.Peer
   266  }
   267  
   268  func (o PeerCallOption) before(*callInfo) error { return nil }
   269  func (o PeerCallOption) after(_ *callInfo, attempt *csAttempt) {
   270  	if x, ok := peer.FromContext(attempt.transportStream.Context()); ok {
   271  		*o.PeerAddr = *x
   272  	}
   273  }
   274  
   275  // WaitForReady configures the RPC's behavior when the client is in
   276  // TRANSIENT_FAILURE, which occurs when all addresses fail to connect.  If
   277  // waitForReady is false, the RPC will fail immediately.  Otherwise, the client
   278  // will wait until a connection becomes available or the RPC's deadline is
   279  // reached.
   280  //
   281  // By default, RPCs do not "wait for ready".
   282  func WaitForReady(waitForReady bool) CallOption {
   283  	return FailFastCallOption{FailFast: !waitForReady}
   284  }
   285  
   286  // FailFast is the opposite of WaitForReady.
   287  //
   288  // Deprecated: use WaitForReady.
   289  func FailFast(failFast bool) CallOption {
   290  	return FailFastCallOption{FailFast: failFast}
   291  }
   292  
   293  // FailFastCallOption is a CallOption for indicating whether an RPC should fail
   294  // fast or not.
   295  //
   296  // # Experimental
   297  //
   298  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   299  // later release.
   300  type FailFastCallOption struct {
   301  	FailFast bool
   302  }
   303  
   304  func (o FailFastCallOption) before(c *callInfo) error {
   305  	c.failFast = o.FailFast
   306  	return nil
   307  }
   308  func (o FailFastCallOption) after(*callInfo, *csAttempt) {}
   309  
   310  // OnFinish returns a CallOption that configures a callback to be called when
   311  // the call completes. The error passed to the callback is the status of the
   312  // RPC, and may be nil. The onFinish callback provided will only be called once
   313  // by gRPC. This is mainly used to be used by streaming interceptors, to be
   314  // notified when the RPC completes along with information about the status of
   315  // the RPC.
   316  //
   317  // # Experimental
   318  //
   319  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   320  // later release.
   321  func OnFinish(onFinish func(err error)) CallOption {
   322  	return OnFinishCallOption{
   323  		OnFinish: onFinish,
   324  	}
   325  }
   326  
   327  // OnFinishCallOption is CallOption that indicates a callback to be called when
   328  // the call completes.
   329  //
   330  // # Experimental
   331  //
   332  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   333  // later release.
   334  type OnFinishCallOption struct {
   335  	OnFinish func(error)
   336  }
   337  
   338  func (o OnFinishCallOption) before(c *callInfo) error {
   339  	c.onFinish = append(c.onFinish, o.OnFinish)
   340  	return nil
   341  }
   342  
   343  func (o OnFinishCallOption) after(*callInfo, *csAttempt) {}
   344  
   345  // MaxCallRecvMsgSize returns a CallOption which sets the maximum message size
   346  // in bytes the client can receive. If this is not set, gRPC uses the default
   347  // 4MB.
   348  func MaxCallRecvMsgSize(bytes int) CallOption {
   349  	return MaxRecvMsgSizeCallOption{MaxRecvMsgSize: bytes}
   350  }
   351  
   352  // MaxRecvMsgSizeCallOption is a CallOption that indicates the maximum message
   353  // size in bytes the client can receive.
   354  //
   355  // # Experimental
   356  //
   357  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   358  // later release.
   359  type MaxRecvMsgSizeCallOption struct {
   360  	MaxRecvMsgSize int
   361  }
   362  
   363  func (o MaxRecvMsgSizeCallOption) before(c *callInfo) error {
   364  	c.maxReceiveMessageSize = &o.MaxRecvMsgSize
   365  	return nil
   366  }
   367  func (o MaxRecvMsgSizeCallOption) after(*callInfo, *csAttempt) {}
   368  
   369  // CallAuthority returns a CallOption that sets the HTTP/2 :authority header of
   370  // an RPC to the specified value. When using CallAuthority, the credentials in
   371  // use must implement the AuthorityValidator interface.
   372  //
   373  // # Experimental
   374  //
   375  // Notice: This API is EXPERIMENTAL and may be changed or removed in a later
   376  // release.
   377  func CallAuthority(authority string) CallOption {
   378  	return AuthorityOverrideCallOption{Authority: authority}
   379  }
   380  
   381  // AuthorityOverrideCallOption is a CallOption that indicates the HTTP/2
   382  // :authority header value to use for the call.
   383  //
   384  // # Experimental
   385  //
   386  // Notice: This type is EXPERIMENTAL and may be changed or removed in a later
   387  // release.
   388  type AuthorityOverrideCallOption struct {
   389  	Authority string
   390  }
   391  
   392  func (o AuthorityOverrideCallOption) before(c *callInfo) error {
   393  	c.authority = o.Authority
   394  	return nil
   395  }
   396  
   397  func (o AuthorityOverrideCallOption) after(*callInfo, *csAttempt) {}
   398  
   399  // MaxCallSendMsgSize returns a CallOption which sets the maximum message size
   400  // in bytes the client can send. If this is not set, gRPC uses the default
   401  // `math.MaxInt32`.
   402  func MaxCallSendMsgSize(bytes int) CallOption {
   403  	return MaxSendMsgSizeCallOption{MaxSendMsgSize: bytes}
   404  }
   405  
   406  // MaxSendMsgSizeCallOption is a CallOption that indicates the maximum message
   407  // size in bytes the client can send.
   408  //
   409  // # Experimental
   410  //
   411  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   412  // later release.
   413  type MaxSendMsgSizeCallOption struct {
   414  	MaxSendMsgSize int
   415  }
   416  
   417  func (o MaxSendMsgSizeCallOption) before(c *callInfo) error {
   418  	c.maxSendMessageSize = &o.MaxSendMsgSize
   419  	return nil
   420  }
   421  func (o MaxSendMsgSizeCallOption) after(*callInfo, *csAttempt) {}
   422  
   423  // PerRPCCredentials returns a CallOption that sets credentials.PerRPCCredentials
   424  // for a call.
   425  func PerRPCCredentials(creds credentials.PerRPCCredentials) CallOption {
   426  	return PerRPCCredsCallOption{Creds: creds}
   427  }
   428  
   429  // PerRPCCredsCallOption is a CallOption that indicates the per-RPC
   430  // credentials to use for the call.
   431  //
   432  // # Experimental
   433  //
   434  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   435  // later release.
   436  type PerRPCCredsCallOption struct {
   437  	Creds credentials.PerRPCCredentials
   438  }
   439  
   440  func (o PerRPCCredsCallOption) before(c *callInfo) error {
   441  	c.creds = o.Creds
   442  	return nil
   443  }
   444  func (o PerRPCCredsCallOption) after(*callInfo, *csAttempt) {}
   445  
   446  // UseCompressor returns a CallOption which sets the compressor used when
   447  // sending the request.  If WithCompressor is also set, UseCompressor has
   448  // higher priority.
   449  //
   450  // # Experimental
   451  //
   452  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   453  // later release.
   454  func UseCompressor(name string) CallOption {
   455  	return CompressorCallOption{CompressorType: name}
   456  }
   457  
   458  // CompressorCallOption is a CallOption that indicates the compressor to use.
   459  //
   460  // # Experimental
   461  //
   462  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   463  // later release.
   464  type CompressorCallOption struct {
   465  	CompressorType string
   466  }
   467  
   468  func (o CompressorCallOption) before(c *callInfo) error {
   469  	c.compressorName = o.CompressorType
   470  	return nil
   471  }
   472  func (o CompressorCallOption) after(*callInfo, *csAttempt) {}
   473  
   474  // CallContentSubtype returns a CallOption that will set the content-subtype
   475  // for a call. For example, if content-subtype is "json", the Content-Type over
   476  // the wire will be "application/grpc+json". The content-subtype is converted
   477  // to lowercase before being included in Content-Type. See Content-Type on
   478  // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
   479  // more details.
   480  //
   481  // If ForceCodec is not also used, the content-subtype will be used to look up
   482  // the Codec to use in the registry controlled by RegisterCodec. See the
   483  // documentation on RegisterCodec for details on registration. The lookup of
   484  // content-subtype is case-insensitive. If no such Codec is found, the call
   485  // will result in an error with code codes.Internal.
   486  //
   487  // If ForceCodec is also used, that Codec will be used for all request and
   488  // response messages, with the content-subtype set to the given contentSubtype
   489  // here for requests.
   490  func CallContentSubtype(contentSubtype string) CallOption {
   491  	return ContentSubtypeCallOption{ContentSubtype: strings.ToLower(contentSubtype)}
   492  }
   493  
   494  // ContentSubtypeCallOption is a CallOption that indicates the content-subtype
   495  // used for marshaling messages.
   496  //
   497  // # Experimental
   498  //
   499  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   500  // later release.
   501  type ContentSubtypeCallOption struct {
   502  	ContentSubtype string
   503  }
   504  
   505  func (o ContentSubtypeCallOption) before(c *callInfo) error {
   506  	c.contentSubtype = o.ContentSubtype
   507  	return nil
   508  }
   509  func (o ContentSubtypeCallOption) after(*callInfo, *csAttempt) {}
   510  
   511  // ForceCodec returns a CallOption that will set codec to be used for all
   512  // request and response messages for a call. The result of calling Name() will
   513  // be used as the content-subtype after converting to lowercase, unless
   514  // CallContentSubtype is also used.
   515  //
   516  // See Content-Type on
   517  // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
   518  // more details. Also see the documentation on RegisterCodec and
   519  // CallContentSubtype for more details on the interaction between Codec and
   520  // content-subtype.
   521  //
   522  // This function is provided for advanced users; prefer to use only
   523  // CallContentSubtype to select a registered codec instead.
   524  //
   525  // # Experimental
   526  //
   527  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   528  // later release.
   529  func ForceCodec(codec encoding.Codec) CallOption {
   530  	return ForceCodecCallOption{Codec: codec}
   531  }
   532  
   533  // ForceCodecCallOption is a CallOption that indicates the codec used for
   534  // marshaling messages.
   535  //
   536  // # Experimental
   537  //
   538  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   539  // later release.
   540  type ForceCodecCallOption struct {
   541  	Codec encoding.Codec
   542  }
   543  
   544  func (o ForceCodecCallOption) before(c *callInfo) error {
   545  	c.codec = newCodecV1Bridge(o.Codec)
   546  	return nil
   547  }
   548  func (o ForceCodecCallOption) after(*callInfo, *csAttempt) {}
   549  
   550  // ForceCodecV2 returns a CallOption that will set codec to be used for all
   551  // request and response messages for a call. The result of calling Name() will
   552  // be used as the content-subtype after converting to lowercase, unless
   553  // CallContentSubtype is also used.
   554  //
   555  // See Content-Type on
   556  // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
   557  // more details. Also see the documentation on RegisterCodec and
   558  // CallContentSubtype for more details on the interaction between Codec and
   559  // content-subtype.
   560  //
   561  // This function is provided for advanced users; prefer to use only
   562  // CallContentSubtype to select a registered codec instead.
   563  //
   564  // # Experimental
   565  //
   566  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   567  // later release.
   568  func ForceCodecV2(codec encoding.CodecV2) CallOption {
   569  	return ForceCodecV2CallOption{CodecV2: codec}
   570  }
   571  
   572  // ForceCodecV2CallOption is a CallOption that indicates the codec used for
   573  // marshaling messages.
   574  //
   575  // # Experimental
   576  //
   577  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   578  // later release.
   579  type ForceCodecV2CallOption struct {
   580  	CodecV2 encoding.CodecV2
   581  }
   582  
   583  func (o ForceCodecV2CallOption) before(c *callInfo) error {
   584  	c.codec = o.CodecV2
   585  	return nil
   586  }
   587  
   588  func (o ForceCodecV2CallOption) after(*callInfo, *csAttempt) {}
   589  
   590  // CallCustomCodec behaves like ForceCodec, but accepts a grpc.Codec instead of
   591  // an encoding.Codec.
   592  //
   593  // Deprecated: use ForceCodec instead.
   594  func CallCustomCodec(codec Codec) CallOption {
   595  	return CustomCodecCallOption{Codec: codec}
   596  }
   597  
   598  // CustomCodecCallOption is a CallOption that indicates the codec used for
   599  // marshaling messages.
   600  //
   601  // # Experimental
   602  //
   603  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   604  // later release.
   605  type CustomCodecCallOption struct {
   606  	Codec Codec
   607  }
   608  
   609  func (o CustomCodecCallOption) before(c *callInfo) error {
   610  	c.codec = newCodecV0Bridge(o.Codec)
   611  	return nil
   612  }
   613  func (o CustomCodecCallOption) after(*callInfo, *csAttempt) {}
   614  
   615  // MaxRetryRPCBufferSize returns a CallOption that limits the amount of memory
   616  // used for buffering this RPC's requests for retry purposes.
   617  //
   618  // # Experimental
   619  //
   620  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   621  // later release.
   622  func MaxRetryRPCBufferSize(bytes int) CallOption {
   623  	return MaxRetryRPCBufferSizeCallOption{bytes}
   624  }
   625  
   626  // MaxRetryRPCBufferSizeCallOption is a CallOption indicating the amount of
   627  // memory to be used for caching this RPC for retry purposes.
   628  //
   629  // # Experimental
   630  //
   631  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
   632  // later release.
   633  type MaxRetryRPCBufferSizeCallOption struct {
   634  	MaxRetryRPCBufferSize int
   635  }
   636  
   637  func (o MaxRetryRPCBufferSizeCallOption) before(c *callInfo) error {
   638  	c.maxRetryRPCBufferSize = o.MaxRetryRPCBufferSize
   639  	return nil
   640  }
   641  func (o MaxRetryRPCBufferSizeCallOption) after(*callInfo, *csAttempt) {}
   642  
   643  // The format of the payload: compressed or not?
   644  type payloadFormat uint8
   645  
   646  const (
   647  	compressionNone payloadFormat = 0 // no compression
   648  	compressionMade payloadFormat = 1 // compressed
   649  )
   650  
   651  func (pf payloadFormat) isCompressed() bool {
   652  	return pf == compressionMade
   653  }
   654  
   655  type streamReader interface {
   656  	ReadMessageHeader(header []byte) error
   657  	Read(n int) (mem.BufferSlice, error)
   658  }
   659  
   660  // parser reads complete gRPC messages from the underlying reader.
   661  type parser struct {
   662  	// r is the underlying reader.
   663  	// See the comment on recvMsg for the permissible
   664  	// error types.
   665  	r streamReader
   666  
   667  	// The header of a gRPC message. Find more detail at
   668  	// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
   669  	header [5]byte
   670  
   671  	// bufferPool is the pool of shared receive buffers.
   672  	bufferPool mem.BufferPool
   673  }
   674  
   675  // recvMsg reads a complete gRPC message from the stream.
   676  //
   677  // It returns the message and its payload (compression/encoding)
   678  // format. The caller owns the returned msg memory.
   679  //
   680  // If there is an error, possible values are:
   681  //   - io.EOF, when no messages remain
   682  //   - io.ErrUnexpectedEOF
   683  //   - of type transport.ConnectionError
   684  //   - an error from the status package
   685  //
   686  // No other error values or types must be returned, which also means
   687  // that the underlying streamReader must not return an incompatible
   688  // error.
   689  func (p *parser) recvMsg(maxReceiveMessageSize int) (payloadFormat, mem.BufferSlice, error) {
   690  	err := p.r.ReadMessageHeader(p.header[:])
   691  	if err != nil {
   692  		return 0, nil, err
   693  	}
   694  
   695  	pf := payloadFormat(p.header[0])
   696  	length := binary.BigEndian.Uint32(p.header[1:])
   697  
   698  	if int64(length) > int64(maxInt) {
   699  		return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max length allowed on current machine (%d vs. %d)", length, maxInt)
   700  	}
   701  	if int(length) > maxReceiveMessageSize {
   702  		return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize)
   703  	}
   704  
   705  	data, err := p.r.Read(int(length))
   706  	if err != nil {
   707  		if err == io.EOF {
   708  			err = io.ErrUnexpectedEOF
   709  		}
   710  		return 0, nil, err
   711  	}
   712  	return pf, data, nil
   713  }
   714  
   715  // encode serializes msg and returns a buffer containing the message, or an
   716  // error if it is too large to be transmitted by grpc.  If msg is nil, it
   717  // generates an empty message.
   718  func encode(c baseCodec, msg any) (mem.BufferSlice, error) {
   719  	if msg == nil { // NOTE: typed nils will not be caught by this check
   720  		return nil, nil
   721  	}
   722  	b, err := c.Marshal(msg)
   723  	if err != nil {
   724  		return nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error())
   725  	}
   726  	if bufSize := uint(b.Len()); bufSize > math.MaxUint32 {
   727  		b.Free()
   728  		return nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", bufSize)
   729  	}
   730  	return b, nil
   731  }
   732  
   733  // compress returns the input bytes compressed by compressor or cp.
   734  // If both compressors are nil, or if the message has zero length, returns nil,
   735  // indicating no compression was done.
   736  //
   737  // TODO(dfawley): eliminate cp parameter by wrapping Compressor in an encoding.Compressor.
   738  func compress(in mem.BufferSlice, cp Compressor, compressor encoding.Compressor, pool mem.BufferPool) (mem.BufferSlice, payloadFormat, error) {
   739  	if (compressor == nil && cp == nil) || in.Len() == 0 {
   740  		return nil, compressionNone, nil
   741  	}
   742  	var out mem.BufferSlice
   743  	w := mem.NewWriter(&out, pool)
   744  	wrapErr := func(err error) error {
   745  		out.Free()
   746  		return status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error())
   747  	}
   748  	if compressor != nil {
   749  		z, err := compressor.Compress(w)
   750  		if err != nil {
   751  			return nil, 0, wrapErr(err)
   752  		}
   753  		for _, b := range in {
   754  			if _, err := z.Write(b.ReadOnlyData()); err != nil {
   755  				return nil, 0, wrapErr(err)
   756  			}
   757  		}
   758  		if err := z.Close(); err != nil {
   759  			return nil, 0, wrapErr(err)
   760  		}
   761  	} else {
   762  		// This is obviously really inefficient since it fully materializes the data, but
   763  		// there is no way around this with the old Compressor API. At least it attempts
   764  		// to return the buffer to the provider, in the hopes it can be reused (maybe
   765  		// even by a subsequent call to this very function).
   766  		buf := in.MaterializeToBuffer(pool)
   767  		defer buf.Free()
   768  		if err := cp.Do(w, buf.ReadOnlyData()); err != nil {
   769  			return nil, 0, wrapErr(err)
   770  		}
   771  	}
   772  	return out, compressionMade, nil
   773  }
   774  
   775  const (
   776  	payloadLen = 1
   777  	sizeLen    = 4
   778  	headerLen  = payloadLen + sizeLen
   779  )
   780  
   781  // msgHeader returns a 5-byte header for the message being transmitted and the
   782  // payload, which is compData if non-nil or data otherwise.
   783  func msgHeader(data, compData mem.BufferSlice, pf payloadFormat) (hdr []byte, payload mem.BufferSlice) {
   784  	hdr = make([]byte, headerLen)
   785  	hdr[0] = byte(pf)
   786  
   787  	var length uint32
   788  	if pf.isCompressed() {
   789  		length = uint32(compData.Len())
   790  		payload = compData
   791  	} else {
   792  		length = uint32(data.Len())
   793  		payload = data
   794  	}
   795  
   796  	// Write length of payload into buf
   797  	binary.BigEndian.PutUint32(hdr[payloadLen:], length)
   798  	return hdr, payload
   799  }
   800  
   801  func outPayload(client bool, msg any, dataLength, payloadLength int, t time.Time) *stats.OutPayload {
   802  	return &stats.OutPayload{
   803  		Client:           client,
   804  		Payload:          msg,
   805  		Length:           dataLength,
   806  		WireLength:       payloadLength + headerLen,
   807  		CompressedLength: payloadLength,
   808  		SentTime:         t,
   809  	}
   810  }
   811  
   812  func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool, isServer bool) *status.Status {
   813  	switch pf {
   814  	case compressionNone:
   815  	case compressionMade:
   816  		if recvCompress == "" || recvCompress == encoding.Identity {
   817  			return status.New(codes.Internal, "grpc: compressed flag set with identity or empty encoding")
   818  		}
   819  		if !haveCompressor {
   820  			if isServer {
   821  				return status.Newf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress)
   822  			}
   823  			return status.Newf(codes.Internal, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress)
   824  		}
   825  	default:
   826  		return status.Newf(codes.Internal, "grpc: received unexpected payload format %d", pf)
   827  	}
   828  	return nil
   829  }
   830  
   831  type payloadInfo struct {
   832  	compressedLength  int // The compressed length got from wire.
   833  	uncompressedBytes mem.BufferSlice
   834  }
   835  
   836  func (p *payloadInfo) free() {
   837  	if p != nil && p.uncompressedBytes != nil {
   838  		p.uncompressedBytes.Free()
   839  	}
   840  }
   841  
   842  // recvAndDecompress reads a message from the stream, decompressing it if necessary.
   843  //
   844  // Cancelling the returned cancel function releases the buffer back to the pool. So the caller should cancel as soon as
   845  // the buffer is no longer needed.
   846  // TODO: Refactor this function to reduce the number of arguments.
   847  // See: https://google.github.io/styleguide/go/best-practices.html#function-argument-lists
   848  func recvAndDecompress(p *parser, s recvCompressor, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor, isServer bool,
   849  ) (out mem.BufferSlice, err error) {
   850  	pf, compressed, err := p.recvMsg(maxReceiveMessageSize)
   851  	if err != nil {
   852  		return nil, err
   853  	}
   854  
   855  	compressedLength := compressed.Len()
   856  
   857  	if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil, isServer); st != nil {
   858  		compressed.Free()
   859  		return nil, st.Err()
   860  	}
   861  
   862  	if pf.isCompressed() {
   863  		defer compressed.Free()
   864  		// To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor,
   865  		// use this decompressor as the default.
   866  		out, err = decompress(compressor, compressed, dc, maxReceiveMessageSize, p.bufferPool)
   867  		if err != nil {
   868  			return nil, err
   869  		}
   870  	} else {
   871  		out = compressed
   872  	}
   873  
   874  	if payInfo != nil {
   875  		payInfo.compressedLength = compressedLength
   876  		out.Ref()
   877  		payInfo.uncompressedBytes = out
   878  	}
   879  
   880  	return out, nil
   881  }
   882  
   883  // decompress processes the given data by decompressing it using either a custom decompressor or a standard compressor.
   884  // If a custom decompressor is provided, it takes precedence. The function validates that the decompressed data
   885  // does not exceed the specified maximum size and returns an error if this limit is exceeded.
   886  // On success, it returns the decompressed data. Otherwise, it returns an error if decompression fails or the data exceeds the size limit.
   887  func decompress(compressor encoding.Compressor, d mem.BufferSlice, dc Decompressor, maxReceiveMessageSize int, pool mem.BufferPool) (mem.BufferSlice, error) {
   888  	if dc != nil {
   889  		uncompressed, err := dc.Do(d.Reader())
   890  		if err != nil {
   891  			return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
   892  		}
   893  		if len(uncompressed) > maxReceiveMessageSize {
   894  			return nil, status.Errorf(codes.ResourceExhausted, "grpc: message after decompression larger than max (%d vs. %d)", len(uncompressed), maxReceiveMessageSize)
   895  		}
   896  		return mem.BufferSlice{mem.SliceBuffer(uncompressed)}, nil
   897  	}
   898  	if compressor != nil {
   899  		dcReader, err := compressor.Decompress(d.Reader())
   900  		if err != nil {
   901  			return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the message: %v", err)
   902  		}
   903  
   904  		// Read at most one byte more than the limit from the decompressor.
   905  		// Unless the limit is MaxInt64, in which case, that's impossible, so
   906  		// apply no limit.
   907  		if limit := int64(maxReceiveMessageSize); limit < math.MaxInt64 {
   908  			dcReader = io.LimitReader(dcReader, limit+1)
   909  		}
   910  		out, err := mem.ReadAll(dcReader, pool)
   911  		if err != nil {
   912  			out.Free()
   913  			return nil, status.Errorf(codes.Internal, "grpc: failed to read decompressed data: %v", err)
   914  		}
   915  
   916  		if out.Len() > maxReceiveMessageSize {
   917  			out.Free()
   918  			return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max %d", maxReceiveMessageSize)
   919  		}
   920  		return out, nil
   921  	}
   922  	return nil, status.Errorf(codes.Internal, "grpc: no decompressor available for compressed payload")
   923  }
   924  
   925  type recvCompressor interface {
   926  	RecvCompress() string
   927  }
   928  
   929  // For the two compressor parameters, both should not be set, but if they are,
   930  // dc takes precedence over compressor.
   931  // TODO(dfawley): wrap the old compressor/decompressor using the new API?
   932  func recv(p *parser, c baseCodec, s recvCompressor, dc Decompressor, m any, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor, isServer bool) error {
   933  	data, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor, isServer)
   934  	if err != nil {
   935  		return err
   936  	}
   937  
   938  	// If the codec wants its own reference to the data, it can get it. Otherwise, always
   939  	// free the buffers.
   940  	defer data.Free()
   941  
   942  	if err := c.Unmarshal(data, m); err != nil {
   943  		return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err)
   944  	}
   945  
   946  	return nil
   947  }
   948  
   949  // Information about RPC
   950  type rpcInfo struct {
   951  	failfast      bool
   952  	preloaderInfo *compressorInfo
   953  }
   954  
   955  // Information about Preloader
   956  // Responsible for storing codec, and compressors
   957  // If stream (s) has  context s.Context which stores rpcInfo that has non nil
   958  // pointers to codec, and compressors, then we can use preparedMsg for Async message prep
   959  // and reuse marshalled bytes
   960  type compressorInfo struct {
   961  	codec baseCodec
   962  	cp    Compressor
   963  	comp  encoding.Compressor
   964  }
   965  
   966  type rpcInfoContextKey struct{}
   967  
   968  func newContextWithRPCInfo(ctx context.Context, failfast bool, codec baseCodec, cp Compressor, comp encoding.Compressor) context.Context {
   969  	return context.WithValue(ctx, rpcInfoContextKey{}, &rpcInfo{
   970  		failfast: failfast,
   971  		preloaderInfo: &compressorInfo{
   972  			codec: codec,
   973  			cp:    cp,
   974  			comp:  comp,
   975  		},
   976  	})
   977  }
   978  
   979  func rpcInfoFromContext(ctx context.Context) (s *rpcInfo, ok bool) {
   980  	s, ok = ctx.Value(rpcInfoContextKey{}).(*rpcInfo)
   981  	return
   982  }
   983  
   984  // Code returns the error code for err if it was produced by the rpc system.
   985  // Otherwise, it returns codes.Unknown.
   986  //
   987  // Deprecated: use status.Code instead.
   988  func Code(err error) codes.Code {
   989  	return status.Code(err)
   990  }
   991  
   992  // ErrorDesc returns the error description of err if it was produced by the rpc system.
   993  // Otherwise, it returns err.Error() or empty string when err is nil.
   994  //
   995  // Deprecated: use status.Convert and Message method instead.
   996  func ErrorDesc(err error) string {
   997  	return status.Convert(err).Message()
   998  }
   999  
  1000  // Errorf returns an error containing an error code and a description;
  1001  // Errorf returns nil if c is OK.
  1002  //
  1003  // Deprecated: use status.Errorf instead.
  1004  func Errorf(c codes.Code, format string, a ...any) error {
  1005  	return status.Errorf(c, format, a...)
  1006  }
  1007  
  1008  var errContextCanceled = status.Error(codes.Canceled, context.Canceled.Error())
  1009  var errContextDeadline = status.Error(codes.DeadlineExceeded, context.DeadlineExceeded.Error())
  1010  
  1011  // toRPCErr converts an error into an error from the status package.
  1012  func toRPCErr(err error) error {
  1013  	switch err {
  1014  	case nil, io.EOF:
  1015  		return err
  1016  	case context.DeadlineExceeded:
  1017  		return errContextDeadline
  1018  	case context.Canceled:
  1019  		return errContextCanceled
  1020  	case io.ErrUnexpectedEOF:
  1021  		return status.Error(codes.Internal, err.Error())
  1022  	}
  1023  
  1024  	switch e := err.(type) {
  1025  	case transport.ConnectionError:
  1026  		return status.Error(codes.Unavailable, e.Desc)
  1027  	case *transport.NewStreamError:
  1028  		return toRPCErr(e.Err)
  1029  	}
  1030  
  1031  	if _, ok := status.FromError(err); ok {
  1032  		return err
  1033  	}
  1034  
  1035  	return status.Error(codes.Unknown, err.Error())
  1036  }
  1037  
  1038  // setCallInfoCodec should only be called after CallOptions have been applied.
  1039  func setCallInfoCodec(c *callInfo) error {
  1040  	if c.codec != nil {
  1041  		// codec was already set by a CallOption; use it, but set the content
  1042  		// subtype if it is not set.
  1043  		if c.contentSubtype == "" {
  1044  			// c.codec is a baseCodec to hide the difference between grpc.Codec and
  1045  			// encoding.Codec (Name vs. String method name).  We only support
  1046  			// setting content subtype from encoding.Codec to avoid a behavior
  1047  			// change with the deprecated version.
  1048  			if ec, ok := c.codec.(encoding.CodecV2); ok {
  1049  				c.contentSubtype = strings.ToLower(ec.Name())
  1050  			}
  1051  		}
  1052  		return nil
  1053  	}
  1054  
  1055  	if c.contentSubtype == "" {
  1056  		// No codec specified in CallOptions; use proto by default.
  1057  		c.codec = getCodec(proto.Name)
  1058  		return nil
  1059  	}
  1060  
  1061  	// c.contentSubtype is already lowercased in CallContentSubtype
  1062  	c.codec = getCodec(c.contentSubtype)
  1063  	if c.codec == nil {
  1064  		return status.Errorf(codes.Internal, "no codec registered for content-subtype %s", c.contentSubtype)
  1065  	}
  1066  	return nil
  1067  }
  1068  
  1069  // The SupportPackageIsVersion variables are referenced from generated protocol
  1070  // buffer files to ensure compatibility with the gRPC version used.  The latest
  1071  // support package version is 9.
  1072  //
  1073  // Older versions are kept for compatibility.
  1074  //
  1075  // These constants should not be referenced from any other code.
  1076  const (
  1077  	SupportPackageIsVersion3 = true
  1078  	SupportPackageIsVersion4 = true
  1079  	SupportPackageIsVersion5 = true
  1080  	SupportPackageIsVersion6 = true
  1081  	SupportPackageIsVersion7 = true
  1082  	SupportPackageIsVersion8 = true
  1083  	SupportPackageIsVersion9 = true
  1084  )
  1085  
  1086  const grpcUA = "grpc-go/" + Version