package config import ( "crypto/tls" "net/http" "time" ) type ProxyServerConfig struct { HTTP HTTPConfig `yaml:"http"` Metrics MetricsConfig `yaml:"metrics"` Transport TransportConfig `yaml:"transport"` Dial DialConfig `yaml:"dial"` Sentry SentryConfig `yaml:"sentry"` } // See https://pkg.go.dev/net/http#Transport type TransportConfig struct { ForceAttemptHTTP2 InterpolatedBool `yaml:"forceAttemptHTTP2"` MaxIdleConns InterpolatedInt `yaml:"maxIdleConns"` MaxIdleConnsPerHost InterpolatedInt `yaml:"maxIdleConnsPerHost"` MaxConnsPerHost InterpolatedInt `yaml:"maxConnsPerHost"` IdleConnTimeout *InterpolatedDuration `yaml:"idleConnTimeout"` TLSHandshakeTimeout *InterpolatedDuration `yaml:"tlsHandshakeTimeout"` ExpectContinueTimeout *InterpolatedDuration `yaml:"expectContinueTimeout"` DisableKeepAlives InterpolatedBool `yaml:"disableKeepAlives"` DisableCompression InterpolatedBool `yaml:"disableCompression"` ResponseHeaderTimeout *InterpolatedDuration `yaml:"responseHeaderTimeout"` WriteBufferSize InterpolatedInt `yaml:"writeBufferSize"` ReadBufferSize InterpolatedInt `yaml:"readBufferSize"` MaxResponseHeaderBytes InterpolatedInt `yaml:"maxResponseHeaderBytes"` InsecureSkipVerify InterpolatedBool `yaml:"insecureSkipVerify"` } func (c TransportConfig) AsTransport() *http.Transport { httpTransport := http.DefaultTransport.(*http.Transport).Clone() httpTransport.Proxy = http.ProxyFromEnvironment httpTransport.ForceAttemptHTTP2 = bool(c.ForceAttemptHTTP2) httpTransport.MaxIdleConns = int(c.MaxIdleConns) httpTransport.MaxIdleConnsPerHost = int(c.MaxIdleConnsPerHost) httpTransport.MaxConnsPerHost = int(c.MaxConnsPerHost) httpTransport.IdleConnTimeout = time.Duration(*c.IdleConnTimeout) httpTransport.TLSHandshakeTimeout = time.Duration(*c.TLSHandshakeTimeout) httpTransport.ExpectContinueTimeout = time.Duration(*c.ExpectContinueTimeout) httpTransport.DisableKeepAlives = bool(c.DisableKeepAlives) httpTransport.DisableCompression = bool(c.DisableCompression) httpTransport.ResponseHeaderTimeout = time.Duration(*c.ResponseHeaderTimeout) httpTransport.WriteBufferSize = int(c.WriteBufferSize) httpTransport.ReadBufferSize = int(c.ReadBufferSize) httpTransport.MaxResponseHeaderBytes = int64(c.MaxResponseHeaderBytes) if httpTransport.TLSClientConfig == nil { httpTransport.TLSClientConfig = &tls.Config{} } httpTransport.TLSClientConfig.InsecureSkipVerify = bool(c.InsecureSkipVerify) return httpTransport } func NewDefaultProxyServerConfig() ProxyServerConfig { return ProxyServerConfig{ HTTP: NewHTTPConfig("0.0.0.0", 8080), Metrics: NewDefaultMetricsConfig(), Transport: NewDefaultTransportConfig(), Dial: NewDefaultDialConfig(), Sentry: NewDefaultSentryConfig(), } } // See https://pkg.go.dev/net#Dialer type DialConfig struct { Timeout *InterpolatedDuration `yaml:"timeout"` KeepAlive *InterpolatedDuration `yaml:"keepAlive"` FallbackDelay *InterpolatedDuration `yaml:"fallbackDelay"` DualStack InterpolatedBool `yaml:"dualStack"` } func NewDefaultDialConfig() DialConfig { return DialConfig{ Timeout: NewInterpolatedDuration(30 * time.Second), KeepAlive: NewInterpolatedDuration(30 * time.Second), FallbackDelay: NewInterpolatedDuration(300 * time.Millisecond), DualStack: true, } } func NewDefaultTransportConfig() TransportConfig { return TransportConfig{ ForceAttemptHTTP2: true, MaxIdleConns: 100, MaxIdleConnsPerHost: 100, MaxConnsPerHost: 100, IdleConnTimeout: NewInterpolatedDuration(90 * time.Second), TLSHandshakeTimeout: NewInterpolatedDuration(10 * time.Second), ExpectContinueTimeout: NewInterpolatedDuration(1 * time.Second), ResponseHeaderTimeout: NewInterpolatedDuration(10 * time.Second), DisableCompression: false, DisableKeepAlives: false, ReadBufferSize: 4096, WriteBufferSize: 4096, MaxResponseHeaderBytes: 0, InsecureSkipVerify: false, } }