func (c *Cast) Do(ctx context.Context, request *Request) (*Response, error) {
	body, err := request.ReqBody()
	if err != nil {
		c.logger.WithError(err).Error("request.reqBody")
		return nil, err
	}
	for _, hook := range c.beforeRequestHooks {
		err = hook(c, request)
		if err != nil {
			return nil, err
		}
	}
	tracer := opentracing.GlobalTracer()
	span := opentracing.SpanFromContext(ctx)
	if tracer != nil && span != nil {
		err := tracer.Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(request.header))
		if err != nil {
			c.logger.WithError(err).Error("tracer.Inject")
			return nil, err
		}
	}
	request.rawRequest, err = http.NewRequestWithContext(ctx, request.method, c.baseURL+request.path, bytes.NewReader(body))
	if err != nil {
		c.logger.WithError(err).Error("http.NewRequest")
		return nil, err
	}
	for _, hook := range c.requestHooks {
		err = hook(c, request)
		if err != nil {
			return nil, err
		}
	}
	rep, err := c.genReply(request)
	if err != nil {
		return nil, err
	}
	for _, hook := range c.responseHooks {
		if err := hook(c, rep); err != nil {
			c.logger.WithError(err).Error("hook(c, resp)")
			return nil, err
		}
	}
	return rep, nil
}
Do initiates a request.
package cast
import (
	"bytes"
	"context"
	"crypto/tls"
	"errors"
	"github.com/cep21/circuit/v3"
	"github.com/cep21/circuit/v3/closers/hystrix"
	"github.com/opentracing/opentracing-go"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"time"
	"github.com/sirupsen/logrus"
)
const (
	defaultDumpBodyLimit int = 8192
)
type Cast struct {
	client             *http.Client
	baseURL            string
	header             http.Header
	basicAuth          *BasicAuth
	bearerToken        string
	cookies            []*http.Cookie
	retry              int
	stg                backoffStrategy
	beforeRequestHooks []BeforeRequestHook
	requestHooks       []RequestHook
	responseHooks      []responseHook
	retryHooks         []RetryHook
	dumpFlag           int
	httpClientTimeout  time.Duration
	logger             *logrus.Logger
	h                  circuit.Manager
	defaultCircuitName string
}
func New(sl ...Setter) (*Cast, error) {
	c := new(Cast)
	c.header = make(http.Header)
	c.beforeRequestHooks = defaultBeforeRequestHooks
	c.requestHooks = defaultRequestHooks
	c.responseHooks = defaultResponseHooks
	c.retryHooks = defaultRetryHooks
	c.dumpFlag = fStd
	c.httpClientTimeout = 10 * time.Second
	c.logger = logrus.New()
	c.logger.SetFormatter(&logrus.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})
	c.logger.SetReportCaller(true)
	c.logger.SetOutput(os.Stderr)
	c.logger.SetLevel(logrus.InfoLevel)
	configuration := hystrix.Factory{
		ConfigureOpener: hystrix.ConfigureOpener{
			ErrorThresholdPercentage: 70,
			RequestVolumeThreshold:   10,
			RollingDuration:          10 * time.Second,
			Now:                      time.Now,
			NumBuckets:               10,
		},
		ConfigureCloser: hystrix.ConfigureCloser{
			SleepWindow:                  10 * time.Second,
			HalfOpenAttempts:             1,
			RequiredConcurrentSuccessful: 1,
		},
	}
	c.h = circuit.Manager{
		DefaultCircuitProperties: []circuit.CommandPropertiesConstructor{configuration.Configure},
	}
	for _, s := range sl {
		if err := s(c); err != nil {
			return nil, err
		}
	}
	c.client = &http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			DialContext: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
				DualStack: true,
			}).DialContext,
			MaxIdleConns:          2000,
			MaxIdleConnsPerHost:   2000,
			IdleConnTimeout:       90 * time.Second,
			TLSHandshakeTimeout:   10 * time.Second,
			ExpectContinueTimeout: 1 * time.Second,
		},
		Timeout: c.httpClientTimeout,
	}
	return c, nil
}
func (c *Cast) SetInsecureSkipVerify(v bool) error {
	t, ok := c.client.Transport.(*http.Transport)
	if !ok {
		return errors.New("http client type assertion failed")
	}
	if t.TLSClientConfig == nil {
		t.TLSClientConfig = &tls.Config{}
	}
	t.TLSClientConfig.InsecureSkipVerify = true
	return nil
}
func (c *Cast) NewRequest() *Request {
	return NewRequest()
}