Skip to content

Commit ba65a82

Browse files
committed
Add support for Go contexts
1 parent c9c83ed commit ba65a82

File tree

9 files changed

+104
-25
lines changed

9 files changed

+104
-25
lines changed

client/base_client.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package client
22

33
import (
4+
"context"
45
"net/http"
56
"net/url"
67
"time"
@@ -14,3 +15,9 @@ type BaseClient interface {
1415
SetOauth(auth OAuth)
1516
OAuth() OAuth
1617
}
18+
19+
type BaseClientWithContext interface {
20+
BaseClient
21+
SendRequestWithContext(ctx context.Context, method string, rawURL string, data url.Values,
22+
headers map[string]interface{}, body ...byte) (*http.Response, error)
23+
}

client/client.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ var userAgentOnce sync.Once
140140
func (c *Client) SendRequest(method string, rawURL string, data url.Values,
141141
headers map[string]interface{}, body ...byte) (*http.Response, error) {
142142

143+
return c.SendRequestWithContext(context.Background(), method, rawURL, data, headers, body...)
144+
}
145+
146+
func (c *Client) SendRequestWithContext(ctx context.Context, method string, rawURL string, data url.Values,
147+
headers map[string]interface{}, body ...byte) (*http.Response, error) {
148+
143149
contentType := extractContentTypeHeader(headers)
144150

145151
u, err := url.Parse(rawURL)
@@ -167,7 +173,7 @@ func (c *Client) SendRequest(method string, rawURL string, data url.Values,
167173
//data is already processed and information will be added to u(the url) in the
168174
//previous step. Now body will solely contain json payload
169175
if contentType == jsonContentType {
170-
req, err = http.NewRequest(method, u.String(), bytes.NewBuffer(body))
176+
req, err = http.NewRequestWithContext(ctx, method, u.String(), bytes.NewBuffer(body))
171177
if err != nil {
172178
return nil, err
173179
}
@@ -177,7 +183,7 @@ func (c *Client) SendRequest(method string, rawURL string, data url.Values,
177183
if method == http.MethodPost || method == http.MethodPut || method == http.MethodPatch {
178184
valueReader = strings.NewReader(data.Encode())
179185
}
180-
req, err = http.NewRequestWithContext(context.Background(), method, u.String(), valueReader)
186+
req, err = http.NewRequestWithContext(ctx, method, u.String(), valueReader)
181187
if err != nil {
182188
return nil, err
183189
}
@@ -203,7 +209,7 @@ func (c *Client) SendRequest(method string, rawURL string, data url.Values,
203209
}
204210
if c.OAuth() != nil {
205211
oauth := c.OAuth()
206-
token, _ := c.OAuth().GetAccessToken(context.TODO())
212+
token, _ := c.OAuth().GetAccessToken(ctx)
207213
if token != "" {
208214
req.Header.Add("Authorization", "Bearer "+token)
209215
}

client/page_util.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package client
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67
"strings"
@@ -25,13 +26,17 @@ func ReadLimits(pageSize *int, limit *int) int {
2526
}
2627
}
2728

28-
func GetNext(baseUrl string, response interface{}, getNextPage func(nextPageUri string) (interface{}, error)) (interface{}, error) {
29+
func GetNext(baseUrl string, response interface{}, getNextPage func(ctx context.Context, nextPageUri string) (interface{}, error)) (interface{}, error) {
30+
return GetNextWithContext(context.Background(), baseUrl, response, getNextPage)
31+
}
32+
33+
func GetNextWithContext(ctx context.Context, baseUrl string, response interface{}, getNextPage func(ctx context.Context, nextPageUri string) (interface{}, error)) (interface{}, error) {
2934
nextPageUrl, err := getNextPageUrl(baseUrl, response)
3035
if err != nil {
3136
return nil, err
3237
}
3338

34-
return getNextPage(nextPageUrl)
39+
return getNextPage(ctx, nextPageUrl)
3540
}
3641

3742
func toMap(s interface{}) (map[string]interface{}, error) {

client/page_util_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package client
22

33
import (
44
"bytes"
5+
"context"
56
"encoding/json"
67
"io"
78
"net/http"
@@ -140,7 +141,7 @@ type testMessage struct {
140141
To *string `json:"to,omitempty"`
141142
}
142143

143-
func getSomething(nextPageUrl string) (interface{}, error) {
144+
func getSomething(ctx context.Context, nextPageUrl string) (interface{}, error) {
144145
return nextPageUrl, nil
145146
}
146147

@@ -151,11 +152,11 @@ func TestPageUtil_GetNext(t *testing.T) {
151152
ps := &testResponse{}
152153
_ = json.NewDecoder(response.Body).Decode(ps)
153154

154-
nextPageUrl, err := GetNext(baseUrl, ps, getSomething)
155+
nextPageUrl, err := GetNextWithContext(context.Background(), baseUrl, ps, getSomething)
155156
assert.Equal(t, "https://api.twilio.com/2010-04-01/Accounts/ACXX/Messages.json?From=9999999999&PageNumber=&To=4444444444&PageSize=2&Page=1&PageToken=PASMXX", nextPageUrl)
156157
assert.Nil(t, err)
157158

158-
nextPageUrl, err = GetNext(baseUrl, nil, getSomething)
159+
nextPageUrl, err = GetNextWithContext(context.Background(), baseUrl, nil, getSomething)
159160
assert.Empty(t, nextPageUrl)
160161
assert.Nil(t, err)
161162
}

client/request_handler.go

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,46 @@
22
package client
33

44
import (
5+
"context"
56
"net/http"
67
"net/url"
78
"os"
89
"strings"
910
)
1011

1112
type RequestHandler struct {
12-
Client BaseClient
13-
Edge string
14-
Region string
13+
Client BaseClient
14+
Edge string
15+
Region string
16+
clientWithContext BaseClientWithContext
1517
}
1618

1719
func NewRequestHandler(client BaseClient) *RequestHandler {
20+
// If the base client supports context, add it to the request handler.
21+
// Otherwise we leave it nil and the base client will be used.
22+
clientWithContext, _ := client.(BaseClientWithContext)
23+
1824
return &RequestHandler{
19-
Client: client,
20-
Edge: os.Getenv("TWILIO_EDGE"),
21-
Region: os.Getenv("TWILIO_REGION"),
25+
Client: client,
26+
Edge: os.Getenv("TWILIO_EDGE"),
27+
Region: os.Getenv("TWILIO_REGION"),
28+
clientWithContext: clientWithContext,
2229
}
2330
}
2431

25-
func (c *RequestHandler) sendRequest(method string, rawURL string, data url.Values,
32+
func NewRequestHandlerWithContext(client BaseClientWithContext) *RequestHandler {
33+
return NewRequestHandler(client)
34+
}
35+
36+
func (c *RequestHandler) sendRequest(ctx context.Context, method string, rawURL string, data url.Values,
2637
headers map[string]interface{}, body ...byte) (*http.Response, error) {
2738
parsedURL, err := c.BuildUrl(rawURL)
2839
if err != nil {
2940
return nil, err
3041
}
42+
if c.clientWithContext != nil {
43+
return c.clientWithContext.SendRequestWithContext(ctx, method, parsedURL, data, headers, body...)
44+
}
3145
return c.Client.SendRequest(method, parsedURL, data, headers, body...)
3246
}
3347

@@ -83,21 +97,41 @@ func (c *RequestHandler) BuildUrl(rawURL string) (string, error) {
8397
}
8498

8599
func (c *RequestHandler) Post(path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
86-
return c.sendRequest(http.MethodPost, path, bodyData, headers, body...)
100+
return c.PostWithContext(context.Background(), path, bodyData, headers, body...)
101+
}
102+
103+
func (c *RequestHandler) PostWithContext(ctx context.Context, path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
104+
return c.clientWithContext.SendRequestWithContext(ctx, http.MethodPost, path, bodyData, headers, body...)
87105
}
88106

89107
func (c *RequestHandler) Put(path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
90-
return c.sendRequest(http.MethodPut, path, bodyData, headers, body...)
108+
return c.PutWithContext(context.Background(), path, bodyData, headers, body...)
109+
}
110+
111+
func (c *RequestHandler) PutWithContext(ctx context.Context, path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
112+
return c.clientWithContext.SendRequestWithContext(ctx, http.MethodPut, path, bodyData, headers, body...)
91113
}
92114

93115
func (c *RequestHandler) Patch(path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
94-
return c.sendRequest(http.MethodPatch, path, bodyData, headers, body...)
116+
return c.PatchWithContext(context.Background(), path, bodyData, headers, body...)
117+
}
118+
119+
func (c *RequestHandler) PatchWithContext(ctx context.Context, path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
120+
return c.clientWithContext.SendRequestWithContext(ctx, http.MethodPatch, path, bodyData, headers, body...)
95121
}
96122

97123
func (c *RequestHandler) Get(path string, queryData url.Values, headers map[string]interface{}) (*http.Response, error) {
98-
return c.sendRequest(http.MethodGet, path, queryData, headers)
124+
return c.GetWithContext(context.Background(), path, queryData, headers)
125+
}
126+
127+
func (c *RequestHandler) GetWithContext(ctx context.Context, path string, queryData url.Values, headers map[string]interface{}) (*http.Response, error) {
128+
return c.clientWithContext.SendRequestWithContext(ctx, http.MethodGet, path, queryData, headers)
99129
}
100130

101131
func (c *RequestHandler) Delete(path string, queryData url.Values, headers map[string]interface{}) (*http.Response, error) {
102-
return c.sendRequest(http.MethodDelete, path, queryData, headers)
132+
return c.DeleteWithContext(context.Background(), path, queryData, headers)
133+
}
134+
135+
func (c *RequestHandler) DeleteWithContext(ctx context.Context, path string, queryData url.Values, headers map[string]interface{}) (*http.Response, error) {
136+
return c.clientWithContext.SendRequestWithContext(ctx, http.MethodDelete, path, queryData, headers)
103137
}

client/request_handler_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package client_test
22

33
import (
4+
"context"
45
"errors"
56
"net/http"
67
"net/http/httptest"
@@ -83,7 +84,7 @@ func TestRequestHandler_SendGetRequest(t *testing.T) {
8384
defer errorServer.Close()
8485

8586
requestHandler := NewRequestHandler("user", "pass")
86-
resp, err := requestHandler.Get(errorServer.URL, nil, nil) //nolint:bodyclose
87+
resp, err := requestHandler.GetWithContext(context.Background(), errorServer.URL, nil, nil) //nolint:bodyclose
8788
twilioError := err.(*client.TwilioRestError)
8889
assert.Nil(t, resp)
8990
assert.Equal(t, 400, twilioError.Status)
@@ -108,7 +109,7 @@ func TestRequestHandler_SendPostRequest(t *testing.T) {
108109
defer errorServer.Close()
109110

110111
requestHandler := NewRequestHandler("user", "pass")
111-
resp, err := requestHandler.Post(errorServer.URL, nil, nil) //nolint:bodyclose
112+
resp, err := requestHandler.PostWithContext(context.Background(), errorServer.URL, nil, nil) //nolint:bodyclose
112113
twilioError := err.(*client.TwilioRestError)
113114
assert.Nil(t, resp)
114115
assert.Equal(t, 400, twilioError.Status)

cluster_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package twilio
55

66
import (
7+
"context"
78
"os"
89
"testing"
910

@@ -15,6 +16,7 @@ import (
1516
EventsV1 "github.com/twilio/twilio-go/rest/events/v1"
1617

1718
"github.com/stretchr/testify/assert"
19+
1820
IamV1 "github.com/twilio/twilio-go/rest/iam/v1"
1921
)
2022

@@ -268,3 +270,26 @@ func TestOrgsScimUerList(t *testing.T) {
268270
assert.Nil(t, err)
269271
assert.NotNil(t, users)
270272
}
273+
274+
func TestSendingATextWithContext(t *testing.T) {
275+
params := &Api.CreateMessageParams{}
276+
params.SetTo(to)
277+
params.SetFrom(from)
278+
params.SetBody("Hello there")
279+
280+
resp, err := testClient.Api.CreateMessageWithContext(context.Background(), params)
281+
assert.Nil(t, err)
282+
assert.NotNil(t, resp)
283+
assert.Equal(t, "Hello there", *resp.Body)
284+
assert.Equal(t, from, *resp.From)
285+
assert.Equal(t, to, *resp.To)
286+
}
287+
288+
func TestOrgsAccountsListWithContext(t *testing.T) {
289+
listAccounts, err := orgsClient.PreviewIamOrganization.ListOrganizationAccountsWithContext(context.Background(), orgSid, &PreviewIam.ListOrganizationAccountsParams{})
290+
assert.Nil(t, err)
291+
assert.NotNil(t, listAccounts)
292+
accounts, err := orgsClient.PreviewIamOrganization.FetchOrganizationAccountWithContext(context.Background(), orgSid, &PreviewIam.FetchOrganizationAccountParams{PathAccountSid: &accountSidOrgs})
293+
assert.Nil(t, err)
294+
assert.NotNil(t, accounts)
295+
}

oauth.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func (a *APIOAuth) GetAccessToken(ctx context.Context) (string, error) {
100100
SetClientId(a.creds.ClientId).
101101
SetClientSecret(a.creds.ClientSecret)
102102
a.iamService.RequestHandler().Client.SetOauth(nil) // set oauth to nil to make no-auth request
103-
token, err := a.iamService.CreateToken(params)
103+
token, err := a.iamService.CreateTokenWithContext(ctx, params)
104104
if err == nil {
105105
a.tokenAuth = TokenAuth{
106106
Token: *token.AccessToken,

twilio.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func NewRestClientWithParams(params ClientParams) *RestClient {
187187
} else {
188188
defaultClient.SetAccountSid(username)
189189
}
190-
requestHandler = client.NewRequestHandler(defaultClient)
190+
requestHandler = client.NewRequestHandlerWithContext(defaultClient)
191191
} else if params.ClientCredentialProvider != nil {
192192
oauthClient := &client.Client{
193193
Credentials: client.NewCredentials("", ""),
@@ -199,7 +199,7 @@ func NewRestClientWithParams(params ClientParams) *RestClient {
199199
if params.AccountSid != "" {
200200
oauthClient.SetAccountSid(params.AccountSid)
201201
}
202-
requestHandler = client.NewRequestHandler(oauthClient)
202+
requestHandler = client.NewRequestHandlerWithContext(oauthClient)
203203
}
204204

205205
c := &RestClient{

0 commit comments

Comments
 (0)