httpsms.*Client.newRequest   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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