mirror of
				https://github.com/linka-cloud/grpc.git
				synced 2025-10-31 01:22:29 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			212 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package client
 | |
| 
 | |
| import (
 | |
| 	"crypto/tls"
 | |
| 	"crypto/x509"
 | |
| 	"fmt"
 | |
| 	"os"
 | |
| 
 | |
| 	"google.golang.org/grpc"
 | |
| 
 | |
| 	"go.linka.cloud/grpc-toolkit/interceptors"
 | |
| 	"go.linka.cloud/grpc-toolkit/registry"
 | |
| )
 | |
| 
 | |
| type Options interface {
 | |
| 	Name() string
 | |
| 	Version() string
 | |
| 	Address() string
 | |
| 	Secure() bool
 | |
| 	Registry() registry.Registry
 | |
| 	CA() string
 | |
| 	Cert() string
 | |
| 	Key() string
 | |
| 	TLSConfig() *tls.Config
 | |
| 	DialOptions() []grpc.DialOption
 | |
| 	UnaryInterceptors() []grpc.UnaryClientInterceptor
 | |
| 	StreamInterceptors() []grpc.StreamClientInterceptor
 | |
| }
 | |
| 
 | |
| type Option func(*options)
 | |
| 
 | |
| func WithRegistry(registry registry.Registry) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.registry = registry
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithName(name string) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.name = name
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithVersion(version string) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.version = version
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithAddress(address string) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.addr = address
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithCA(ca string) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.caCert = ca
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithCert(cert string) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.cert = cert
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithKey(key string) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.key = key
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithTLSConfig(conf *tls.Config) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.tlsConfig = conf
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithSecure(s bool) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.secure = s
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithDialOptions(opts ...grpc.DialOption) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.dialOptions = opts
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithInterceptors(i ...interceptors.ClientInterceptors) Option {
 | |
| 	return func(o *options) {
 | |
| 		for _, v := range i {
 | |
| 			o.unaryInterceptors = append(o.unaryInterceptors, v.UnaryClientInterceptor())
 | |
| 			o.streamInterceptors = append(o.streamInterceptors, v.StreamClientInterceptor())
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithUnaryInterceptors(i ...grpc.UnaryClientInterceptor) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.unaryInterceptors = append(o.unaryInterceptors, i...)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WithStreamInterceptors(i ...grpc.StreamClientInterceptor) Option {
 | |
| 	return func(o *options) {
 | |
| 		o.streamInterceptors = append(o.streamInterceptors, i...)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type options struct {
 | |
| 	registry registry.Registry
 | |
| 	name     string
 | |
| 	version  string
 | |
| 	addr     string
 | |
| 
 | |
| 	caCert      string
 | |
| 	cert        string
 | |
| 	key         string
 | |
| 	tlsConfig   *tls.Config
 | |
| 	secure      bool
 | |
| 	dialOptions []grpc.DialOption
 | |
| 
 | |
| 	unaryInterceptors  []grpc.UnaryClientInterceptor
 | |
| 	streamInterceptors []grpc.StreamClientInterceptor
 | |
| }
 | |
| 
 | |
| func (o *options) Name() string {
 | |
| 	return o.name
 | |
| }
 | |
| 
 | |
| func (o *options) Version() string {
 | |
| 	return o.version
 | |
| }
 | |
| 
 | |
| func (o *options) Address() string {
 | |
| 	return o.addr
 | |
| }
 | |
| 
 | |
| func (o *options) Registry() registry.Registry {
 | |
| 	return o.registry
 | |
| }
 | |
| 
 | |
| func (o *options) CA() string {
 | |
| 	return o.caCert
 | |
| }
 | |
| 
 | |
| func (o *options) Cert() string {
 | |
| 	return o.cert
 | |
| }
 | |
| 
 | |
| func (o *options) Key() string {
 | |
| 	return o.key
 | |
| }
 | |
| 
 | |
| func (o *options) TLSConfig() *tls.Config {
 | |
| 	return o.tlsConfig
 | |
| }
 | |
| 
 | |
| func (o *options) Secure() bool {
 | |
| 	return o.secure
 | |
| }
 | |
| 
 | |
| func (o *options) DialOptions() []grpc.DialOption {
 | |
| 	return o.dialOptions
 | |
| }
 | |
| 
 | |
| func (o *options) UnaryInterceptors() []grpc.UnaryClientInterceptor {
 | |
| 	return o.unaryInterceptors
 | |
| }
 | |
| 
 | |
| func (o *options) StreamInterceptors() []grpc.StreamClientInterceptor {
 | |
| 	return o.streamInterceptors
 | |
| }
 | |
| 
 | |
| func (o *options) hasTLSConfig() bool {
 | |
| 	return o.caCert != "" && o.cert != "" && o.key != "" && o.tlsConfig == nil
 | |
| }
 | |
| 
 | |
| func (o *options) parseTLSConfig() error {
 | |
| 	if o.tlsConfig != nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 	if !o.hasTLSConfig() {
 | |
| 		if !o.secure {
 | |
| 			return nil
 | |
| 		}
 | |
| 		o.tlsConfig = &tls.Config{InsecureSkipVerify: true}
 | |
| 		return nil
 | |
| 	}
 | |
| 	caCert, err := os.ReadFile(o.caCert)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	caCertPool := x509.NewCertPool()
 | |
| 	ok := caCertPool.AppendCertsFromPEM(caCert)
 | |
| 	if !ok {
 | |
| 		return fmt.Errorf("failed to load CA Cert from %s", o.caCert)
 | |
| 	}
 | |
| 	cert, err := tls.LoadX509KeyPair(o.cert, o.key)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	o.tlsConfig = &tls.Config{
 | |
| 		Certificates: []tls.Certificate{cert},
 | |
| 		RootCAs:      caCertPool,
 | |
| 	}
 | |
| 	return nil
 | |
| }
 |