in protocol/triple/triple_protocol/client.go [45:118]
func NewClient(httpClient HTTPClient, url string, options ...ClientOption) *Client {
client := &Client{}
config, err := newClientConfig(url, options)
if err != nil {
client.err = err
return client
}
client.config = config
protocolCli, protocolErr := client.config.Protocol.NewClient(
&protocolClientParams{
CompressionName: config.RequestCompressionName,
CompressionPools: newReadOnlyCompressionPools(
config.CompressionPools,
config.CompressionNames,
),
Codec: config.Codec,
Protobuf: config.protobuf(),
CompressMinBytes: config.CompressMinBytes,
HTTPClient: httpClient,
URL: config.URL,
BufferPool: config.BufferPool,
ReadMaxBytes: config.ReadMaxBytes,
SendMaxBytes: config.SendMaxBytes,
GetURLMaxBytes: config.GetURLMaxBytes,
},
)
if protocolErr != nil {
client.err = protocolErr
return client
}
client.protocolClient = protocolCli
// Rather than applying unary interceptors along the hot path, we can do it
// once at client creation.
unarySpec := config.newSpec(StreamTypeUnary)
unaryFunc := UnaryFunc(func(ctx context.Context, request AnyRequest, response AnyResponse) error {
conn := client.protocolClient.NewConn(ctx, unarySpec, request.Header())
// Send always returns an io.EOF unless the error is from the client-side.
// We want the user to continue to call Receive in those cases to get the
// full error from the server-side.
if err := conn.Send(request.Any()); err != nil && !errors.Is(err, io.EOF) {
// for HTTP/1.1 case, CloseRequest must happen before CloseResponse
// since HTTP/1.1 is of request-response type
_ = conn.CloseRequest()
_ = conn.CloseResponse()
return err
}
if err := conn.CloseRequest(); err != nil {
_ = conn.CloseResponse()
return err
}
if err := receiveUnaryResponse(conn, response); err != nil {
_ = conn.CloseResponse()
return err
}
return conn.CloseResponse()
})
if interceptor := config.Interceptor; interceptor != nil {
unaryFunc = interceptor.WrapUnary(unaryFunc)
}
client.callUnary = func(ctx context.Context, request *Request, response *Response) error {
// To make the specification, peer, and RPC headers visible to the full
// interceptor chain (as though they were supplied by the caller), we'll
// add them here.
request.spec = unarySpec
request.peer = client.protocolClient.Peer()
protocolCli.WriteRequestHeader(StreamTypeUnary, request.Header())
if err := unaryFunc(ctx, request, response); err != nil {
return err
}
return nil
}
return client
}