Path: blob/dev/pkg/protocols/headless/engine/http_client.go
2840 views
package engine12import (3"context"4"crypto/tls"5"fmt"6"net"7"net/http"8"net/http/cookiejar"9"net/url"10"time"1112"golang.org/x/net/proxy"1314"github.com/projectdiscovery/fastdialer/fastdialer/ja3/impersonate"15"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"16"github.com/projectdiscovery/nuclei/v3/pkg/protocols/utils"17"github.com/projectdiscovery/nuclei/v3/pkg/types"18)1920// newHttpClient creates a new http client for headless communication with a timeout21func newHttpClient(options *types.Options) (*http.Client, error) {22dialers := protocolstate.GetDialersWithId(options.ExecutionId)23if dialers == nil {24return nil, fmt.Errorf("dialers not initialized for %s", options.ExecutionId)25}26// Set the base TLS configuration definition27tlsConfig := &tls.Config{28Renegotiation: tls.RenegotiateOnceAsClient,29InsecureSkipVerify: true,30MinVersion: tls.VersionTLS10,31ClientSessionCache: tls.NewLRUClientSessionCache(1024),32}3334if options.SNI != "" {35tlsConfig.ServerName = options.SNI36}3738// Add the client certificate authentication to the request if it's configured39var err error40tlsConfig, err = utils.AddConfiguredClientCertToRequest(tlsConfig, options)41if err != nil {42return nil, err43}4445transport := &http.Transport{46ForceAttemptHTTP2: options.ForceAttemptHTTP2,47DialContext: dialers.Fastdialer.Dial,48DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {49if options.TlsImpersonate {50return dialers.Fastdialer.DialTLSWithConfigImpersonate(ctx, network, addr, tlsConfig, impersonate.Random, nil)51}52if options.HasClientCertificates() || options.ForceAttemptHTTP2 {53return dialers.Fastdialer.DialTLSWithConfig(ctx, network, addr, tlsConfig)54}55return dialers.Fastdialer.DialTLS(ctx, network, addr)56},57MaxIdleConns: 500,58MaxIdleConnsPerHost: 500,59MaxConnsPerHost: 500,60TLSClientConfig: tlsConfig,61}62if options.AliveHttpProxy != "" {63if proxyURL, err := url.Parse(options.AliveHttpProxy); err == nil {64transport.Proxy = http.ProxyURL(proxyURL)65}66} else if options.AliveSocksProxy != "" {67socksURL, proxyErr := url.Parse(options.AliveSocksProxy)68if proxyErr != nil {69return nil, err70}71dialer, err := proxy.FromURL(socksURL, proxy.Direct)72if err != nil {73return nil, err74}7576dc := dialer.(interface {77DialContext(ctx context.Context, network, addr string) (net.Conn, error)78})79transport.DialContext = dc.DialContext80}8182jar, _ := cookiejar.New(nil)8384httpclient := &http.Client{85Transport: transport,86Timeout: time.Duration(options.Timeout*3) * time.Second,87Jar: jar,88CheckRedirect: func(req *http.Request, via []*http.Request) error {89// the browser should follow redirects not us90return http.ErrUseLastResponse91},92}9394return httpclient, nil95}969798