1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
package config
import (
"context"
"crypto/tls"
"crypto/x509"
"io/ioutil"
"net"
"net/http"
"path/filepath"
"strings"
"time"
)
const (
socketBaseUrl = "http://unix"
unixSocketProtocol = "http+unix://"
httpProtocol = "http://"
httpsProtocol = "https://"
defaultReadTimeoutSeconds = 300
)
type HttpClient struct {
HttpClient *http.Client
Host string
}
func (c *Config) GetHttpClient() *HttpClient {
if c.HttpClient != nil {
return c.HttpClient
}
var transport *http.Transport
var host string
if strings.HasPrefix(c.GitlabUrl, unixSocketProtocol) {
transport, host = c.buildSocketTransport()
} else if strings.HasPrefix(c.GitlabUrl, httpProtocol) {
transport, host = c.buildHttpTransport()
} else if strings.HasPrefix(c.GitlabUrl, httpsProtocol) {
transport, host = c.buildHttpsTransport()
} else {
return nil
}
httpClient := &http.Client{
Transport: transport,
Timeout: c.readTimeout(),
}
client := &HttpClient{HttpClient: httpClient, Host: host}
c.HttpClient = client
return client
}
func (c *Config) buildSocketTransport() (*http.Transport, string) {
socketPath := strings.TrimPrefix(c.GitlabUrl, unixSocketProtocol)
transport := &http.Transport{
DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
dialer := net.Dialer{}
return dialer.DialContext(ctx, "unix", socketPath)
},
}
return transport, socketBaseUrl
}
func (c *Config) buildHttpsTransport() (*http.Transport, string) {
certPool, err := x509.SystemCertPool()
if err != nil {
certPool = x509.NewCertPool()
}
caFile := c.HttpSettings.CaFile
if caFile != "" {
addCertToPool(certPool, caFile)
}
caPath := c.HttpSettings.CaPath
if caPath != "" {
fis, _ := ioutil.ReadDir(caPath)
for _, fi := range fis {
if fi.IsDir() {
continue
}
addCertToPool(certPool, filepath.Join(caPath, fi.Name()))
}
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
InsecureSkipVerify: c.HttpSettings.SelfSignedCert,
},
}
return transport, c.GitlabUrl
}
func addCertToPool(certPool *x509.CertPool, fileName string) {
cert, err := ioutil.ReadFile(fileName)
if err == nil {
certPool.AppendCertsFromPEM(cert)
}
}
func (c *Config) buildHttpTransport() (*http.Transport, string) {
return &http.Transport{}, c.GitlabUrl
}
func (c *Config) readTimeout() time.Duration {
timeoutSeconds := c.HttpSettings.ReadTimeoutSeconds
if timeoutSeconds == 0 {
timeoutSeconds = defaultReadTimeoutSeconds
}
return time.Duration(timeoutSeconds) * time.Second
}
|