github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/transport/config.go (about)

     1  package transport
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/volts-dev/volts/config"
    10  	"github.com/volts-dev/volts/internal/acme"
    11  	"github.com/volts-dev/volts/internal/acme/autocert"
    12  	"github.com/volts-dev/volts/logger"
    13  	"golang.org/x/net/proxy"
    14  )
    15  
    16  var (
    17  	log            = logger.New("Transport")
    18  	DefaultTimeout = time.Second * 5
    19  )
    20  
    21  type (
    22  	Option       func(*Config)
    23  	DialOption   func(*DialConfig)
    24  	ListenOption func(*ListenConfig)
    25  
    26  	Config struct {
    27  		config.Config
    28  		Name       string `field:"-"` // config name/path in config file
    29  		PrefixName string `field:"-"` // config prefix name
    30  		Listener   IListener
    31  		// Addrs is the list of intermediary addresses to connect to
    32  		Addrs []string
    33  		// Codec is the codec interface to use where headers are not supported
    34  		// by the transport and the entire payload must be encoded
    35  		//Codec codec.Marshaler
    36  
    37  		// 证书
    38  		EnableACME   bool          `field:"enable_acme"`
    39  		ACMEHosts    []string      `field:"acme_hosts"`
    40  		ACMEProvider acme.Provider `field:"-"`
    41  		// Secure tells the transport to secure the connection.
    42  		// In the case TLSConfig is not specified best effort self-signed
    43  		// certs should be used
    44  		Secure bool
    45  		// TLSConfig to secure the connection. The assumption is that this
    46  		// is mTLS keypair
    47  		TlsConfig *tls.Config
    48  
    49  		//DialTimeout sets timeout for dialing
    50  		DialTimeout time.Duration
    51  		// ReadTimeout sets readdeadline for underlying net.Conns
    52  		ReadTimeout time.Duration
    53  		// WriteTimeout sets writedeadline for underlying net.Conns
    54  		WriteTimeout time.Duration
    55  
    56  		// Other options for implementations of the interface
    57  		// can be stored in a context
    58  		Context context.Context
    59  	}
    60  
    61  	DialConfig struct {
    62  		// Tells the transport this is a streaming connection with
    63  		// multiple calls to send/recv and that send may not even be called
    64  		Stream bool
    65  		// Other options for implementations of the interface
    66  		// can be stored in a context
    67  		Secure      bool
    68  		DialTimeout time.Duration
    69  		// ReadTimeout sets readdeadline for underlying net.Conns
    70  		ReadTimeout time.Duration
    71  		// WriteTimeout sets writedeadline for underlying net.Conns
    72  		WriteTimeout time.Duration
    73  
    74  		// TODO: add tls options when dialling
    75  		// Currently set in global options
    76  		Ja3      Ja3 // TODO 添加加缓存
    77  		ProxyURL string
    78  		dialer   proxy.Dialer
    79  		Network  string
    80  
    81  		Context context.Context
    82  	}
    83  
    84  	ListenConfig struct {
    85  		// TODO: add tls options when listening
    86  		// Currently set in global options
    87  
    88  		// Other options for implementations of the interface
    89  		// can be stored in a context
    90  		Context context.Context
    91  	}
    92  )
    93  
    94  func (self *DialConfig) Init(opts ...DialOption) {
    95  	for _, opt := range opts {
    96  		if opt != nil {
    97  			opt(self)
    98  		}
    99  	}
   100  }
   101  
   102  func newConfig(opts ...Option) *Config {
   103  	cfg := &Config{
   104  		//Name:         "transport",
   105  		DialTimeout:  DefaultTimeout,
   106  		ReadTimeout:  DefaultTimeout,
   107  		WriteTimeout: DefaultTimeout,
   108  	}
   109  	cfg.Init(opts...)
   110  	config.Register(cfg)
   111  	return cfg
   112  }
   113  
   114  func (self *Config) String() string {
   115  	if len(self.PrefixName) > 0 {
   116  		return strings.Join([]string{self.PrefixName, "transport"}, ".")
   117  	}
   118  	return self.Name
   119  }
   120  
   121  func (self *Config) Init(opts ...Option) {
   122  	for _, opt := range opts {
   123  		if opt != nil {
   124  			opt(self)
   125  		}
   126  	}
   127  }
   128  
   129  func (self *Config) Load() error {
   130  	if err := self.LoadToModel(self); err != nil {
   131  		return err
   132  	}
   133  
   134  	// 打开了SSL需要指定自动更新服务者
   135  	if self.EnableACME && self.ACMEProvider == nil {
   136  		// 默认是 Let’s Encrypt
   137  		self.ACMEProvider = autocert.NewProvider()
   138  	}
   139  
   140  	return nil
   141  }
   142  
   143  func (self *Config) Save(immed ...bool) error {
   144  	return self.SaveFromModel(self, immed...)
   145  }
   146  
   147  func Debug() Option {
   148  	return func(cfg *Config) {
   149  		cfg.Debug = true
   150  		cfg.ReadTimeout = 60 * time.Second
   151  		cfg.WriteTimeout = 60 * time.Second
   152  		cfg.DialTimeout = 60 * time.Second
   153  	}
   154  }
   155  
   156  func Logger() logger.ILogger {
   157  	return log
   158  }
   159  
   160  // Addrs to use for transport
   161  func Addrs(addrs ...string) Option {
   162  	return func(cfg *Config) {
   163  		cfg.Addrs = addrs
   164  	}
   165  }
   166  
   167  // Timeout sets the timeout for Send/Recv execution
   168  func Timeout(t time.Duration) Option {
   169  	return func(cfg *Config) {
   170  		cfg.ReadTimeout = t
   171  		cfg.WriteTimeout = t
   172  		cfg.DialTimeout = t
   173  	}
   174  }
   175  
   176  // Timeout sets the timeout for Send/Recv execution
   177  func ReadTimeout(t time.Duration) Option {
   178  	return func(cfg *Config) {
   179  		cfg.ReadTimeout = t
   180  	}
   181  }
   182  
   183  // Timeout sets the timeout for Send/Recv execution
   184  func WriteTimeout(t time.Duration) Option {
   185  	return func(cfg *Config) {
   186  		cfg.WriteTimeout = t
   187  	}
   188  }
   189  
   190  // Timeout sets the timeout for Send/Recv execution
   191  func DialTimeout(t time.Duration) Option {
   192  	return func(cfg *Config) {
   193  		cfg.DialTimeout = t
   194  	}
   195  }
   196  
   197  func EnableACME(b bool) Option {
   198  	return func(cfg *Config) {
   199  		cfg.EnableACME = b
   200  	}
   201  }
   202  func ACMEHosts(hosts ...string) Option {
   203  	return func(o *Config) {
   204  		o.ACMEHosts = hosts
   205  	}
   206  }
   207  
   208  func ACMEProvider(p acme.Provider) Option {
   209  	return func(o *Config) {
   210  		o.ACMEProvider = p
   211  	}
   212  }
   213  
   214  // Use secure communication. If TLSConfig is not specified we
   215  // use InsecureSkipVerify and generate a self signed cert
   216  func Secure(b bool) Option {
   217  	return func(cfg *Config) {
   218  		cfg.Secure = b
   219  	}
   220  }
   221  
   222  // TLSConfig to be used for the transport.
   223  func TLSConfig(t *tls.Config) Option {
   224  	return func(cfg *Config) {
   225  		cfg.TlsConfig = t
   226  	}
   227  }
   228  
   229  func WithNetwork(network string) DialOption {
   230  	return func(o *DialConfig) {
   231  		o.Network = network
   232  	}
   233  }
   234  
   235  func WithTLS() DialOption {
   236  	return func(o *DialConfig) {
   237  		o.Secure = true
   238  	}
   239  }
   240  
   241  func WithContext(ctx context.Context) DialOption {
   242  	return func(o *DialConfig) {
   243  		o.Context = ctx
   244  	}
   245  }
   246  
   247  // Indicates whether this is a streaming connection
   248  func WithStream() DialOption {
   249  	return func(o *DialConfig) {
   250  		o.Stream = true
   251  	}
   252  }
   253  
   254  func WithTimeout(dial, read, write time.Duration) DialOption {
   255  	return func(cfg *DialConfig) {
   256  		if dial > 0 {
   257  			cfg.DialTimeout = dial
   258  		}
   259  		if read > 0 {
   260  			cfg.ReadTimeout = read
   261  		}
   262  		if write > 0 {
   263  			cfg.WriteTimeout = write
   264  		}
   265  	}
   266  }
   267  
   268  func WithDialTimeout(timeout time.Duration) DialOption {
   269  	return func(cfg *DialConfig) {
   270  		cfg.DialTimeout = timeout
   271  	}
   272  }
   273  
   274  func WithReadTimeout(timeout time.Duration) DialOption {
   275  	return func(cfg *DialConfig) {
   276  		cfg.ReadTimeout = timeout
   277  	}
   278  }
   279  
   280  func WithWriteTimeout(timeout time.Duration) DialOption {
   281  	return func(cfg *DialConfig) {
   282  		cfg.WriteTimeout = timeout
   283  	}
   284  }
   285  
   286  func WithJa3(ja3, userAgent string) DialOption {
   287  	return func(o *DialConfig) {
   288  		o.Ja3.Ja3 = ja3
   289  		o.Ja3.UserAgent = userAgent
   290  	}
   291  }
   292  
   293  func WithProxyURL(proxyURL string) DialOption {
   294  	return func(o *DialConfig) {
   295  		o.ProxyURL = proxyURL
   296  	}
   297  }
   298  
   299  func WithDialer(dialer proxy.Dialer) DialOption {
   300  	return func(o *DialConfig) {
   301  		o.dialer = dialer
   302  	}
   303  }
   304  
   305  // 修改Config.json的路径
   306  func WithConfigPrefixName(prefixName string) Option {
   307  	return func(cfg *Config) {
   308  		// 注销配置
   309  		config.Unregister(cfg)
   310  
   311  		cfg.PrefixName = prefixName
   312  
   313  		// 重新注册
   314  		config.Register(cfg)
   315  	}
   316  }