client.*Client.newResponse   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
dl 0
loc 15
c 0
b 0
f 0
rs 9.9
nop 1
1
package client
2
3
import (
4
	"bytes"
5
	"context"
6
	"encoding/json"
7
	"fmt"
8
	"io"
9
	"io/ioutil"
10
	"net/http"
11
	"strconv"
12
)
13
14
type service struct {
15
	client *Client
16
}
17
18
// Client is the campay API client.
19
// Do not instantiate this client with Client{}. Use the New method instead.
20
type Client struct {
21
	httpClient *http.Client
22
	common     service
23
	baseURL    string
24
	delay      int
25
26
	Status *statusService
27
}
28
29
// New creates and returns a new campay.Client from a slice of campay.ClientOption.
30
func New(options ...Option) *Client {
31
	config := defaultClientConfig()
32
33
	for _, option := range options {
34
		option.apply(config)
35
	}
36
37
	client := &Client{
38
		httpClient: config.httpClient,
39
		delay:      config.delay,
40
		baseURL:    config.baseURL,
41
	}
42
43
	client.common.client = client
44
	client.Status = (*statusService)(&client.common)
45
	return client
46
}
47
48
// newRequest creates an API request. A relative URL can be provided in uri,
49
// in which case it is resolved relative to the BaseURL of the Client.
50
// URI's should always be specified without a preceding slash.
51
func (client *Client) newRequest(ctx context.Context, method, uri string, body interface{}) (*http.Request, error) {
52
	var buf io.ReadWriter
53
	if body != nil {
54
		buf = &bytes.Buffer{}
55
		enc := json.NewEncoder(buf)
56
		enc.SetEscapeHTML(false)
57
		err := enc.Encode(body)
58
		if err != nil {
59
			return nil, err
60
		}
61
	}
62
63
	req, err := http.NewRequestWithContext(ctx, method, client.baseURL+uri, buf)
64
	if err != nil {
65
		return nil, err
66
	}
67
68
	req.Header.Set("Content-Type", "application/json")
69
	req.Header.Set("Accept", "application/json")
70
71
	if client.delay > 0 {
72
		client.addURLParams(req, map[string]string{"sleep": strconv.Itoa(client.delay)})
73
	}
74
75
	return req, nil
76
}
77
78
// addURLParams adds urls parameters to an *http.Request
79
func (client *Client) addURLParams(request *http.Request, params map[string]string) *http.Request {
80
	q := request.URL.Query()
81
	for key, value := range params {
82
		q.Add(key, value)
83
	}
84
	request.URL.RawQuery = q.Encode()
85
	return request
86
}
87
88
// do carries out an HTTP request and returns a Response
89
func (client *Client) do(req *http.Request) (*Response, error) {
90
	if req == nil {
91
		return nil, fmt.Errorf("%T cannot be nil", req)
92
	}
93
94
	httpResponse, err := client.httpClient.Do(req)
95
	if err != nil {
96
		return nil, err
97
	}
98
99
	defer func() { _ = httpResponse.Body.Close() }()
100
101
	resp, err := client.newResponse(httpResponse)
102
	if err != nil {
103
		return resp, err
104
	}
105
106
	_, err = io.Copy(ioutil.Discard, httpResponse.Body)
107
	if err != nil {
108
		return resp, err
109
	}
110
111
	return resp, nil
112
}
113
114
// newResponse converts an *http.Response to *Response
115
func (client *Client) newResponse(httpResponse *http.Response) (*Response, error) {
116
	if httpResponse == nil {
117
		return nil, fmt.Errorf("%T cannot be nil", httpResponse)
118
	}
119
120
	resp := new(Response)
121
	resp.HTTPResponse = httpResponse
122
123
	buf, err := ioutil.ReadAll(resp.HTTPResponse.Body)
124
	if err != nil {
125
		return nil, err
126
	}
127
	resp.Body = &buf
128
129
	return resp, resp.Error()
130
}
131