summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/pkg/web/client.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/go/collectors/go.d.plugin/pkg/web/client.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/pkg/web/client.go b/src/go/collectors/go.d.plugin/pkg/web/client.go
new file mode 100644
index 000000000..616d8f8fc
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/pkg/web/client.go
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package web
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "net/http"
+ "net/url"
+
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/tlscfg"
+)
+
+// ErrRedirectAttempted indicates that a redirect occurred.
+var ErrRedirectAttempted = errors.New("redirect")
+
+// Client is the configuration of the HTTP client.
+// This structure is not intended to be used directly as part of a module's configuration.
+// Supported configuration file formats: YAML.
+type Client struct {
+ // Timeout specifies a time limit for requests made by this Client.
+ // Default (zero value) is no timeout. Must be set before http.Client creation.
+ Timeout Duration `yaml:"timeout" json:"timeout"`
+
+ // NotFollowRedirect specifies the policy for handling redirects.
+ // Default (zero value) is std http package default policy (stop after 10 consecutive requests).
+ NotFollowRedirect bool `yaml:"not_follow_redirects" json:"not_follow_redirects"`
+
+ // ProxyURL specifies the URL of the proxy to use. An empty string means use the environment variables
+ // HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the lowercase versions thereof) to get the URL.
+ ProxyURL string `yaml:"proxy_url" json:"proxy_url"`
+
+ // TLSConfig specifies the TLS configuration.
+ tlscfg.TLSConfig `yaml:",inline" json:",inline"`
+}
+
+// NewHTTPClient returns a new *http.Client given a Client configuration and an error if any.
+func NewHTTPClient(cfg Client) (*http.Client, error) {
+ tlsConfig, err := tlscfg.NewTLSConfig(cfg.TLSConfig)
+ if err != nil {
+ return nil, fmt.Errorf("error on creating TLS config: %v", err)
+ }
+
+ if cfg.ProxyURL != "" {
+ if _, err := url.Parse(cfg.ProxyURL); err != nil {
+ return nil, fmt.Errorf("error on parsing proxy URL '%s': %v", cfg.ProxyURL, err)
+ }
+ }
+
+ d := &net.Dialer{Timeout: cfg.Timeout.Duration()}
+
+ transport := &http.Transport{
+ Proxy: proxyFunc(cfg.ProxyURL),
+ TLSClientConfig: tlsConfig,
+ DialContext: d.DialContext,
+ TLSHandshakeTimeout: cfg.Timeout.Duration(),
+ }
+
+ return &http.Client{
+ Timeout: cfg.Timeout.Duration(),
+ Transport: transport,
+ CheckRedirect: redirectFunc(cfg.NotFollowRedirect),
+ }, nil
+}
+
+func redirectFunc(notFollowRedirect bool) func(req *http.Request, via []*http.Request) error {
+ if follow := !notFollowRedirect; follow {
+ return nil
+ }
+ return func(_ *http.Request, _ []*http.Request) error { return ErrRedirectAttempted }
+}
+
+func proxyFunc(rawProxyURL string) func(r *http.Request) (*url.URL, error) {
+ if rawProxyURL == "" {
+ return http.ProxyFromEnvironment
+ }
+ proxyURL, _ := url.Parse(rawProxyURL)
+ return http.ProxyURL(proxyURL)
+}