func (h *HTTPX) Do(req *retryablehttp.Request) (*Response, error) {
	timeStart := time.Now()
	httpresp, err := h.getResponse(req)
	if err != nil {
		return nil, err
	}
	var resp Response
	resp.Headers = httpresp.Header.Clone()
	rawresp, err := httputilz.DumpResponse(httpresp)
	if err != nil {
		return nil, err
	}
	resp.Raw = rawresp
	var respbody []byte
	if httpresp.StatusCode != http.StatusSwitchingProtocols {
		var err error
		respbody, err = ioutil.ReadAll(httpresp.Body)
		if err != nil {
			return nil, err
		}
	}
	closeErr := httpresp.Body.Close()
	if closeErr != nil {
		return nil, closeErr
	}
	respbodystr := string(respbody)
	if h.Options.VHostStripHTML {
		respbodystr = h.htmlPolicy.Sanitize(respbodystr)
	}
	resp.ContentLength = utf8.RuneCountInString(respbodystr)
	resp.Data = respbody
	resp.StatusCode = httpresp.StatusCode
	resp.Words = len(strings.Split(respbodystr, " "))
	resp.Lines = len(strings.Split(respbodystr, "\n"))
	if !h.Options.Unsafe {
		resp.TLSData = h.TLSGrab(httpresp)
	}
	resp.CSPData = h.CSPGrab(httpresp)
	resp.Duration = time.Since(timeStart)
	return &resp, nil
}
Do http request
package httpx
import (
	"crypto/tls"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"time"
	"unicode/utf8"
	"github.com/microcosm-cc/bluemonday"
	"github.com/projectdiscovery/cdncheck"
	"github.com/projectdiscovery/fastdialer/fastdialer"
	"github.com/projectdiscovery/httpx/common/httputilz"
	"github.com/projectdiscovery/rawhttp"
	retryablehttp "github.com/projectdiscovery/retryablehttp-go"
	"golang.org/x/net/http2"
)
type HTTPX struct {
	client          *retryablehttp.Client
	client2         *http.Client
	Filters         []Filter
	Options         *Options
	htmlPolicy      *bluemonday.Policy
	CustomHeaders   map[string]string
	RequestOverride *RequestOverride
	cdn             *cdncheck.Client
	Dialer          *fastdialer.Dialer
}
func New(options *Options) (*HTTPX, error) {
	httpx := &HTTPX{}
	dialer, err := fastdialer.NewDialer(fastdialer.DefaultOptions)
	if err != nil {
		return nil, fmt.Errorf("could not create resolver cache: %s", err)
	}
	httpx.Dialer = dialer
	httpx.Options = options
	var retryablehttpOptions = retryablehttp.DefaultOptionsSpraying
	retryablehttpOptions.Timeout = httpx.Options.Timeout
	retryablehttpOptions.RetryMax = httpx.Options.RetryMax
	var redirectFunc = func(_ *http.Request, _ []*http.Request) error {
		return http.ErrUseLastResponse  
	}
	if httpx.Options.FollowRedirects {
		redirectFunc = nil
	}
	if httpx.Options.FollowHostRedirects {
		redirectFunc = func(redirectedRequest *http.Request, previousRequest []*http.Request) error {  
			var newHost = redirectedRequest.URL.Host
			var oldHost = previousRequest[0].URL.Host
			if newHost != oldHost {
				return http.ErrUseLastResponse  
			}
			return nil
		}
	}
	transport := &http.Transport{
		DialContext:         httpx.Dialer.Dial,
		MaxIdleConnsPerHost: -1,
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
		DisableKeepAlives: true,
	}
	if httpx.Options.HTTPProxy != "" {
		proxyURL, parseErr := url.Parse(httpx.Options.HTTPProxy)
		if parseErr != nil {
			return nil, parseErr
		}
		transport.Proxy = http.ProxyURL(proxyURL)
	}
	httpx.client = retryablehttp.NewWithHTTPClient(&http.Client{
		Transport:     transport,
		Timeout:       httpx.Options.Timeout,
		CheckRedirect: redirectFunc,
	}, retryablehttpOptions)
	httpx.client2 = &http.Client{
		Transport: &http2.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
			AllowHTTP: true,
		},
		Timeout: httpx.Options.Timeout,
	}
	httpx.htmlPolicy = bluemonday.NewPolicy()
	httpx.CustomHeaders = httpx.Options.CustomHeaders
	httpx.RequestOverride = &options.RequestOverride
	if options.CdnCheck {
		httpx.cdn, err = cdncheck.NewWithCache()
		if err != nil {
			return nil, fmt.Errorf("could not create cdn check: %s", err)
		}
	}
	return httpx, nil
}