-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathrequest.go
106 lines (84 loc) · 2.71 KB
/
request.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
package est
import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"errors"
"io/ioutil"
"net/http"
)
// Get issues an HTTP GET request.
// Returns the response body.
func Get(url string, headers map[string]string,
serverCert []byte) ([]byte, error) {
return Send("GET", url, nil, headers, "", "", nil, nil, serverCert)
}
// Post issues an HTTP POST request.
// username and password are used for basic auth.
// clientKey and clientCert are used for TLS auth.
// Returns the response body.
func Post(url string, data []byte, headers map[string]string,
username string, password string, clientCert []byte,
clientKey []byte, serverCert []byte) ([]byte, error) {
return Send("POST", url, data, headers, username, password,
clientCert, clientKey, serverCert)
}
// Send issues an HTTP request. Returns the body.
func Send(method string, url string, data []byte, headers map[string]string,
username string, password string,
clientCert []byte,
clientKey []byte, serverCert []byte) ([]byte, error) {
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(serverCert)
tlsConfig := tls.Config{
RootCAs: caCertPool,
}
if clientCert != nil && clientKey != nil {
cert, err := tls.X509KeyPair(clientCert, clientKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
}
tlsConfig.BuildNameToCertificate()
tr := &http.Transport{
TLSClientConfig: &tlsConfig,
}
client := &http.Client{Transport: tr}
req, err := http.NewRequest(method, url, bytes.NewReader(data))
if err != nil {
return nil, err
}
if username != "" && password != "" {
req.SetBasicAuth(username, password)
}
for key, value := range headers {
req.Header.Set(key, value)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
err := errors.New(
"Request error: " + resp.Status + " - " + string(body[:]))
return nil, err
}
encoding := resp.Header.Get("Content-Transfer-Encoding")
prefix := []byte{'-', '-', '-', '-', '-', 'B', 'E', 'G', 'I', 'N'}
if encoding == "base64" && !bytes.HasPrefix(body, prefix) {
bodyDec := make([]byte, base64.StdEncoding.DecodedLen(len(body)))
l, err := base64.StdEncoding.Decode(bodyDec, body)
if err != nil {
return nil, err
}
return bodyDec[:l], nil
}
return body, nil
}