github.com/projectdiscovery/nuclei/v2@v2.9.15/pkg/protocols/headless/engine/http_client.go (about) 1 package engine 2 3 import ( 4 "context" 5 "crypto/tls" 6 "net" 7 "net/http" 8 "net/http/cookiejar" 9 "net/url" 10 "time" 11 12 "golang.org/x/net/proxy" 13 14 "github.com/projectdiscovery/fastdialer/fastdialer/ja3/impersonate" 15 "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/protocolstate" 16 "github.com/projectdiscovery/nuclei/v2/pkg/protocols/utils" 17 "github.com/projectdiscovery/nuclei/v2/pkg/types" 18 ) 19 20 // newHttpClient creates a new http client for headless communication with a timeout 21 func newHttpClient(options *types.Options) (*http.Client, error) { 22 dialer := protocolstate.Dialer 23 24 // Set the base TLS configuration definition 25 tlsConfig := &tls.Config{ 26 Renegotiation: tls.RenegotiateOnceAsClient, 27 InsecureSkipVerify: true, 28 MinVersion: tls.VersionTLS10, 29 } 30 31 if options.SNI != "" { 32 tlsConfig.ServerName = options.SNI 33 } 34 35 // Add the client certificate authentication to the request if it's configured 36 var err error 37 tlsConfig, err = utils.AddConfiguredClientCertToRequest(tlsConfig, options) 38 if err != nil { 39 return nil, err 40 } 41 42 transport := &http.Transport{ 43 ForceAttemptHTTP2: options.ForceAttemptHTTP2, 44 DialContext: dialer.Dial, 45 DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) { 46 if options.TlsImpersonate { 47 return dialer.DialTLSWithConfigImpersonate(ctx, network, addr, tlsConfig, impersonate.Random, nil) 48 } 49 return dialer.DialTLS(ctx, network, addr) 50 }, 51 MaxIdleConns: 500, 52 MaxIdleConnsPerHost: 500, 53 MaxConnsPerHost: 500, 54 TLSClientConfig: tlsConfig, 55 } 56 if types.ProxyURL != "" { 57 if proxyURL, err := url.Parse(types.ProxyURL); err == nil { 58 transport.Proxy = http.ProxyURL(proxyURL) 59 } 60 } else if types.ProxySocksURL != "" { 61 socksURL, proxyErr := url.Parse(types.ProxySocksURL) 62 if proxyErr != nil { 63 return nil, err 64 } 65 dialer, err := proxy.FromURL(socksURL, proxy.Direct) 66 if err != nil { 67 return nil, err 68 } 69 70 dc := dialer.(interface { 71 DialContext(ctx context.Context, network, addr string) (net.Conn, error) 72 }) 73 transport.DialContext = dc.DialContext 74 } 75 76 jar, _ := cookiejar.New(nil) 77 78 httpclient := &http.Client{ 79 Transport: transport, 80 Timeout: time.Duration(options.Timeout*3) * time.Second, 81 Jar: jar, 82 CheckRedirect: func(req *http.Request, via []*http.Request) error { 83 // the browser should follow redirects not us 84 return http.ErrUseLastResponse 85 }, 86 } 87 88 return httpclient, nil 89 }