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