pkg/scan/client/client.go   A
last analyzed

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 66
dl 0
loc 103
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
F client.NewClientFromConfig 0 71 15
A client.buildTransport 0 14 2
1
package client
2
3
import (
4
	"context"
5
	"crypto/tls"
6
	"net"
7
	"net/http"
8
	"net/http/cookiejar"
9
	"net/url"
10
	"time"
11
12
	"github.com/pkg/errors"
13
	"github.com/stefanoj3/dirstalk/pkg/scan/client/cookie"
14
	"golang.org/x/net/proxy"
15
)
16
17
func NewClientFromConfig(
18
	timeoutInMilliseconds int,
19
	socks5Url *url.URL,
20
	userAgent string,
21
	useCookieJar bool,
22
	cookies []*http.Cookie,
23
	headers map[string]string,
24
	shouldCacheRequests bool,
25
	shouldSkipSSLCertificatesValidation bool,
26
	u *url.URL,
27
) (*http.Client, error) {
28
	transport := buildTransport(shouldSkipSSLCertificatesValidation)
29
30
	c := &http.Client{
31
		Timeout:   time.Millisecond * time.Duration(timeoutInMilliseconds),
32
		Transport: transport,
33
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
34
			return http.ErrUseLastResponse
35
		},
36
	}
37
38
	if useCookieJar {
39
		jar, err := cookiejar.New(nil)
40
		if err != nil {
41
			return nil, errors.Wrap(err, "NewClientFromConfig: failed to create cookie jar")
42
		}
43
44
		c.Jar = jar
45
	}
46
47
	if c.Jar != nil {
48
		c.Jar.SetCookies(u, cookies)
49
	}
50
51
	if len(cookies) > 0 && c.Jar == nil {
52
		c.Jar = cookie.NewStatelessJar(cookies)
53
	}
54
55
	if socks5Url != nil {
56
		tbDialer, err := proxy.FromURL(socks5Url, proxy.Direct)
57
		if err != nil {
58
			return nil, errors.Wrap(err, "NewClientFromConfig: failed to create socks5 proxy")
59
		}
60
61
		transport.DialContext = func(ctx context.Context, network, addr string) (conn net.Conn, e error) {
62
			return tbDialer.Dial(network, addr)
63
		}
64
	}
65
66
	var err error
67
68
	c.Transport, err = decorateTransportWithUserAgentDecorator(c.Transport, userAgent)
69
	if err != nil {
70
		return nil, errors.Wrap(err, "NewClientFromConfig: failed to decorate transport")
71
	}
72
73
	if len(headers) > 0 {
74
		c.Transport, err = decorateTransportWithHeadersDecorator(c.Transport, headers)
75
		if err != nil {
76
			return nil, errors.Wrap(err, "NewClientFromConfig: failed to decorate transport")
77
		}
78
	}
79
80
	if shouldCacheRequests {
81
		c.Transport, err = decorateTransportWithRequestCacheDecorator(c.Transport)
82
		if err != nil {
83
			return nil, errors.Wrap(err, "NewClientFromConfig: failed to decorate transport")
84
		}
85
	}
86
87
	return c, nil
88
}
89
90
func buildTransport(shouldSkipSSLCertificatesValidation bool) *http.Transport {
91
	transport := http.Transport{
92
		MaxIdleConns:          100,
93
		IdleConnTimeout:       90 * time.Second,
94
		TLSHandshakeTimeout:   10 * time.Second,
95
		ExpectContinueTimeout: 1 * time.Second,
96
	}
97
98
	if shouldSkipSSLCertificatesValidation {
99
		//nolint:gosec
100
		transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
101
	}
102
103
	return &transport
104
}
105