influxdb/flux/client.go

87 lines
1.5 KiB
Go

package flux
import (
"context"
"crypto/tls"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
// Shared transports for all clients to prevent leaking connections.
var (
skipVerifyTransport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
defaultTransport = &http.Transport{}
)
// Client is how we interact with Flux.
type Client struct {
URL *url.URL
InsecureSkipVerify bool
Timeout time.Duration
}
// Ping checks the connection of a Flux.
func (c *Client) Ping(ctx context.Context) error {
t := 2 * time.Second
if c.Timeout > 0 {
t = c.Timeout
}
ctx, cancel := context.WithTimeout(ctx, t)
defer cancel()
err := c.pingTimeout(ctx)
return err
}
func (c *Client) pingTimeout(ctx context.Context) error {
resps := make(chan (error))
go func() {
resps <- c.ping(c.URL)
}()
select {
case resp := <-resps:
return resp
case <-ctx.Done():
return fmt.Errorf("request to backend timed out")
}
}
func (c *Client) ping(u *url.URL) error {
u.Path = "ping"
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return err
}
hc := &http.Client{}
if c.InsecureSkipVerify {
hc.Transport = skipVerifyTransport
} else {
hc.Transport = defaultTransport
}
resp, err := hc.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
if resp.StatusCode != http.StatusNoContent {
var err = fmt.Errorf(string(body))
return err
}
return nil
}