170 lines
4.4 KiB
Go
170 lines
4.4 KiB
Go
package httpc
|
|
|
|
import (
|
|
"compress/gzip"
|
|
"crypto/tls"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// ClientOptFn are options to set different parameters on the Client.
|
|
type ClientOptFn func(*clientOpt) error
|
|
|
|
type clientOpt struct {
|
|
addr string
|
|
insecureSkipVerify bool
|
|
doer doer
|
|
headers http.Header
|
|
authFn func(*http.Request) error
|
|
respFn func(*http.Response) error
|
|
statusFn func(*http.Response) error
|
|
writerFns []WriteCloserFn
|
|
}
|
|
|
|
// WithAddr sets the host address on the client.
|
|
func WithAddr(addr string) ClientOptFn {
|
|
return func(opt *clientOpt) error {
|
|
opt.addr = addr
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithAuth provides a means to set a custom auth that doesn't match
|
|
// the provided auth types here.
|
|
func WithAuth(fn func(r *http.Request) error) ClientOptFn {
|
|
return func(opt *clientOpt) error {
|
|
opt.authFn = fn
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithAuthToken provides token auth for requests.
|
|
func WithAuthToken(token string) ClientOptFn {
|
|
return WithAuth(func(r *http.Request) error {
|
|
r.Header.Set("Authorization", "Token "+token)
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// WithSessionCookie provides cookie auth for requests to mimic the browser.
|
|
// Typically, session is influxdb.Session.Key.
|
|
func WithSessionCookie(session string) ClientOptFn {
|
|
return WithAuth(func(r *http.Request) error {
|
|
r.AddCookie(&http.Cookie{
|
|
Name: "session",
|
|
Value: session,
|
|
})
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// WithContentType sets the content type that will be applied to the requests created
|
|
// by the Client.
|
|
func WithContentType(ct string) ClientOptFn {
|
|
return WithHeader(headerContentType, ct)
|
|
}
|
|
|
|
func withDoer(d doer) ClientOptFn {
|
|
return func(opt *clientOpt) error {
|
|
opt.doer = d
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithHeader sets a default header that will be applied to all requests created
|
|
// by the client.
|
|
func WithHeader(header, val string) ClientOptFn {
|
|
return func(opt *clientOpt) error {
|
|
if opt.headers == nil {
|
|
opt.headers = make(http.Header)
|
|
}
|
|
opt.headers.Add(header, val)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithUserAgentHeader sets the user agent for the http client requests.
|
|
func WithUserAgentHeader(userAgent string) ClientOptFn {
|
|
return WithHeader("User-Agent", userAgent)
|
|
}
|
|
|
|
// WithHTTPClient sets the raw http client on the httpc Client.
|
|
func WithHTTPClient(c *http.Client) ClientOptFn {
|
|
return func(opt *clientOpt) error {
|
|
opt.doer = c
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithInsecureSkipVerify sets the insecure skip verify on the http client's htp transport.
|
|
func WithInsecureSkipVerify(b bool) ClientOptFn {
|
|
return func(opts *clientOpt) error {
|
|
opts.insecureSkipVerify = b
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithRespFn sets the default resp fn for the client that will be applied to all requests
|
|
// generated from it.
|
|
func WithRespFn(fn func(*http.Response) error) ClientOptFn {
|
|
return func(opt *clientOpt) error {
|
|
opt.respFn = fn
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithStatusFn sets the default status fn for the client that will be applied to all requests
|
|
// generated from it.
|
|
func WithStatusFn(fn func(*http.Response) error) ClientOptFn {
|
|
return func(opt *clientOpt) error {
|
|
opt.statusFn = fn
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithWriterFn applies the provided writer behavior to all the request bodies'
|
|
// generated from the client.
|
|
func WithWriterFn(fn WriteCloserFn) ClientOptFn {
|
|
return func(opt *clientOpt) error {
|
|
opt.writerFns = append(opt.writerFns, fn)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithWriterGZIP gzips the request body generated from this client.
|
|
func WithWriterGZIP() ClientOptFn {
|
|
return WithWriterFn(func(w io.WriteCloser) (string, string, io.WriteCloser) {
|
|
return headerContentEncoding, "gzip", gzip.NewWriter(w)
|
|
})
|
|
}
|
|
|
|
// DefaultTransportInsecure is identical to http.DefaultTransport, with
|
|
// the exception that tls.Config is configured with InsecureSkipVerify
|
|
// set to true.
|
|
var DefaultTransportInsecure http.RoundTripper = &http.Transport{
|
|
Proxy: http.ProxyFromEnvironment,
|
|
DialContext: (&net.Dialer{
|
|
Timeout: 30 * time.Second,
|
|
KeepAlive: 30 * time.Second,
|
|
DualStack: true,
|
|
}).DialContext,
|
|
ForceAttemptHTTP2: true,
|
|
MaxIdleConns: 100,
|
|
IdleConnTimeout: 90 * time.Second,
|
|
TLSHandshakeTimeout: 10 * time.Second,
|
|
ExpectContinueTimeout: 1 * time.Second,
|
|
TLSClientConfig: &tls.Config{
|
|
InsecureSkipVerify: true,
|
|
},
|
|
}
|
|
|
|
func defaultHTTPClient(scheme string, insecure bool) *http.Client {
|
|
if scheme == "https" && insecure {
|
|
return &http.Client{Transport: DefaultTransportInsecure}
|
|
}
|
|
return &http.Client{Transport: http.DefaultTransport}
|
|
}
|