-
Notifications
You must be signed in to change notification settings - Fork 0
/
request.go
148 lines (124 loc) · 3.61 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package please
import (
"crypto/tls"
"encoding/json"
"fmt"
"strings"
"time"
"github.com/dgrr/http2"
"github.com/valyala/fasthttp"
"github.com/wrk-grp/errnie"
)
/*
Request is a much faster implementation compared to the standard
library one, at the cost of not being 100% compliant.
*/
type Request struct {
conn *fasthttp.Client
endpoint string
headers map[string]string
handle *fasthttp.Request
response *fasthttp.Response
}
/*
NewRequest returns a pointer to a new instance of the client.
You should store the client on the object level and re-use it,
it makes less sense to actually instantiate a new one inside of
individual methods, as you lose out on the builtin concurrency and
buffer pools.
*/
func NewRequest(endpoint string) *Request {
errnie.Debugs("NewRequest() <-", endpoint)
readTimeout, _ := time.ParseDuration("30s")
writeTimeout, _ := time.ParseDuration("30s")
maxIdleConnDuration, _ := time.ParseDuration("1h")
return &Request{
conn: &fasthttp.Client{
ReadTimeout: readTimeout,
WriteTimeout: writeTimeout,
MaxIdleConnDuration: maxIdleConnDuration,
NoDefaultUserAgentHeader: true,
DisableHeaderNamesNormalizing: true,
DisablePathNormalizing: true,
Dial: (&fasthttp.TCPDialer{
Concurrency: 4096,
DNSCacheDuration: 5 * time.Minute,
}).Dial,
},
endpoint: endpoint,
headers: make(map[string]string),
handle: fasthttp.AcquireRequest(),
response: fasthttp.AcquireResponse(),
}
}
/*
AddHeaders allows you to pass in a map[string]string object which will
be iterated over to be converted into HTTP request headers.
*/
func (request *Request) AddHeaders(headers map[string]string) *Request {
errnie.Trace()
request.headers = headers
return request
}
func (request *Request) GetHeader(key string) string {
return string(request.response.Header.Peek(key))
}
/*
AddClientCert configures a client certificate for accessing services that
require this type of authorization.
*/
func (request *Request) AddClientCert(certs *tls.Config) *Request {
errnie.Trace()
request.conn.TLSConfig = certs
return request
}
func (request *Request) Get(path string, data map[string]interface{}) []byte {
errnie.Trace()
return request.do("GET", path, data)
}
func (request *Request) Post(path string, data map[string]interface{}) []byte {
errnie.Trace()
return request.do("POST", path, data)
}
func (request *Request) Put(path string, data map[string]interface{}) []byte {
errnie.Trace()
return request.do("PUT", path, data)
}
/*
do implements the Job interface, which enables the HTTP request to
be scheduled onto a worker pool.
TODO: Only handles POST for now, but that is all we use anyway.
*/
func (request *Request) do(
method string, path string, data map[string]interface{},
) []byte {
errnie.Trace()
hc := &fasthttp.HostClient{
Addr: request.getAddr(),
IsTLS: true,
}
errnie.Handles(http2.ConfigureClient(hc, http2.ClientOpts{}))
request.response.Reset()
request.handle.Header.SetMethod(method)
request.handle.URI().Update(request.endpoint + path)
for key, value := range request.headers {
request.handle.Header.Add(key, value)
}
buf, err := json.Marshal(&data)
errnie.Handles(err)
if method == "POST" {
request.handle.SetBody(buf)
}
if method == "GET" {
url := request.endpoint + path + "?"
for key, value := range data {
url += fmt.Sprintf("&%s=%v", key, value)
}
request.handle.URI().Update(url)
}
errnie.Handles(hc.Do(request.handle, request.response))
return request.response.Body()
}
func (request *Request) getAddr() string {
return strings.Split(request.endpoint, "/")[2] + ":443"
}