Path: blob/dev/pkg/protocols/headless/engine/http_client.go
2072 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,31}3233if options.SNI != "" {34tlsConfig.ServerName = options.SNI35}3637// Add the client certificate authentication to the request if it's configured38var err error39tlsConfig, err = utils.AddConfiguredClientCertToRequest(tlsConfig, options)40if err != nil {41return nil, err42}4344transport := &http.Transport{45ForceAttemptHTTP2: options.ForceAttemptHTTP2,46DialContext: dialers.Fastdialer.Dial,47DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {48if options.TlsImpersonate {49return dialers.Fastdialer.DialTLSWithConfigImpersonate(ctx, network, addr, tlsConfig, impersonate.Random, nil)50}51if options.HasClientCertificates() || options.ForceAttemptHTTP2 {52return dialers.Fastdialer.DialTLSWithConfig(ctx, network, addr, tlsConfig)53}54return dialers.Fastdialer.DialTLS(ctx, network, addr)55},56MaxIdleConns: 500,57MaxIdleConnsPerHost: 500,58MaxConnsPerHost: 500,59TLSClientConfig: tlsConfig,60}61if options.AliveHttpProxy != "" {62if proxyURL, err := url.Parse(options.AliveHttpProxy); err == nil {63transport.Proxy = http.ProxyURL(proxyURL)64}65} else if options.AliveSocksProxy != "" {66socksURL, proxyErr := url.Parse(options.AliveSocksProxy)67if proxyErr != nil {68return nil, err69}70dialer, err := proxy.FromURL(socksURL, proxy.Direct)71if err != nil {72return nil, err73}7475dc := dialer.(interface {76DialContext(ctx context.Context, network, addr string) (net.Conn, error)77})78transport.DialContext = dc.DialContext79}8081jar, _ := cookiejar.New(nil)8283httpclient := &http.Client{84Transport: transport,85Timeout: time.Duration(options.Timeout*3) * time.Second,86Jar: jar,87CheckRedirect: func(req *http.Request, via []*http.Request) error {88// the browser should follow redirects not us89return http.ErrUseLastResponse90},91}9293return httpclient, nil94}959697