-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient_http.go
109 lines (95 loc) · 2.8 KB
/
client_http.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
package kickbox
import (
"errors"
"fmt"
"net/http"
"time"
"golang.org/x/time/rate"
)
// ClientHTTP kickbox
type ClientHTTP struct {
httpClient *http.Client
apiKey string
baseURL string
connPool chan struct{}
rateLimit *rate.Limiter
}
// Ensure Verifier implementation
var _ Verifier = (*ClientHTTP)(nil)
// ClientHTTPOptions holds optional values to parametrize the client
type ClientHTTPOptions struct {
baseURL string
maxConcurrentConnections uint
httpClient *http.Client
rateLimiter *rate.Limiter
}
// ClientHTTPOption signature
type ClientHTTPOption func(*ClientHTTPOptions) error
// OverrideBaseURL allows override the main endpoint to run tests against mock servers
func OverrideBaseURL(baseURL string) ClientHTTPOption {
return func(o *ClientHTTPOptions) error {
if baseURL == "" {
return errors.New("baseURL is empty")
}
o.baseURL = baseURL
return nil
}
}
// MaxConcurrentConnections sets the number of maximum simultaneous connections to the service
// see: https://docs.kickbox.com/docs/using-the-api#api-limits
func MaxConcurrentConnections(num uint) ClientHTTPOption {
return func(o *ClientHTTPOptions) error {
if num <= 0 {
return fmt.Errorf("max concurrent connection must be greater than zero")
}
o.maxConcurrentConnections = num
return nil
}
}
// CustomRateLimiter sets a custom rate limiter
// see: https://docs.kickbox.com/docs/using-the-api#api-limits
func CustomRateLimiter(r *rate.Limiter) ClientHTTPOption {
return func(o *ClientHTTPOptions) error {
if r == nil {
return errors.New("rate limiter is nil")
}
o.rateLimiter = r
return nil
}
}
// CustomHTTPClient allows to use a custom http client instead of the default one
func CustomHTTPClient(client *http.Client) ClientHTTPOption {
return func(o *ClientHTTPOptions) error {
if client == nil {
return errors.New("client is nil")
}
o.httpClient = client
return nil
}
}
// New creates a new kickbox HTTP API client
func New(apiKey string, opts ...ClientHTTPOption) (*ClientHTTP, error) {
if apiKey == "" {
return nil, errors.New("apikey is empty")
}
// default option values
const defaultClientTimeout = 30 * time.Second
options := ClientHTTPOptions{
baseURL: BaseURL,
maxConcurrentConnections: maxConcurrentConnections,
httpClient: &http.Client{Timeout: defaultClientTimeout},
rateLimiter: rate.NewLimiter(rate.Limit(maxRatePerMinute), 1),
}
for _, o := range opts {
if err := o(&options); err != nil {
return nil, fmt.Errorf("applying optional settings: %v", err)
}
}
return &ClientHTTP{
apiKey: apiKey,
httpClient: options.httpClient,
baseURL: options.baseURL,
connPool: make(chan struct{}, options.maxConcurrentConnections),
rateLimit: options.rateLimiter,
}, nil
}