-
Notifications
You must be signed in to change notification settings - Fork 12
/
httpclient.go
123 lines (102 loc) · 3.46 KB
/
httpclient.go
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
123
// Copyright 2021-Present Couchbase, Inc.
//
// Use of this software is governed by the Business Source License included
// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified
// in that file, in accordance with the Business Source License, use of this
// software will be governed by the Apache License, Version 2.0, included in
// the file licenses/APL2.txt.
package cbgt
import (
"crypto/tls"
"crypto/x509"
"io"
"net"
"net/http"
"sync"
"time"
"golang.org/x/net/http2"
)
var HttpTransportDialContextTimeout = 30 * time.Second // Go's default is 30 secs.
var HttpTransportDialContextKeepAlive = 30 * time.Second // Go's default is 30 secs.
var HttpTransportMaxIdleConns = 300 // Go's default is 100 (0 means no limit).
var HttpTransportMaxIdleConnsPerHost = 100 // Go's default is 2.
var HttpTransportIdleConnTimeout = 90 * time.Second // Go's default is 90 secs.
var HttpTransportTLSHandshakeTimeout = 10 * time.Second // Go's default is 10 secs.
var HttpTransportExpectContinueTimeout = 1 * time.Second // Go's default is 1 secs.
var httpClientM sync.RWMutex
type HTTPClient interface {
Get(string) (*http.Response, error)
Post(string, string, io.Reader) (*http.Response, error)
Do(*http.Request) (*http.Response, error)
}
// A wrapper over the HTTP client.
type WrapperHTTPClient struct {
Client *http.Client
}
var httpClient = &WrapperHTTPClient{
Client: http.DefaultClient,
}
func (w *WrapperHTTPClient) Get(url string) (*http.Response, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
return w.Do(req)
}
func (w *WrapperHTTPClient) Post(url, contentType string, body io.Reader) (*http.Response, error) {
req, err := http.NewRequest("POST", url, body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", contentType)
return w.Do(req)
}
var UserAgentStr = "CB-SearchService"
func (w *WrapperHTTPClient) Do(req *http.Request) (*http.Response, error) {
req.Header.Set("User-Agent", UserAgentStr)
return w.Client.Do(req)
}
func RegisterHttpClient() {
RegisterConfigRefreshCallback("cbgt/httpClient", updateHttpClient)
updateHttpClient(AuthChange_certificates | AuthChange_clientCertificates)
}
func HttpClient() HTTPClient {
httpClientM.RLock()
client := httpClient
httpClientM.RUnlock()
return client
}
func updateHttpClient(status int) error {
if status&AuthChange_certificates != 0 ||
status&AuthChange_clientCertificates != 0 {
transport := &http.Transport{
DialContext: (&net.Dialer{
Timeout: HttpTransportDialContextTimeout,
KeepAlive: HttpTransportDialContextKeepAlive,
}).DialContext,
MaxIdleConns: HttpTransportMaxIdleConns,
MaxIdleConnsPerHost: HttpTransportMaxIdleConnsPerHost,
IdleConnTimeout: HttpTransportIdleConnTimeout,
TLSHandshakeTimeout: HttpTransportTLSHandshakeTimeout,
ExpectContinueTimeout: HttpTransportExpectContinueTimeout,
TLSClientConfig: &tls.Config{},
}
ss := GetSecuritySetting()
rootCAs := x509.NewCertPool()
ok := rootCAs.AppendCertsFromPEM(ss.CACertInBytes)
if ok {
transport.TLSClientConfig.RootCAs = rootCAs
transport.TLSClientConfig.Certificates = []tls.Certificate{ss.ClientCertificate}
_ = http2.ConfigureTransport(transport)
} else {
transport.TLSClientConfig.InsecureSkipVerify = true
}
client := &http.Client{
Transport: transport,
}
httpClientM.Lock()
httpClient.Client = client
httpClientM.Unlock()
}
return nil
}