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 }