Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple ProxyURLs in http config #323

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions config/http_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,11 @@ type HTTPClientConfig struct {
// The bearer token file for the targets. Deprecated in favour of
// Authorization.CredentialsFile.
BearerTokenFile string `yaml:"bearer_token_file,omitempty" json:"bearer_token_file,omitempty"`
// HTTP proxy server to use to connect to the targets.
ProxyURL URL `yaml:"proxy_url,omitempty" json:"proxy_url,omitempty"`
// HTTP proxy server to use to connect to the targets. ProxyURL is appended
// to ProxyURLs. If multiple URLs are provided, each RoundTrip will cycle
// through them.
ProxyURL URL `yaml:"proxy_url,omitempty" json:"proxy_url,omitempty"`
ProxyURLs []URL `yaml:"proxy_urls,omitempty" json:"proxy_urls,omitempty"`
// TLSConfig to use to connect to the targets.
TLSConfig TLSConfig `yaml:"tls_config,omitempty" json:"tls_config,omitempty"`
// FollowRedirects specifies whether the client should follow HTTP 3xx redirects.
Expand Down Expand Up @@ -343,6 +346,36 @@ func NewClientFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HTTPClie
return client, nil
}

func proxyURLs(cfg HTTPClientConfig) func(*http.Request) (*url.URL, error) {
urls := []*url.URL{}
for _, u := range cfg.ProxyURLs {
if u.URL != nil {
urls = append(urls, u.URL)
}
}
if cfg.ProxyURL.URL != nil {
urls = append(urls, cfg.ProxyURL.URL)
}

if len(urls) == 0 {
return nil
}

// Every time this function is called, it will cycle through the URLs provided
next := 0
var mux sync.Mutex
return func(_ *http.Request) (*url.URL, error) {
mux.Lock()
defer mux.Unlock()
if next >= len(urls) {
next = 0
}
u := urls[next]
next += 1
return u, nil
}
}

// NewRoundTripperFromConfig returns a new HTTP RoundTripper configured for the
// given config.HTTPClientConfig and config.HTTPClientOption.
// The name is used as go-conntrack metric label.
Expand All @@ -369,7 +402,7 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HT
// The only timeout we care about is the configured scrape timeout.
// It is applied on request. So we leave out any timings here.
var rt http.RoundTripper = &http.Transport{
Proxy: http.ProxyURL(cfg.ProxyURL.URL),
Proxy: proxyURLs(cfg),
MaxIdleConns: 20000,
MaxIdleConnsPerHost: 1000, // see https://github.com/golang/go/issues/13801
DisableKeepAlives: !opts.keepAlivesEnabled,
Expand Down