-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
client.go
159 lines (129 loc) · 4.32 KB
/
client.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
149
150
151
152
153
154
155
156
157
158
159
package paymail
import (
"time"
"github.com/go-resty/resty/v2"
"github.com/tonicpow/go-paymail/interfaces"
)
type (
// Client is the Paymail client configuration and options
Client struct {
httpClient *resty.Client // HTTP client for GET/POST requests
options *ClientOptions // Options are all the default settings / configuration
resolver interfaces.DNSResolver // Resolver for DNS look ups
}
// ClientOptions holds all the configuration for client requests and default resources
ClientOptions struct {
brfcSpecs []*BRFCSpec // List of BRFC specifications
dnsPort string // Default DNS port for SRV checks
dnsTimeout time.Duration // Default timeout in seconds for DNS fetching
httpTimeout time.Duration // Default timeout in seconds for GET requests
nameServer string // Default name server for DNS checks
nameServerNetwork string // Default name server network
requestTracing bool // If enabled, it will trace the request timing
retryCount int // Default retry count for HTTP requests
sslDeadline time.Duration // Default timeout in seconds for SSL deadline
sslTimeout time.Duration // Default timeout in seconds for SSL timeout
userAgent string // User agent for all outgoing requests
network Network // The bitcoin network to operate on
}
)
// NewClient creates a new client for all paymail requests
//
// If no options are given, it will use the defaultClientOptions()
// If no client is supplied it will use a default Resty HTTP client
func NewClient(opts ...ClientOps) (ClientInterface, error) {
// Start with the defaults
defaults, err := defaultClientOptions()
if err != nil {
return nil, err
}
// Create a new client
client := &Client{
options: defaults,
}
// Overwrite defaults with any set by user
for _, opt := range opts {
opt(client.options)
}
// Check for specs (if not set, use the defaults)
if len(client.options.brfcSpecs) == 0 {
if client.options.brfcSpecs, err = LoadBRFCs(""); err != nil {
return nil, err
}
}
// Set the resolver
if client.resolver == nil {
r := client.defaultResolver()
client.resolver = &r
}
// Set the Resty HTTP client
if client.httpClient == nil {
client.httpClient = resty.New()
// Set defaults (for GET requests)
client.httpClient.SetTimeout(client.options.httpTimeout)
client.httpClient.SetRetryCount(client.options.retryCount)
}
return client, nil
}
// GetBRFCs will return the list of specs
func (c *Client) GetBRFCs() []*BRFCSpec {
return c.options.brfcSpecs
}
// GetOptions will return the Client options
func (c *Client) GetOptions() *ClientOptions {
return c.options
}
// GetUserAgent will return the user agent string of the client
func (c *Client) GetUserAgent() string {
return c.options.userAgent
}
// GetResolver will return the internal resolver from the client
func (c *Client) GetResolver() interfaces.DNSResolver {
return c.resolver
}
// getRequest is a standard GET request for all outgoing HTTP requests
func (c *Client) getRequest(requestURL string) (response StandardResponse, err error) {
// Set the user agent
req := c.httpClient.R().SetHeader("User-Agent", c.options.userAgent)
// Enable tracing
if c.options.requestTracing {
req.EnableTrace()
}
// Fire the request
var resp *resty.Response
if resp, err = req.Get(requestURL); err != nil {
return
}
// Tracing enabled?
if c.options.requestTracing {
response.Tracing = resp.Request.TraceInfo()
}
// Set the status code
response.StatusCode = resp.StatusCode()
// Set the body
response.Body = resp.Body()
return
}
// postRequest is a standard POST request for all outgoing HTTP requests
func (c *Client) postRequest(requestURL string, data interface{}) (response StandardResponse, err error) {
// Set the user agent
req := c.httpClient.R().SetBody(data).SetHeader("User-Agent", c.options.userAgent)
// Enable tracing
if c.options.requestTracing {
req.EnableTrace()
}
// Fire the request
var resp *resty.Response
if resp, err = req.Post(requestURL); err != nil {
return
}
// Tracing enabled?
if c.options.requestTracing {
response.Tracing = resp.Request.TraceInfo()
}
// Set the status code
response.StatusCode = resp.StatusCode()
// Set the body
response.Body = resp.Body()
return
}